Decompiled source of S1API Forked v2.9.2

Mods/S1API.Il2Cpp.MelonLoader.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using HarmonyLib;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Managing;
using Il2CppFishNet.Managing.Client;
using Il2CppFishNet.Managing.Object;
using Il2CppFishNet.Managing.Scened;
using Il2CppFishNet.Managing.Server;
using Il2CppFishNet.Managing.Transporting;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.AvatarFramework.Animation;
using Il2CppScheduleOne.AvatarFramework.Customization;
using Il2CppScheduleOne.AvatarFramework.Equipping;
using Il2CppScheduleOne.Building;
using Il2CppScheduleOne.Calling;
using Il2CppScheduleOne.Cartel;
using Il2CppScheduleOne.Casino;
using Il2CppScheduleOne.Clothing;
using Il2CppScheduleOne.Combat;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dialogue;
using Il2CppScheduleOne.Doors;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.Effects;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Graffiti;
using Il2CppScheduleOne.Growing;
using Il2CppScheduleOne.Interaction;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Law;
using Il2CppScheduleOne.Levelling;
using Il2CppScheduleOne.Management;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Misc;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Actions;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.NPCs.Relation;
using Il2CppScheduleOne.NPCs.Responses;
using Il2CppScheduleOne.NPCs.Schedules;
using Il2CppScheduleOne.Noise;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.Persistence.Loaders;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerScripts.Health;
using Il2CppScheduleOne.Police;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.ScriptableObjects;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.Trash;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.ContactsApp;
using Il2CppScheduleOne.UI.Phone.Messages;
using Il2CppScheduleOne.UI.Phone.ProductManagerApp;
using Il2CppScheduleOne.UI.Relations;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.UI.WorldspacePopup;
using Il2CppScheduleOne.Variables;
using Il2CppScheduleOne.Vehicles;
using Il2CppScheduleOne.Vehicles.Modification;
using Il2CppScheduleOne.Vision;
using Il2CppScheduleOne.VoiceOver;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using S1API;
using S1API.AssetBundles;
using S1API.Avatar;
using S1API.Building;
using S1API.Casino;
using S1API.Conditions;
using S1API.Console;
using S1API.Economy;
using S1API.Entities;
using S1API.Entities.Appearances.AccessoryFields;
using S1API.Entities.Appearances.Base;
using S1API.Entities.Appearances.BodyLayerFields;
using S1API.Entities.Appearances.CustomizationFields;
using S1API.Entities.Appearances.FaceLayerFields;
using S1API.Entities.Behaviour;
using S1API.Entities.Customer;
using S1API.Entities.Dealer;
using S1API.Entities.Dialogue;
using S1API.Entities.Interfaces;
using S1API.Entities.Relation;
using S1API.Entities.Schedule;
using S1API.GameTime;
using S1API.Graffiti;
using S1API.Internal;
using S1API.Internal.Abstraction;
using S1API.Internal.Entities;
using S1API.Internal.Items;
using S1API.Internal.Lifecycle;
using S1API.Internal.Map;
using S1API.Internal.Patches;
using S1API.Internal.Shops;
using S1API.Internal.Utils;
using S1API.Items;
using S1API.Law;
using S1API.Lifecycle;
using S1API.Logging;
using S1API.Map;
using S1API.Map.Buildings;
using S1API.Map.DeliveryLocations;
using S1API.Messaging;
using S1API.Money;
using S1API.PhoneApp;
using S1API.PhoneCalls;
using S1API.PhoneCalls.Constants;
using S1API.Products;
using S1API.Products.Packaging;
using S1API.Properties;
using S1API.Properties.Interfaces;
using S1API.Properties.Internal;
using S1API.Properties.Tokens;
using S1API.Property;
using S1API.Quests;
using S1API.Quests.Constants;
using S1API.Quests.Identifiers;
using S1API.Rendering;
using S1API.Saveables;
using S1API.Shops;
using S1API.Storage;
using S1API.Storages;
using S1API.Utils;
using S1API.Vehicles;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
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(global::S1API.S1API), "S1API (Forked by Bars)", "2.9.2", "KaBooMa", null)]
[assembly: MelonPriority(int.MinValue)]
[assembly: MelonIncompatibleAssemblies(new string[] { "ModManager&PhoneApp", "AutoClearCompletedDeals" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ifBars")]
[assembly: AssemblyConfiguration("Il2CppMelon")]
[assembly: AssemblyDescription("A Schedule One Mono / Il2Cpp Cross Compatibility Layer (Forked from the original S1API by Kabooma)")]
[assembly: AssemblyFileVersion("2.9.2.0")]
[assembly: AssemblyInformationalVersion("2.9.2+10756501477c52b00a756563976cf3d56790554a")]
[assembly: AssemblyProduct("S1API")]
[assembly: AssemblyTitle("S1API")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ifBars/S1API")]
[assembly: AssemblyVersion("2.9.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class ClickHandler
{
	private readonly UnityAction _callback;

	public ClickHandler(UnityAction callback)
	{
		_callback = callback;
	}

	public void OnClick()
	{
		_callback.Invoke();
	}
}
namespace S1API
{
	public class S1API : MelonMod
	{
		public override void OnPreSupportModule()
		{
			VersionChecker.CheckMelonLoaderVersion();
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				GameLifecycle.Initialize();
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: true);
			if (sceneName == "Main")
			{
				GameLifecycle.Reset();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			NPCNetworkBootstrap.EnsurePrefabsWarmup();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: false);
		}
	}
	public static class VersionChecker
	{
		private const string PROBLEMATIC_VERSION = "0.7.1";

		private const string RECOMMENDED_VERSION_1 = "0.7.0";

		private const string RECOMMENDED_VERSION_2 = "0.7.2-nightly";

		public static void CheckMelonLoaderVersion()
		{
			try
			{
				string melonLoaderVersion = GetMelonLoaderVersion();
				if (string.IsNullOrEmpty(melonLoaderVersion))
				{
					MelonLogger.Warning("[S1API VersionChecker] Could not determine MelonLoader version!");
					return;
				}
				MelonLogger.Msg("========================================");
				MelonLogger.Msg("[S1API VersionChecker] MelonLoader Version Detected: " + melonLoaderVersion);
				MelonLogger.Msg("========================================");
				if (IsProblematicVersion(melonLoaderVersion))
				{
					ShowBigWarning(melonLoaderVersion);
				}
				else
				{
					MelonLogger.Msg("[S1API VersionChecker] Your MelonLoader version appears to be compatible!");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[S1API VersionChecker] Version check failed: " + ex.Message);
			}
		}

		private static string GetMelonLoaderVersion()
		{
			try
			{
				Assembly assembly = typeof(MelonMod).Assembly;
				PropertyInfo propertyInfo = assembly.GetType("MelonLoader.Properties.BuildInfo")?.GetProperty("VersionNumber");
				if (propertyInfo?.GetValue(null) != null)
				{
					object value = propertyInfo.GetValue(null);
					return value.ToString() ?? GetVersionFromAssembly(assembly);
				}
				return GetVersionFromAssembly(assembly);
			}
			catch
			{
				try
				{
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly2 in assemblies)
					{
						string name = assembly2.GetName().Name;
						if (name != null && (name.Equals("MelonLoader") || name.Equals("MelonLoader.Core")))
						{
							return GetVersionFromAssembly(assembly2);
						}
					}
				}
				catch
				{
				}
				return null;
			}
		}

		private static string GetVersionFromAssembly(Assembly assembly)
		{
			Version version = assembly.GetName().Version;
			if (version != null)
			{
				return $"{version.Major}.{version.Minor}.{version.Build}";
			}
			return null;
		}

		private static bool IsProblematicVersion(string version)
		{
			if (string.IsNullOrEmpty(version))
			{
				return false;
			}
			return version.StartsWith("0.7.1", StringComparison.OrdinalIgnoreCase);
		}

		private static void ShowBigWarning(string detectedVersion)
		{
			string text = $"\r\n╔════════════════════════════════════════════════════════════════════════╗\r\n║                                                                        ║\r\n║                        !!! URGENT WARNING !!!                          ║\r\n║                                                                        ║\r\n║                YOU ARE USING MELONLOADER VERSION {detectedVersion,-21} ║\r\n║                                                                        ║\r\n║      This version is KNOWN TO HAVE CRITICAL ISSUES and may cause:      ║\r\n║                                                                        ║\r\n║                - Game crashes and unexpected behavior                  ║\r\n║                - Mod incompatibility and loading failures              ║\r\n║                - Performance issues and memory leaks                   ║\r\n║                - Random errors and instability                         ║\r\n║                                                                        ║\r\n║           PLEASE UPDATE IMMEDIATELY to one of these versions:          ║\r\n║                                                                        ║\r\n║                ► {"0.7.0",-27} (Stable Release)          ║\r\n║                ► {"0.7.2-nightly",-27} (Latest Nightly)          ║\r\n║                                                                        ║\r\n║      Download: https://melonwiki.xyz/#/?id=automated-installation      ║\r\n║                                                                        ║\r\n╚════════════════════════════════════════════════════════════════════════╝";
			MelonLogger.Error(text);
			MelonLogger.Error("[S1API VersionChecker] DETECTED PROBLEMATIC MELONLOADER VERSION: " + detectedVersion);
			MelonLogger.Error("[S1API VersionChecker] PLEASE UPDATE TO 0.7.0 OR 0.7.2-nightly");
			MelonLogger.Error(string.Concat(Enumerable.Repeat(Environment.NewLine, 2)));
			MelonLogger.Warning("[S1API VersionChecker] IMPORTANT: This message will be available in logs for your reference at \n" + Path.Combine(MelonEnvironment.MelonLoaderLogsDirectory, "Latest.log"));
		}
	}
}
namespace S1API.Vehicles
{
	public class LandVehicle
	{
		internal LandVehicle S1LandVehicle = null;

		internal bool _isDeferredByName = false;

		internal StorageInstance _storage;

		private static readonly Log _logger = new Log("S1API.LandVehicle");

		private static readonly FieldInfo? VehiclePriceField = typeof(LandVehicle).GetField("vehiclePrice", BindingFlags.NonPublic);

		private NetworkConnection? _conn;

		private string _guid = string.Empty;

		public float VehiclePrice
		{
			get
			{
				return S1LandVehicle.VehiclePrice;
			}
			set
			{
				VehiclePriceField?.SetValue(S1LandVehicle, value);
			}
		}

		public float TopSpeed
		{
			get
			{
				return S1LandVehicle.TopSpeed;
			}
			set
			{
				S1LandVehicle.TopSpeed = value;
			}
		}

		public bool IsPlayerOwned
		{
			get
			{
				return S1LandVehicle.IsPlayerOwned;
			}
			set
			{
				SetIsPlayerOwned(value);
			}
		}

		public bool IsOccupied
		{
			get
			{
				return S1LandVehicle.IsOccupied;
			}
			set
			{
				S1LandVehicle.IsOccupied = value;
			}
		}

		public VehicleColor Color
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Expected I4, but got Unknown
				return (VehicleColor)S1LandVehicle.OwnedColor;
			}
			set
			{
				SetColor(value);
			}
		}

		public string GUID => _guid;

		public StorageInstance Storage => _storage;

		public event Action OnVehicleStart
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStart += Action.op_Implicit(value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStart -= Action.op_Implicit(value);
			}
		}

		public event Action OnVehicleStop
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStop += Action.op_Implicit(value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStop -= Action.op_Implicit(value);
			}
		}

		public event Action OnHandbrakeApplied
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onHandbrakeApplied += Action.op_Implicit(value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onHandbrakeApplied -= Action.op_Implicit(value);
			}
		}

		public event Action<Collision> OnCollision
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onCollision += Action<Collision>.op_Implicit(value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onCollision -= Action<Collision>.op_Implicit(value);
			}
		}

		public LandVehicle(string vehicleCode)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(vehicleCode);
			if ((Object)(object)vehiclePrefab == (Object)null)
			{
				_logger.Error("SpawnVehicle: '" + vehicleCode + "' is not a valid vehicle code!");
				return;
			}
			LandVehicle component = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject).GetComponent<LandVehicle>();
			component.SetGUID(GUIDManager.GenerateUniqueGUID());
			NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component);
			S1LandVehicle = component;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(component.Storage);
		}

		public void Spawn(Vector3 position, Quaternion rotation)
		{
			//IL_0046: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServer)
			{
				_logger.Warning("Spawn can only be called on the server!");
				return;
			}
			if ((Object)(object)S1LandVehicle == (Object)null)
			{
				throw new Exception("Unable to spawn vehicle, S1LandVehicle is null!");
			}
			((Component)S1LandVehicle).transform.position = position;
			((Component)S1LandVehicle).transform.rotation = rotation;
			((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).Spawn(((Component)S1LandVehicle).gameObject, (NetworkConnection)null, default(Scene));
		}

		public void AlignTo(Transform target, ParkingAlignment type, bool network = false)
		{
			if ((Object)(object)S1LandVehicle == (Object)null)
			{
				throw new Exception("Unable to align to position, S1LandVehicle is null!");
			}
			S1LandVehicle.AlignTo(target, (EParkingAlignment)type, network);
		}

		public void ExitPark(bool moveToExitPoint = true)
		{
			S1LandVehicle.ExitPark(moveToExitPoint);
		}

		public void SetVisible(bool vis)
		{
			S1LandVehicle.SetVisible(vis);
		}

		public void DestroyVehichle()
		{
			S1LandVehicle.DestroyVehicle();
		}

		public void ApplyColor(VehicleColor col)
		{
			S1LandVehicle.ApplyColor((EVehicleColor)col);
		}

		public void Park(ParkingData parkData, bool network)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			ParkData val = new ParkData
			{
				lotGUID = Guid.Parse(parkData.LotId),
				spotIndex = parkData.Index,
				alignment = (EParkingAlignment)parkData.Alignment
			};
			S1LandVehicle.Park(_conn, val, network);
		}

		internal LandVehicle(LandVehicle landVehicle)
		{
			S1LandVehicle = landVehicle;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(landVehicle.Storage);
			_isDeferredByName = false;
		}

		internal LandVehicle(string vehicleName, bool isDeferred)
		{
			_isDeferredByName = isDeferred;
		}

		private void SetConnection()
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if (networkManager.IsClientOnly)
			{
				NetworkConnection connection = InstanceFinder.ClientManager.Connection;
				if (connection != (NetworkConnection)null && connection.IsValid)
				{
					_conn = connection;
				}
			}
			else if (networkManager.IsServerOnly || (networkManager.IsServer && !networkManager.IsClient))
			{
				NetworkConnection owner = ((NetworkBehaviour)S1LandVehicle).Owner;
				if (owner != (NetworkConnection)null && owner.IsValid)
				{
					_conn = owner;
				}
			}
		}

		private void SetIsPlayerOwned(bool isPlayerOwned)
		{
			S1LandVehicle.SetIsPlayerOwned(_conn, isPlayerOwned);
			if (isPlayerOwned)
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(S1LandVehicle);
			}
			else
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Remove(S1LandVehicle);
			}
		}

		private void SetColor(VehicleColor color)
		{
			MethodInfo method = typeof(LandVehicle).GetMethod("SetOwnedColor", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method == null)
			{
				_logger.Error("SetOwnedColor method not found!");
				return;
			}
			method.Invoke(S1LandVehicle, new object[2]
			{
				_conn,
				(object)(EVehicleColor)color
			});
		}

		private void UpdateGuidFromGame()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			try
			{
				PropertyInfo property = typeof(LandVehicle).GetProperty("GUID", BindingFlags.Instance | BindingFlags.Public);
				if (!(property == null))
				{
					Guid val = (Guid)(property.GetValue(S1LandVehicle) ?? ((object)default(Guid)));
					_guid = ((object)(Guid)(ref val)).ToString();
				}
			}
			catch
			{
			}
		}
	}
	public enum ParkingAlignment
	{
		FrontToKerb,
		RearToKerb
	}
	public enum VehicleColor
	{
		Black,
		DarkGrey,
		LightGrey,
		White,
		Yellow,
		Orange,
		Red,
		DullRed,
		Pink,
		Purple,
		Navy,
		DarkBlue,
		LightBlue,
		Cyan,
		LightGreen,
		DarkGreen,
		Custom
	}
	public static class VehicleRegistry
	{
		private static readonly Dictionary<object, LandVehicle> _cache = new Dictionary<object, LandVehicle>();

		public static LandVehicle[] GetAll()
		{
			try
			{
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles == null)
				{
					return Array.Empty<LandVehicle>();
				}
				List<LandVehicle> list = new List<LandVehicle>();
				Enumerator<LandVehicle> enumerator = allVehicles.GetEnumerator();
				while (enumerator.MoveNext())
				{
					LandVehicle current = enumerator.Current;
					if ((Object)(object)current != (Object)null)
					{
						LandVehicle landVehicle = Wrap(current);
						if (landVehicle != null)
						{
							list.Add(landVehicle);
						}
					}
				}
				return list.ToArray();
			}
			catch
			{
				return Array.Empty<LandVehicle>();
			}
		}

		public static LandVehicle GetByGUID(string guid)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(guid))
			{
				return null;
			}
			try
			{
				Guid val = default(Guid);
				((Guid)(ref val))..ctor(guid);
				LandVehicle @object = GUIDManager.GetObject<LandVehicle>(val);
				if ((Object)(object)@object == (Object)null)
				{
					return null;
				}
				return Wrap(@object);
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle GetByName(string gameObjectName)
		{
			if (string.IsNullOrEmpty(gameObjectName))
			{
				return null;
			}
			try
			{
				GameObject val = GameObject.Find(gameObjectName);
				if ((Object)(object)val != (Object)null)
				{
					LandVehicle component = val.GetComponent<LandVehicle>();
					if ((Object)(object)component != (Object)null)
					{
						return Wrap(component);
					}
				}
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles != null)
				{
					for (int i = 0; i < allVehicles.Count; i++)
					{
						LandVehicle val2 = allVehicles[i];
						if ((Object)(object)val2 != (Object)null && ((Object)((Component)val2).gameObject).name == gameObjectName)
						{
							return Wrap(val2);
						}
					}
				}
				if (DeferredMapResolver.IsMenuScene())
				{
					LandVehicle deferredVehicle = new LandVehicle(gameObjectName, isDeferred: true);
					DeferredMapResolver.RegisterDeferredLookup(new DeferredLookup(gameObjectName, delegate(object resolved)
					{
						if (resolved is LandVehicle landVehicle && landVehicle != null && (Object)(object)landVehicle.S1LandVehicle != (Object)null)
						{
							deferredVehicle.S1LandVehicle = landVehicle.S1LandVehicle;
							deferredVehicle._isDeferredByName = false;
						}
					}));
					return deferredVehicle;
				}
				return null;
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle CreateVehicle(string vehicleCode)
		{
			if (!string.IsNullOrEmpty(vehicleCode))
			{
				try
				{
					return new LandVehicle(vehicleCode);
				}
				catch
				{
					return null;
				}
			}
			return null;
		}

		public static void RemoveVehicle(string guidString)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(guidString))
			{
				return;
			}
			VehicleManager instance = NetworkSingleton<VehicleManager>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Guid val = default(Guid);
			((Guid)(ref val))..ctor(guidString);
			int? num = null;
			LandVehicle val2 = null;
			List<LandVehicle> allVehicles = instance.AllVehicles;
			Guid gUID;
			if (allVehicles != null)
			{
				for (int i = 0; i < allVehicles.Count; i++)
				{
					LandVehicle obj = allVehicles[i];
					if (obj != null)
					{
						gUID = obj.GUID;
						if (((Guid)(ref gUID)).Equals(val))
						{
							num = i;
							val2 = allVehicles[i];
							break;
						}
					}
				}
			}
			int? num2 = null;
			List<LandVehicle> playerOwnedVehicles = instance.PlayerOwnedVehicles;
			if (playerOwnedVehicles != null)
			{
				for (int j = 0; j < playerOwnedVehicles.Count; j++)
				{
					LandVehicle obj2 = playerOwnedVehicles[j];
					if (obj2 != null)
					{
						gUID = obj2.GUID;
						if (((Guid)(ref gUID)).Equals(val))
						{
							num2 = j;
							break;
						}
					}
				}
			}
			if (num.HasValue)
			{
				allVehicles?.RemoveAt(num.Value);
			}
			if (num2.HasValue)
			{
				playerOwnedVehicles?.RemoveAt(num2.Value);
			}
			if ((Object)(object)val2 != (Object)null && _cache.ContainsKey(val2))
			{
				_cache.Remove(val2);
			}
		}

		private static LandVehicle Wrap(LandVehicle veh)
		{
			if ((Object)(object)veh == (Object)null)
			{
				return null;
			}
			if (_cache.TryGetValue(veh, out LandVehicle value))
			{
				return value;
			}
			LandVehicle landVehicle = new LandVehicle(veh);
			_cache[veh] = landVehicle;
			return landVehicle;
		}
	}
}
namespace S1API.Utils
{
	public static class ArrayExtensions
	{
		public static T[] AddItemToArray<T>(this T[]? array, T item)
		{
			return global::S1API.Internal.Utils.ArrayExtensions.AddItemToArray(array, item);
		}

		public static Il2CppReferenceArray<T> AddItemToArray<T>(this Il2CppReferenceArray<T>? array, params T[]? itemsToAdd) where T : Object
		{
			return global::S1API.Internal.Utils.ArrayExtensions.AddItemToArray(array, itemsToAdd);
		}
	}
	public static class ButtonUtils
	{
		public static void AddListener(Button button, Action action)
		{
			global::S1API.Internal.Utils.ButtonUtils.AddListener(button, action);
		}

		public static void RemoveListener(Button button, Action action)
		{
			global::S1API.Internal.Utils.ButtonUtils.RemoveListener(button, action);
		}

		public static void ClearListeners(Button button)
		{
			global::S1API.Internal.Utils.ButtonUtils.ClearListeners(button);
		}

		public static void Enable(Button button, Text? label = null, string? text = null)
		{
			global::S1API.Internal.Utils.ButtonUtils.Enable(button, label, text);
		}

		public static void Disable(Button button, Text? label = null, string? text = null)
		{
			global::S1API.Internal.Utils.ButtonUtils.Disable(button, label, text);
		}

		public static void SetLabel(Text label, string text)
		{
			global::S1API.Internal.Utils.ButtonUtils.SetLabel(label, text);
		}

		public static void SetStyle(Button button, Text label, string text, Color bg)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Utils.ButtonUtils.SetStyle(button, label, text, bg);
		}
	}
	public static class ColorUtils
	{
		public static Color ToColor(this uint hexColor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return global::S1API.Internal.Utils.ColorUtils.ToColor(hexColor);
		}
	}
	public static class ImageUtils
	{
		public static Sprite? LoadImage(string fileName)
		{
			return global::S1API.Internal.Utils.ImageUtils.LoadImage(fileName);
		}

		public static Sprite? LoadImageRaw(byte[] data)
		{
			return global::S1API.Internal.Utils.ImageUtils.LoadImageRaw(data);
		}

		public static Sprite? TextureToSprite(Texture2D? texture, float pixelsPerUnit = 100f)
		{
			return global::S1API.Internal.Utils.ImageUtils.TextureToSprite(texture, pixelsPerUnit);
		}

		public static Sprite? LoadImageFromResource(Assembly assembly, string resourceName, float pixelsPerUnit = 100f, FilterMode filterMode = 1)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return global::S1API.Internal.Utils.ImageUtils.LoadImageFromResource(assembly, resourceName, pixelsPerUnit, filterMode);
		}
	}
	public static class RandomUtils
	{
		public static T PickOne<T>(this IList<T> list)
		{
			return global::S1API.Internal.Utils.RandomUtils.PickOne(list);
		}

		public static T PickUnique<T>(this IList<T> list, Func<T, bool> isDuplicate, int maxTries = 10)
		{
			return global::S1API.Internal.Utils.RandomUtils.PickUnique(list, isDuplicate, maxTries);
		}

		public static List<T> PickMany<T>(this IList<T> list, int count)
		{
			return global::S1API.Internal.Utils.RandomUtils.PickMany(list, count);
		}

		public static int RangeInt(int minInclusive, int maxExclusive)
		{
			return global::S1API.Internal.Utils.RandomUtils.RangeInt(minInclusive, maxExclusive);
		}
	}
	public static class ReflectionUtils
	{
		public static MethodInfo? GetMethod(Type? type, string methodName, BindingFlags bindingFlags)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetMethod(type, methodName, bindingFlags);
		}

		public static bool IsValueTuple(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.IsValueTuple(obj);
		}

		public static object[]? GetValueTupleItems(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetValueTupleItems(obj);
		}

		public static bool TrySetFieldOrProperty(object target, string memberName, object value)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TrySetFieldOrProperty(target, memberName, value);
		}

		public static object? TryGetFieldOrProperty(object target, string memberName)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(target, memberName);
		}
	}
	public static class ToggleUtils
	{
		public static void AddListener(Toggle toggle, Action<bool> listener)
		{
			global::S1API.Internal.Utils.ToggleUtils.AddListener(toggle, listener);
		}

		public static void RemoveListener(Toggle toggle, Action<bool> listener)
		{
			global::S1API.Internal.Utils.ToggleUtils.RemoveListener(toggle, listener);
		}

		public static void ClearListeners(Toggle toggle)
		{
			global::S1API.Internal.Utils.ToggleUtils.ClearListeners(toggle);
		}

		public static void SetGraphic(Toggle toggle, Graphic graphic)
		{
			global::S1API.Internal.Utils.ToggleUtils.SetGraphic(toggle, graphic);
		}

		public static Graphic? GetGraphic(Toggle toggle)
		{
			return global::S1API.Internal.Utils.ToggleUtils.GetGraphic(toggle);
		}
	}
}
namespace S1API.UI
{
	public static class CharacterCreatorManager
	{
		[CompilerGenerated]
		private sealed class <RestoreAfterClose>d__27 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = RestoreGameState();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					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 <RestoreGameState>d__28 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private PlayerCamera <camera>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (PlayerSingleton<PlayerCamera>.InstanceExists)
					{
						<camera>5__1 = PlayerSingleton<PlayerCamera>.Instance;
						PlayerCamera obj = <camera>5__1;
						CharacterCreator s1Creator = _s1Creator;
						obj.RemoveActiveUIElement(((s1Creator != null) ? ((Object)s1Creator).name : null) ?? "CharacterCreator");
						if (<camera>5__1.activeUIElementCount == 0)
						{
							<camera>5__1.StopTransformOverride(0f, true, false);
							<camera>5__1.StopFOVOverride(0f);
							<camera>5__1.SetCanLook(true);
							<camera>5__1.LockMouse();
						}
						<camera>5__1 = null;
					}
					if (PlayerSingleton<PlayerMovement>.InstanceExists)
					{
						PlayerSingleton<PlayerMovement>.Instance.CanMove = true;
					}
					if (PlayerSingleton<PlayerInventory>.InstanceExists)
					{
						PlayerSingleton<PlayerInventory>.Instance.SetInventoryEnabled(true);
					}
					if (Singleton<HUD>.InstanceExists)
					{
						((Behaviour)Singleton<HUD>.Instance.canvas).enabled = true;
					}
					return false;
				}
			}

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

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

		private static readonly Log Logger = new Log("CharacterCreatorManager");

		private static CharacterCreator _s1Creator;

		private static bool _isInitialized;

		private static bool _eventsRegistered;

		public static bool IsOpen
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				return s1Creator != null && s1Creator.IsOpen;
			}
		}

		public static BasicAvatarSettings ActiveSettings
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				if ((Object)(object)((s1Creator != null) ? s1Creator.ActiveSettings : null) == (Object)null)
				{
					return null;
				}
				return new BasicAvatarSettings(_s1Creator.ActiveSettings);
			}
		}

		public static event Action OnOpened;

		public static event Action OnClosed;

		public static event Action<BasicAvatarSettings> OnCompleted;

		public static void Open(BasicAvatarSettings initialSettings = null, bool showUI = true)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is already open");
				return;
			}
			RegisterEvents();
			if (initialSettings == null)
			{
				initialSettings = GetPlayerAvatarSettings();
			}
			if (showUI && PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
			BasicAvatarSettings val = initialSettings?.S1BasicAvatarSettings;
			_s1Creator.Open(val, showUI);
			try
			{
				CharacterCreatorManager.OnOpened?.Invoke();
			}
			catch (Exception value)
			{
				Logger.Error($"Error in OnOpened event handler: {value}");
			}
		}

		public static void Close()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
				return;
			}
			_s1Creator.Close();
			MelonCoroutines.Start(RestoreAfterClose());
			try
			{
				CharacterCreatorManager.OnClosed?.Invoke();
			}
			catch (Exception value)
			{
				Logger.Error($"Error in OnClosed event handler: {value}");
			}
		}

		public static void Complete()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
			}
			else
			{
				_s1Creator.Done();
			}
		}

		public static void SelectPreset(string presetName)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to select a preset");
			}
			else if (string.IsNullOrWhiteSpace(presetName))
			{
				Logger.Warning("Preset name cannot be null or empty");
			}
			else
			{
				_s1Creator.SelectPreset(presetName);
			}
		}

		public static string[] GetAvailablePresets()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null || _s1Creator.Presets == null)
			{
				return Array.Empty<string>();
			}
			List<string> list = new List<string>();
			for (int i = 0; i < _s1Creator.Presets.Count; i++)
			{
				BasicAvatarSettings val = _s1Creator.Presets[i];
				if ((Object)(object)val != (Object)null && !string.IsNullOrWhiteSpace(((Object)val).name))
				{
					list.Add(((Object)val).name);
				}
			}
			return list.ToArray();
		}

		public static void SetRigRotation(float normalizedValue)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to set rig rotation");
			}
			else
			{
				_s1Creator.SliderChanged(Mathf.Clamp01(normalizedValue));
			}
		}

		public static void PreRegisterAsActiveUI()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Warning("CharacterCreator singleton is not available for pre-registration");
			}
			else if (PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
		}

		private static void EnsureInitialized()
		{
			if (_isInitialized)
			{
				return;
			}
			try
			{
				_s1Creator = Singleton<CharacterCreator>.Instance;
				if ((Object)(object)_s1Creator == (Object)null)
				{
					Logger.Warning("CharacterCreator singleton not found. Make sure you're in the correct scene.");
				}
				_isInitialized = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to initialize CharacterCreatorManager: {value}");
				_isInitialized = true;
			}
		}

		private static void RegisterEvents()
		{
			if (_eventsRegistered || (Object)(object)_s1Creator == (Object)null)
			{
				return;
			}
			try
			{
				if (_s1Creator.onComplete != null)
				{
					_s1Creator.onComplete.AddListener(UnityAction<BasicAvatarSettings>.op_Implicit((Action<BasicAvatarSettings>)OnCreatorCompleted));
				}
				_eventsRegistered = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to register CharacterCreator events: {value}");
			}
		}

		private static void OnCreatorCompleted(BasicAvatarSettings s1Settings)
		{
			try
			{
				if ((Object)(object)s1Settings == (Object)null)
				{
					Logger.Warning("CharacterCreator completed with null settings");
					return;
				}
				BasicAvatarSettings obj = new BasicAvatarSettings(s1Settings);
				MelonCoroutines.Start(RestoreGameState());
				CharacterCreatorManager.OnCompleted?.Invoke(obj);
			}
			catch (Exception value)
			{
				Logger.Error($"Error in OnCompleted event handler: {value}");
			}
		}

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

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

		private static BasicAvatarSettings GetPlayerAvatarSettings()
		{
			try
			{
				Player local = Player.Local;
				if (local == null || (Object)(object)local.S1Player == (Object)null)
				{
					Logger.Warning("Local player not available");
					return null;
				}
				BasicAvatarSettings currentAvatarSettings = local.S1Player.CurrentAvatarSettings;
				if ((Object)(object)currentAvatarSettings == (Object)null)
				{
					Logger.Msg("Player has no current avatar settings, using default");
					return null;
				}
				BasicAvatarSettings settings = Object.Instantiate<BasicAvatarSettings>(currentAvatarSettings);
				return new BasicAvatarSettings(settings);
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to get player avatar settings: {value}");
				return null;
			}
		}
	}
	public sealed class MainMenuRig
	{
		internal readonly MainMenuRig S1MainMenuRig;

		public global::S1API.Avatar.Avatar? Avatar
		{
			get
			{
				if ((Object)(object)S1MainMenuRig == (Object)null || (Object)(object)S1MainMenuRig.Avatar == (Object)null)
				{
					return null;
				}
				return new global::S1API.Avatar.Avatar(S1MainMenuRig.Avatar);
			}
		}

		internal MainMenuRig(MainMenuRig mainMenuRig)
		{
			S1MainMenuRig = mainMenuRig;
		}

		public static MainMenuRig[] FindInScene(bool includeInactive = false)
		{
			Il2CppArrayBase<MainMenuRig> val = Object.FindObjectsOfType<MainMenuRig>(includeInactive);
			if (val == null || val.Length == 0)
			{
				return Array.Empty<MainMenuRig>();
			}
			return (from r in (IEnumerable<MainMenuRig>)val
				where (Object)(object)r != (Object)null
				select new MainMenuRig(r)).ToArray();
		}
	}
	public static class UIFactory
	{
		private static Sprite roundedSprite;

		public static GameObject Panel(string name, Transform parent, Color bgColor, Vector2? anchorMin = null, Vector2? anchorMax = null, bool fullAnchor = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			if (fullAnchor)
			{
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
			}
			else
			{
				val2.anchorMin = (Vector2)(((??)anchorMin) ?? new Vector2(0.5f, 0.5f));
				val2.anchorMax = (Vector2)(((??)anchorMax) ?? new Vector2(0.5f, 0.5f));
			}
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			return val;
		}

		public static Text Text(string name, string content, Transform parent, int fontSize = 14, TextAnchor anchor = 0, FontStyle style = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0035: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			Text val3 = val.AddComponent<Text>();
			val3.text = content;
			val3.fontSize = fontSize;
			val3.alignment = anchor;
			val3.fontStyle = style;
			val3.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			((Graphic)val3).color = Color.white;
			val3.horizontalOverflow = (HorizontalWrapMode)0;
			val3.verticalOverflow = (VerticalWrapMode)1;
			return val3;
		}

		public static RectTransform ScrollableVerticalList(string name, Transform parent, out ScrollRect scrollRect)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0084: 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_009c: 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)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0186: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			scrollRect = val.AddComponent<ScrollRect>();
			scrollRect.horizontal = false;
			GameObject val3 = new GameObject("Viewport");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			((Graphic)val3.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.05f);
			val3.AddComponent<Mask>().showMaskGraphic = false;
			scrollRect.viewport = val4;
			GameObject val5 = new GameObject("Content");
			val5.transform.SetParent(val3.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = new Vector2(0f, 1f);
			val6.anchorMax = new Vector2(1f, 1f);
			val6.pivot = new Vector2(0.5f, 1f);
			VerticalLayoutGroup val7 = val5.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val7).spacing = 10f;
			((LayoutGroup)val7).padding = new RectOffset(10, 10, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val7).childForceExpandHeight = false;
			val5.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			scrollRect.content = val6;
			return val6;
		}

		public static void FitContentHeight(RectTransform content)
		{
			ContentSizeFitter val = ((Component)content).gameObject.GetComponent<ContentSizeFitter>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
			}
			val.verticalFit = (FitMode)2;
		}

		public static (GameObject, Button, Text) RoundedButtonWithLabel(string name, string label, Transform parent, Color bgColor, float width, float height, int fontSize, Color textColor)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00af: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name + "_RoundedMask");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(width, height);
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.preferredWidth = width;
			val3.preferredHeight = height;
			Image val4 = val.AddComponent<Image>();
			val4.sprite = GetRoundedSprite();
			val4.type = (Type)1;
			((Graphic)val4).color = Color.white;
			Mask val5 = val.AddComponent<Mask>();
			val5.showMaskGraphic = true;
			GameObject val6 = new GameObject(name);
			val6.transform.SetParent(val.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = Vector2.zero;
			val7.offsetMax = Vector2.zero;
			Image val8 = val6.AddComponent<Image>();
			((Graphic)val8).color = bgColor;
			val8.sprite = GetRoundedSprite();
			val8.type = (Type)1;
			Button val9 = val6.AddComponent<Button>();
			((Selectable)val9).targetGraphic = (Graphic)(object)val8;
			GameObject val10 = new GameObject("Label");
			val10.transform.SetParent(val6.transform, false);
			RectTransform val11 = val10.AddComponent<RectTransform>();
			val11.anchorMin = Vector2.zero;
			val11.anchorMax = Vector2.one;
			val11.offsetMin = Vector2.zero;
			val11.offsetMax = Vector2.zero;
			Text val12 = val10.AddComponent<Text>();
			val12.text = label;
			val12.alignment = (TextAnchor)4;
			val12.fontSize = fontSize;
			val12.fontStyle = (FontStyle)1;
			((Graphic)val12).color = textColor;
			val12.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val9, val12);
		}

		private static Sprite GetRoundedSprite()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)roundedSprite != (Object)null)
			{
				return roundedSprite;
			}
			int num = 32;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			Color32 val3 = default(Color32);
			((Color32)(ref val3))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			float num2 = 6f;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					bool flag = ((float)j < num2 && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, num2)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, num2)) > num2) || ((float)j < num2 && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, (float)num - num2 - 1f)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, (float)num - num2 - 1f)) > num2);
					val.SetPixel(j, i, Color32.op_Implicit(flag ? val2 : val3));
				}
			}
			val.Apply();
			Vector4 val4 = default(Vector4);
			((Vector4)(ref val4))..ctor(8f, 8f, 8f, 8f);
			roundedSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val4);
			return roundedSprite;
		}

		public static GameObject ButtonRow(string name, Transform parent, float spacing = 12f, TextAnchor alignment = 4)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val3).spacing = spacing;
			((LayoutGroup)val3).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false;
			return val;
		}

		public static (GameObject, Button, Text) ButtonWithLabel(string name, string label, Transform parent, Color bgColor, float Width, float Height)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(Height, Width);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			val3.sprite = Resources.GetBuiltinResource<Sprite>("UI/Skin/UISprite.psd");
			val3.type = (Type)1;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			GameObject val5 = new GameObject("Label");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			Text val7 = val5.AddComponent<Text>();
			val7.text = label;
			val7.alignment = (TextAnchor)4;
			val7.fontSize = 16;
			val7.fontStyle = (FontStyle)1;
			((Graphic)val7).color = Color.white;
			val7.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val4, val7);
		}

		public static void SetIcon(Sprite sprite, Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Icon");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image val3 = val.AddComponent<Image>();
			val3.sprite = sprite;
			val3.preserveAspect = true;
		}

		public static void CreateTextBlock(Transform parent, string title, string subtitle, bool isCompleted)
		{
			Text(((Object)parent).name + "Title", title, parent, 16, (TextAnchor)3, (FontStyle)1);
			Text(((Object)parent).name + "Subtitle", subtitle, parent, 14, (TextAnchor)0, (FontStyle)0);
			if (isCompleted)
			{
				Text("CompletedLabel", "<color=#888888><i>Already Delivered</i></color>", parent, 12, (TextAnchor)0, (FontStyle)0);
			}
		}

		public static void CreateRowButton(GameObject go, UnityAction clickHandler, bool enabled)
		{
			Button val = go.AddComponent<Button>();
			Image component = go.GetComponent<Image>();
			((Selectable)val).targetGraphic = (Graphic)(object)component;
			((Selectable)val).interactable = enabled;
			((UnityEvent)val.onClick).AddListener(clickHandler);
		}

		public static void ClearChildren(Transform parent)
		{
			for (int num = parent.childCount - 1; num >= 0; num--)
			{
				Transform child = parent.GetChild(num);
				Object.Destroy((Object)(object)((Component)child).gameObject);
			}
		}

		public static void VerticalLayoutOnGO(GameObject go, int spacing = 10, RectOffset? padding = null)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			VerticalLayoutGroup val = go.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).padding = (RectOffset)(((object)padding) ?? ((object)new RectOffset(10, 10, 10, 10)));
		}

		public static GameObject CreateQuestRow(string name, Transform parent, out GameObject iconPanel, out GameObject textPanel)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0182: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Row_" + name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(0f, 90f);
			val.AddComponent<LayoutElement>().minHeight = 50f;
			((Shadow)val.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.2f);
			GameObject val3 = Panel("Separator", val.transform, new Color(1f, 1f, 1f, 0.05f));
			val3.GetComponent<RectTransform>().sizeDelta = new Vector2(300f, 1f);
			Image val4 = val.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.12f, 0.12f, 0.12f);
			Button val5 = val.AddComponent<Button>();
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			HorizontalLayoutGroup val6 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val6).spacing = 20f;
			((LayoutGroup)val6).padding = new RectOffset(75, 10, 10, 10);
			((LayoutGroup)val6).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false;
			LayoutElement val7 = val.AddComponent<LayoutElement>();
			val7.minHeight = 90f;
			val7.flexibleWidth = 1f;
			iconPanel = Panel("IconPanel", val.transform, new Color(0.12f, 0.12f, 0.12f));
			RectTransform component = iconPanel.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(80f, 80f);
			LayoutElement val8 = iconPanel.AddComponent<LayoutElement>();
			val8.preferredWidth = 80f;
			val8.preferredHeight = 80f;
			textPanel = Panel("TextPanel", val.transform, Color.clear);
			VerticalLayoutOnGO(textPanel, 2);
			LayoutElement val9 = textPanel.AddComponent<LayoutElement>();
			val9.minWidth = 200f;
			val9.flexibleWidth = 1f;
			return val;
		}

		public static GameObject TopBar(string name, Transform parent, string title, float topbarSize, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			GameObject val = Panel(name, parent, new Color(0.15f, 0.15f, 0.15f), (Vector2?)new Vector2(0f, topbarSize), (Vector2?)new Vector2(1f, 1f), fullAnchor: false);
			HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)val2).padding = new RectOffset(paddingLeft, paddingRight, paddingTop, paddingBottom);
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 20f;
			((LayoutGroup)val2).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = true;
			Text val3 = Text("TopBarTitle", title, val.transform, 26, (TextAnchor)3, (FontStyle)1);
			LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
			val4.minWidth = 300f;
			val4.flexibleWidth = 1f;
			return val;
		}

		public static void HorizontalLayoutOnGO(GameObject go, int spacing = 10, int padLeft = 0, int padRight = 0, int padTop = 0, int padBottom = 0, TextAnchor alignment = 4)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			HorizontalLayoutGroup val = go.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((LayoutGroup)val).padding = new RectOffset(padLeft, padRight, padTop, padBottom);
		}

		public static void SetLayoutGroupPadding(LayoutGroup layoutGroup, int left, int right, int top, int bottom)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			layoutGroup.padding = new RectOffset(left, right, top, bottom);
		}

		public static void BindAcceptButton(Button btn, Text label, string text, UnityAction callback)
		{
			label.text = text;
			((UnityEventBase)btn.onClick).RemoveAllListeners();
			((UnityEvent)btn.onClick).AddListener(callback);
		}
	}
}
namespace S1API.Storage
{
	public sealed class StorageEntity
	{
		private static readonly Log Logger = new Log("StorageEntity");

		internal readonly StorageEntity S1StorageEntity;

		internal readonly PlaceableStorageEntity S1PlaceableStorageEntity;

		public string Name
		{
			get
			{
				return S1StorageEntity.StorageEntityName;
			}
			set
			{
				S1StorageEntity.StorageEntityName = value;
			}
		}

		public int SlotCount
		{
			get
			{
				return S1StorageEntity.SlotCount;
			}
			set
			{
				if (value < 0)
				{
					Logger.Warning("Cannot set SlotCount to negative value");
					return;
				}
				if (value > MaxSlots)
				{
					Logger.Warning($"Cannot set SlotCount to {value}, maximum is {MaxSlots}");
					return;
				}
				int count = S1StorageEntity.ItemSlots.Count;
				if (value > count)
				{
					AddSlots(value - count);
				}
				else if (value < count)
				{
					RemoveSlots(count - value);
				}
			}
		}

		public int MaxSlots { get; set; } = 20;


		public int DisplayRowCount
		{
			get
			{
				return S1StorageEntity.DisplayRowCount;
			}
			set
			{
				S1StorageEntity.DisplayRowCount = value;
			}
		}

		public bool SlotsAreFilterable => S1StorageEntity.SlotsAreFilterable;

		public ItemInstance ItemInstance
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				if (((s1PlaceableStorageEntity != null) ? ((BuildableItem)s1PlaceableStorageEntity).ItemInstance : null) == null)
				{
					return null;
				}
				return new ItemInstance(((BuildableItem)S1PlaceableStorageEntity).ItemInstance);
			}
		}

		public string ItemId
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object result;
				if (s1PlaceableStorageEntity == null)
				{
					result = null;
				}
				else
				{
					ItemInstance itemInstance = ((BuildableItem)s1PlaceableStorageEntity).ItemInstance;
					if (itemInstance == null)
					{
						result = null;
					}
					else
					{
						ItemDefinition definition = itemInstance.Definition;
						result = ((definition != null) ? definition.ID : null);
					}
				}
				return (string)result;
			}
		}

		public bool IsPlaceable => (Object)(object)S1PlaceableStorageEntity != (Object)null;

		public string CustomName
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object result;
				if (s1PlaceableStorageEntity == null)
				{
					result = null;
				}
				else
				{
					EntityConfiguration configuration = s1PlaceableStorageEntity.Configuration;
					if (configuration == null)
					{
						result = null;
					}
					else
					{
						StringField name = configuration.Name;
						result = ((name != null) ? name.Value : null);
					}
				}
				return (string)result;
			}
			set
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object obj;
				if (s1PlaceableStorageEntity == null)
				{
					obj = null;
				}
				else
				{
					EntityConfiguration configuration = s1PlaceableStorageEntity.Configuration;
					obj = ((configuration != null) ? configuration.Name : null);
				}
				if (obj != null && !string.IsNullOrEmpty(value))
				{
					S1PlaceableStorageEntity.Configuration.Name.SetValue(value, true);
				}
			}
		}

		public bool HasCustomName => !string.IsNullOrEmpty(CustomName);

		internal StorageEntity(StorageEntity storageEntity, PlaceableStorageEntity placeableStorage = null)
		{
			S1StorageEntity = storageEntity ?? throw new ArgumentNullException("storageEntity");
			S1PlaceableStorageEntity = placeableStorage;
		}

		public void SyncCustomNameToDisplayName()
		{
			if (HasCustomName)
			{
				Name = CustomName;
			}
		}

		public bool AddSlots(int count)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			if (count <= 0)
			{
				Logger.Warning("AddSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			int num = count2 + count;
			if (num > MaxSlots)
			{
				Logger.Warning($"Cannot add {count} slots, would exceed MaxSlots ({MaxSlots})");
				return false;
			}
			try
			{
				for (int i = 0; i < count; i++)
				{
					ItemSlot val = new ItemSlot(S1StorageEntity.SlotsAreFilterable);
					val.SetSlotOwner(((Il2CppObjectBase)S1StorageEntity).Cast<IItemSlotOwner>());
				}
				S1StorageEntity.SlotCount = num;
				if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
				{
					int count3 = S1StorageEntity.ItemSlots.Count;
					for (int j = count2; j < count3; j++)
					{
						ItemSlot val2 = S1StorageEntity.ItemSlots[j];
						S1PlaceableStorageEntity.InputSlots.Add(val2);
						S1PlaceableStorageEntity.OutputSlots.Add(val2);
					}
				}
				if (num > 6 && DisplayRowCount < 2)
				{
					DisplayRowCount = 2;
				}
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to add slots: " + ex.Message);
				return false;
			}
		}

		public bool RemoveSlots(int count)
		{
			if (count <= 0)
			{
				Logger.Warning("RemoveSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			if (count > count2)
			{
				Logger.Warning($"Cannot remove {count} slots, only {count2} exist");
				return false;
			}
			try
			{
				for (int i = count2 - count; i < count2; i++)
				{
					if (S1StorageEntity.ItemSlots[i].ItemInstance != null)
					{
						Logger.Warning($"Cannot remove slot {i}, it contains an item");
						return false;
					}
				}
				for (int j = 0; j < count; j++)
				{
					int num = S1StorageEntity.ItemSlots.Count - 1;
					ItemSlot val = S1StorageEntity.ItemSlots[num];
					if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
					{
						S1PlaceableStorageEntity.InputSlots.Remove(val);
						S1PlaceableStorageEntity.OutputSlots.Remove(val);
					}
					S1StorageEntity.ItemSlots.RemoveAt(num);
				}
				S1StorageEntity.SlotCount = count2 - count;
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to remove slots: " + ex.Message);
				return false;
			}
		}

		public bool SetSlotCount(int targetSlotCount)
		{
			if (targetSlotCount < 0)
			{
				Logger.Warning("Cannot set negative slot count");
				return false;
			}
			int count = S1StorageEntity.ItemSlots.Count;
			int num = targetSlotCount - count;
			if (num > 0)
			{
				return AddSlots(num);
			}
			if (num < 0)
			{
				return RemoveSlots(-num);
			}
			return true;
		}

		public int GetEmptySlotCount()
		{
			int num = 0;
			Enumerator<ItemSlot> enumerator = S1StorageEntity.ItemSlots.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemSlot current = enumerator.Current;
				if (current.ItemInstance == null)
				{
					num++;
				}
			}
			return num;
		}

		public int GetOccupiedSlotCount()
		{
			return S1StorageEntity.ItemSlots.Count - GetEmptySlotCount();
		}

		public bool HasItems()
		{
			Enumerator<ItemSlot> enumerator = S1StorageEntity.ItemSlots.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemSlot current = enumerator.Current;
				if (current.ItemInstance != null)
				{
					return true;
				}
			}
			return false;
		}

		public bool IsEmpty()
		{
			return !HasItems();
		}
	}
	public class StorageEventArgs
	{
		public StorageEntity Storage { get; internal set; }

		public string ItemId => Storage?.ItemId;

		internal StorageEventArgs(StorageEntity storage)
		{
			Storage = storage;
		}
	}
	public class StorageLoadingEventArgs : StorageEventArgs
	{
		public int ItemCountBeingLoaded { get; internal set; }

		public int CurrentSlotCount => base.Storage?.SlotCount ?? 0;

		public bool NeedsMoreSlots => ItemCountBeingLoaded > CurrentSlotCount;

		public int AdditionalSlotsNeeded => Math.Max(0, ItemCountBeingLoaded - CurrentSlotCount);

		internal StorageLoadingEventArgs(StorageEntity storage, int itemCount)
			: base(storage)
		{
			ItemCountBeingLoaded = itemCount;
		}
	}
	public static class StorageEvents
	{
		private static readonly Log Logger = new Log("StorageEvents");

		public static event Action<StorageEventArgs> OnStorageCreated;

		public static event Action<StorageLoadingEventArgs> OnStorageLoading;

		public static event Action<StorageEventArgs> OnStorageOpening;

		internal static void RaiseStorageCreated(StorageEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageCreated?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error($"Exception in OnStorageCreated handler for storage '{args.ItemId}': {ex.Message}\n{ex.StackTrace}");
			}
		}

		internal static void RaiseStorageLoading(StorageLoadingEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageLoading?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error($"Exception in OnStorageLoading handler for storage '{args.ItemId}': {ex.Message}\n{ex.StackTrace}");
			}
		}

		internal static void RaiseStorageOpening(StorageEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageOpening?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error($"Exception in OnStorageOpening handler for storage '{args.ItemId}': {ex.Message}\n{ex.StackTrace}");
			}
		}
	}
}
namespace S1API.Storages
{
	public enum StorageAccessSettings
	{
		Closed,
		SinglePlayerOnly,
		Full
	}
	public class StorageInstance
	{
		internal readonly StorageEntity S1Storage;

		public string Name => S1Storage.StorageEntityName;

		public string Subtitle => S1Storage.StorageEntitySubtitle;

		public int SlotCount => S1Storage.SlotCount;

		public int ItemCount => S1Storage.ItemCount;

		public StorageAccessSettings AccessSettings
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected I4, but got Unknown
				return (StorageAccessSettings)S1Storage.AccessSettings;
			}
			set
			{
				S1Storage.AccessSettings = (EAccessSettings)value;
			}
		}

		public bool IsOpened => S1Storage.IsOpened;

		public ItemSlotInstance[] Slots => ((IEnumerable<ItemSlot>)S1Storage.ItemSlots.ToArray()).Select((ItemSlot itemSlot) => new ItemSlotInstance(itemSlot)).ToArray();

		public event Action OnOpened
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened += Action.op_Implicit(h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened -= Action.op_Implicit(h);
				});
			}
		}

		public event Action OnClosed
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed += Action.op_Implicit(h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed -= Action.op_Implicit(h);
				});
			}
		}

		public event Action OnContentsChanged
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged += Action.op_Implicit(h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged -= Action.op_Implicit(h);
				});
			}
		}

		internal StorageInstance(StorageEntity storage)
		{
			S1Storage = storage;
		}

		public static StorageInstance? FromGameObject(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				Debug.LogWarning(Object.op_Implicit("[StorageInstance] FromGameObject called with null GameObject"));
				return null;
			}
			Debug.Log(Object.op_Implicit("[StorageInstance] Searching for StorageEntity on GameObject '" + ((Object)gameObject).name + "'"));
			StorageEntity component = gameObject.GetComponent<StorageEntity>();
			if ((Object)(object)component != (Object)null)
			{
				Debug.Log(Object.op_Implicit("[StorageInstance] Found StorageEntity directly on '" + ((Object)gameObject).name + "'"));
				return new StorageInstance(component);
			}
			Debug.Log(Object.op_Implicit("[StorageInstance] StorageEntity not found directly, searching parent hierarchy of '" + ((Object)gameObject).name + "'"));
			component = gameObject.GetComponentInParent<StorageEntity>();
			if ((Object)(object)component != (Object)null)
			{
				Debug.Log(Object.op_Implicit($"[StorageInstance] Found StorageEntity in parent hierarchy of '{((Object)gameObject).name}' on object '{((Object)((Component)component).gameObject).name}'"));
				return new StorageInstance(component);
			}
			Debug.LogWarning(Object.op_Implicit("[StorageInstance] No StorageEntity found on '" + ((Object)gameObject).name + "' or its parents"));
			return null;
		}

		public static StorageInstance? FromGameObjectInChildren(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				Debug.LogWarning(Object.op_Implicit("[StorageInstance] FromGameObjectInChildren called with null GameObject"));
				return null;
			}
			Debug.Log(Object.op_Implicit("[StorageInstance] Searching for StorageEntity in children of '" + ((Object)gameObject).name + "'"));
			StorageEntity componentInChildren = gameObject.GetComponentInChildren<StorageEntity>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Debug.LogWarning(Object.op_Implicit("[StorageInstance] No StorageEntity found in children of '" + ((Object)gameObject).name + "'"));
				return null;
			}
			Debug.Log(Object.op_Implicit($"[StorageInstance] Found StorageEntity in children of '{((Object)gameObject).name}' on object '{((Object)((Component)componentInChildren).gameObject).name}'"));
			return new StorageInstance(componentInChildren);
		}

		public ItemInstance[] GetItems()
		{
			List<ItemInstance> allItems = S1Storage.GetAllItems();
			if (allItems == null || allItems.Count == 0)
			{
				return Array.Empty<ItemInstance>();
			}
			ItemInstance[] array = new ItemInstance[allItems.Count];
			for (int i = 0; i < allItems.Count; i++)
			{
				array[i] = new ItemInstance(allItems[i]);
			}
			return array;
		}

		public Dictionary<ItemInstance, int> GetContentsDictionary()
		{
			Dictionary<StorableItemInstance, int> contentsDictionary = S1Storage.GetContentsDictionary();
			Dictionary<ItemInstance, int> dictionary = new Dictionary<ItemInstance, int>();
			Enumerator<StorableItemInstance, int> enumerator = contentsDictionary.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<StorableItemInstance, int> current = enumerator.Current;
				if (current.Key != null)
				{
					dictionary[new ItemInstance((ItemInstance)(object)current.Key)] = current.Value;
				}
			}
			return dictionary;
		}

		public bool CanItemFit(ItemInstance itemInstance, int quantity = 1)
		{
			return S1Storage.CanItemFit(itemInstance.S1ItemInstance, quantity);
		}

		public void AddItem(ItemInstance itemInstance)
		{
			S1Storage.InsertItem(itemInstance.S1ItemInstance, true);
		}

		public int RemoveItem(ItemInstance itemInstance)
		{
			if (itemInstance == null)
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance == itemInstance.S1ItemInstance)
				{
					int quantity = val.Quantity;
					val.ClearStoredInstance(false);
					num += quantity;
					break;
				}
			}
			return num;
		}

		public int TryRemoveQuantity(string itemDefinitionId, int quantity)
		{
			if (string.IsNullOrEmpty(itemDefinitionId) || quantity <= 0)
			{
				return 0;
			}
			int num = quantity;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				if (num <= 0)
				{
					break;
				}
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					int quantity2 = val.Quantity;
					int num2 = Math.Min(num, quantity2);
					num -= num2;
					if (num2 >= quantity2)
					{
						val.ClearStoredInstance(false);
					}
					else
					{
						val.ChangeQuantity(-num2, false);
					}
				}
			}
			return quantity - num;
		}

		public int RemoveAllOfDefinition(string itemDefinitionId)
		{
			if (string.IsNullOrEmpty(itemDefinitionId))
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					num += val.Quantity;
					val.ClearStoredInstance(false);
				}
			}
			return num;
		}
	}
	public static class StorageManager
	{
		public static StorageInstance[] GetAll()
		{
			List<StorageInstance> list = new List<StorageInstance>();
			if (WorldStorageEntity.All == null)
			{
				return list.ToArray();
			}
			Enumerator<WorldStorageEntity> enumerator = WorldStorageEntity.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				WorldStorageEntity current = enumerator.Current;
				if ((Object)(object)current != (Object)null)
				{
					list.Add(new StorageInstance((StorageEntity)(object)current));
				}
			}
			return list.ToArray();
		}

		public static StorageInstance? FindByName(string name)
		{
			if (string.IsNullOrEmpty(name) || WorldStorageEntity.All == null)
			{
				return null;
			}
			Enumerator<WorldStorageEntity> enumerator = WorldStorageEntity.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				WorldStorageEntity current = enumerator.Current;
				if ((Object)(object)current != (Object)null && ((StorageEntity)current).StorageEntityName == name)
				{
					return new StorageInstance((StorageEntity)(object)current);
				}
			}
			return null;
		}

		public static StorageInstance[] FindByPredicate(Func<StorageInstance, bool> predicate)
		{
			if (predicate == null || WorldStorageEntity.All == null)
			{
				return Array.Empty<StorageInstance>();
			}
			List<StorageInstance> list = new List<StorageInstance>();
			Enumerator<WorldStorageEntity> enumerator = WorldStorageEntity.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				WorldStorageEntity current = enumerator.Current;
				if ((Object)(object)current != (Object)null)
				{
					StorageInstance storageInstance = new StorageInstance((StorageEntity)(object)current);
					if (predicate(storageInstance))
					{
						list.Add(storageInstance);
					}
				}
			}
			return list.ToArray();
		}
	}
}
namespace S1API.Shops
{
	public sealed class Shop
	{
		internal ShopInterface S1ShopInterface { get; }

		public string Name => S1ShopInterface.ShopName;

		internal Shop(ShopInterface shopInterface)
		{
			S1ShopInterface = shopInterface;
		}

		public bool HasItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			Enumerator<ShopListing> enumerator = S1ShopInterface.Listings.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ShopListing current = enumerator.Current;
				object obj;
				if (current == null)
				{
					obj = null;
				}
				else
				{
					StorableItemDefinition item = current.Item;
					obj = ((item != null) ? ((ItemDefinition)item).ID : null);
				}
				if ((string?)obj == itemId)
				{
					return true;
				}
			}
			return false;
		}

		public bool SellsCategory(ItemCategory category)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			EItemCategory val = (EItemCategory)category;
			Enumerator<ShopListing> enumerator = S1ShopInterface.Listings.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ShopListing current = enumerator.Current;
				if ((Object)(object)((current != null) ? current.Item : null) != (Object)null && ((ItemDefinition)current.Item).Category == val)
				{
					return true;
				}
			}
			return false;
		}

		public string[] GetItemIds()
		{
			List<string> list = new List<string>();
			Enumerator<ShopListing> enumerator = S1ShopInterface.Listings.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ShopListing current = enumerator.Current;
				if ((Object)(object)((current != null) ? current.Item : null) != (Object)null)
				{
					list.Add(((ItemDefinition)current.Item).ID);
				}
			}
			return list.ToArray();
		}

		public bool AddItem(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return false;
			}
			if (HasItem(item.ID))
			{
				return false;
			}
			return ShopIntegration.AddItemToShop(this, item, customPrice);
		}

		public bool RemoveItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			return ShopIntegration.RemoveItemFromShop(this, itemId);
		}
	}
	public static class ShopManager
	{
		private static readonly Log Logger = new Log("ShopManager");

		private static readonly List<Shop> _cachedShops = new List<Shop>();

		private static bool _cacheValid = false;

		public static Shop[] GetAllShops()
		{
			RefreshCacheIfNeeded();
			return _cachedShops.ToArray();
		}

		public static Shop GetShopByName(string shopName)
		{
			string shopName2 = shopName;
			if (string.IsNullOrEmpty(shopName2))
			{
				return null;
			}
			return GetAllShops().FirstOrDefault((Shop s) => string.Equals(s.Name, shopName2, StringComparison.OrdinalIgnoreCase));
		}

		public static Shop[] FindShopsByCategory(ItemCategory category)
		{
			return (from s in GetAllShops()
				where s.SellsCategory(category)
				select s).ToArray();
		}

		public static Shop[] FindShopsByItem(string itemId)
		{
			string itemId2 = itemId;
			if (string.IsNullOrEmpty(itemId2))
			{
				return Array.Empty<Shop>();
			}
			return (from s in GetAllShops()
				where s.HasItem(itemId2)
				select s).ToArray();
		}

		public static int AddToCompatibleShops(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return 0;
			}
			Shop[] array = FindShopsByCategory(item.Category);
			int num = 0;
			Shop[] array2 = array;
			foreach (Shop shop in array2)
			{
				if (shop.AddItem(item, customPrice))
				{
					num++;
				}
			}
			if (num > 0)
			{
				Logger.Msg($"Added item '{item.Name}' to {num} compatible shop(s)");
			}
			return num;
		}

		public static int AddToShops(ItemDefinition item, params string[] shopNames)
		{
			return AddToShops(item, null, shopNames);
		}

		public static int AddToShops(ItemDefinition item, float? customPrice, params string[] shopNames)
		{
			if (item == null || shopNames == null || shopNames.Length == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (string shopName in shopNames)
			{
				Shop shopByName = GetShopByName(shopName);
				if (shopByName != null && shopByName.AddItem(item, customPrice))
				{
					num++;
				}
			}
			return num;
		}

		public static int RefreshItemIcon(ItemDefinition item)
		{
			if (item == null)
			{
				return 0;
			}
			return ShopIntegration.RefreshItemIconInShops(item);
		}

		public static int RefreshItemIcon(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return 0;
			}
			Shop[] array = FindShopsByItem(itemId);
			if (array.Length == 0)
			{
				return 0;
			}
			Shop[] array2 = array;
			foreach (Shop shop in array2)
			{
				Enumerator<ShopListing> enumerator = shop.S1ShopInterface.Listings.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ShopListing current = enumerator.Current;
					object obj;
					if (current == null)
					{
						obj = null;
					}
					else
					{
						StorableItemDefinition item = current.Item;
						obj = ((item != null) ? ((ItemDefinition)item).ID : null);
					}
					if ((string?)obj == itemId)
					{
						ItemDefinition itemDefinition = ItemManager.GetItemDefinition(itemId);
						if (itemDefinition != null)
						{
							return RefreshItemIcon(itemDefinition);
						}
						return 0;
					}
				}
			}
			return 0;
		}

		internal static void InvalidateCache()
		{
			_cacheValid = false;
			_cachedShops.Clear();
		}

		private static void RefreshCacheIfNeeded()
		{
			if (_cacheValid)
			{
				return;
			}
			_cachedShops.Clear();
			try
			{
				List<ShopInterface> allShops = ShopInterface.AllShops;
				if (allShops == null)
				{
					_cacheValid = true;
					return;
				}
				Enumerator<ShopInterface> enumerator = allShops.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ShopInterface current = enumerator.Current;
					if ((Object)(object)current != (Object)null)
					{
						_cachedShops.Add(new Shop(current));
					}
				}
				_cacheValid = true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to refresh shop cache: " + ex.Message);
				_cacheValid = false;
			}
		}
	}
}
namespace S1API.Saveables
{
	internal static class SaveableAutoRegistry
	{
		[CompilerGenerated]
		private sealed class <GetOrCreateInstances>d__7 : IEnumerable<Saveable>, IEnumerable, IEnumerator<Saveable>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Saveable <>2__current;

			private int <>l__initialThreadId;

			private List<Type>.Enumerator <>s__1;

			private Type <saveableType>5__2;

			private Saveable <instance>5__3;

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

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

			[DebuggerHidden]
			public <GetOrCreateInstances>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = default(List<Type>.Enumerator);
				<saveableType>5__2 = null;
				<instance>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00eb;
					}
					<>1__state = -1;
					<>s__1 = _discoveredSaveableTypes.GetEnumerator();
					<>1__state = -3;
					goto IL_00fa;
					IL_00eb:
					<instance>5__3 = null;
					<saveableType>5__2 = null;
					goto IL_00fa;
					IL_00fa:
					if (<>s__1.MoveNext())
					{
						<saveableType>5__2 = <>s__1.Current;
						if (!_instances.TryGetValue(<saveableType>5__2, out <instance>5__3))
						{
							try
							{
								<instance>5__3 = (Saveable)Activator.CreateInstance(<saveableType>5__2, nonPublic: true);
								if (<instance>5__3 != null)
								{
									_instances[<saveableType>5__2] = <instance>5__3;
								}
							}
							catch
							{
							}
						}
						if (<instance>5__3 != null)
						{
							<>2__current = <instance>5__3;
							<>1__state = 1;
							return true;
						}
						goto IL_00eb;
					}
					<>m__Finally1();
					<>s__1 = default(List<Type>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<Saveable> IEnumerable<Saveable>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetOrCreateInstances>d__7(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Saveable>)this).GetEnumerator();
			}
		}

		private static readonly List<Type> _discoveredSaveableTypes = new List<Type>();

		private static readonly Dictionary<Type, Saveable> _instances = new Dictionary<Type, Saveable>();

		private static bool _discoveryPerformed = false;

		private static readonly object _lock = new object();

		public static IEnumerable<Saveable> GetRegisteredSaveables()
		{
			lock (_lock)
			{
				if (!_discoveryPerformed)
				{
					DiscoverSaveableTypes();
					_discoveryPerformed = true;
				}
				return GetOrCreateInstances();
			}
		}

		private static void DiscoverSaveableTypes()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					try
					{
						if (assembly == executingAssembly)
						{
							continue;
						}
						string? fullName = assembly.FullName;
						if (fullName != null && fullName.StartsWith("System"))
						{
							continue;
						}
						string? fullName2 = assembly.FullName;
						if (fullName2 != null && fullName2.StartsWith("Unity"))
						{
							continue;
						}
						string? fullName3 = assembly.FullName;
						if (fullName3 != null && fullName3.StartsWith("mscorlib"))
						{
							continue;
						}
						string? fullName4 = assembly.FullName;
						if (fullName4 != null && fullName4.StartsWith("netstandard"))
						{
							continue;
						}
						string? fullName5 = assembly.FullName;
						if (fullName5 != null && fullName5.StartsWith("Microsoft"))
						{
							continue;
						}
						string? fullName6 = assembly.FullName;
						if (fullName6 != null && fullName6.StartsWith("Il2Cpp"))
						{
							continue;
						}
						string? fullName7 = assembly.FullName;
						if (fullName7 != null && fullName7.StartsWith("MelonLoader"))
						{
							continue;
						}
						string? fullName8 = assembly.FullName;
						if ((fullName8 != null && fullName8.StartsWith("0Harmony")) || assembly.IsDynamic)
						{
							continue;
						}
						Type[] array;
						try
						{
							array = assembly.GetTypes();
						}
						catch (ReflectionTypeLoadException ex)
						{
							array = ex.Types.Where((Type t) => t != null).ToArray();
						}
						catch
						{
							goto end_IL_0020;
						}
						Type[] array2 = array;
						foreach (Type type in array2)
						{
							try
							{
								if (!(type == null) && !type.IsAbstract && !type.IsInterface && !type.IsGenericTypeDefinition && IsDirectSaveableInheritor(type))
								{
									_discoveredSaveableTypes.Add(type);
								}
							}
							catch
							{
							}
						}
						end_IL_0020:;
					}
					catch
					{
					}
				}
			}
			catch (Exception ex2)
			{
				try
				{
					MelonLogger.Warning("[S1API] Error during saveable type discovery: " + ex2.Message);
				}
				catch
				{
				}
			}
		}

		private static bool IsDirectSaveableInheritor(Type type)
		{
			if (!typeof(Saveable).IsAssignableFrom(type))
			{
				return false;
			}
			if (type.IsAbstract || type.IsInterface)
			{
				return false;
			}
			Type baseType = type.BaseType;
			return baseType == typeof(Saveable);
		}

		[IteratorStateMachine(typeof(<GetOrCreateInstances>d__7))]
		private static IEnumerable<Saveable> GetOrCreateInstances()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetOrCreateInstances>d__7(-2);
		}

		internal static void ClearCache()
		{
			lock (_lock)
			{
				_discoveredSaveableTypes.Clear();
				_instances.Clear();
				_discoveryPerformed = false;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class SaveableField : Attribute
	{
		internal string SaveName { get; }

		public SaveableField(string saveName)
		{
			SaveName = saveName;
		}
	}
	public enum SaveableLoadOrder
	{
		BeforeBaseGame,
		AfterBaseGame
	}
}
namespace S1API.Rendering
{
	public static class AccessoryFactory
	{
		private static readonly Log Logger = new Log("AccessoryFactory");

		internal static readonly Dictionary<string, Dictionary<string, Texture2D>> _accessoryTextureRegistry = new Dictionary<string, Dictionary<string, Texture2D>>();

		public static GameObject CloneAccessoryWithCustomTextures(string sourceResourcePath, string newName, Dictionary<string, Texture2D> textureReplacements = null, Color? colorTint = null, string targetResourcePath = null)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = Resources.Load<GameObject>(sourceResourcePath);
				if ((Object)(object)val == (Object)null)
				{
					Logger.Error("Failed to load source accessory at path: " + sourceResourcePath);
					return null;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val);
				((Object)val2).name = newName;
				Object.DontDestroyOnLoad((Object)(object)val2);
				val2.SetActive(false);
				Accessory component = val2.GetComponent<Accessory>();
				if ((Object)(object)component != (Object)null)
				{
					component.AssetPath = targetResourcePath ?? sourceResourcePath;
					component.Name = newName;
				}
				if (textureReplacements != null && textureReplacements.Count > 0)
				{
					ApplyTexturesToAccessory(val2, textureReplacements);
				}
				if (colorTint.HasValue && (Object)(object)component != (Object)null)
				{
					component.ApplyColor(colorTint.Value);
				}
				val2.SetActive(true);
				return val2;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to clone accessory '" + sourceResourcePath + "': " + ex.Message);
				Logger.Error(ex.StackTrace);
				return null;
			}
		}

		private static void ApplyTexturesToAccessory(GameObject accessory, Dictionary<string, Texture2D> textureReplacements)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			Il2CppArrayBase<Renderer> componentsInChildren = accessory.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer item in componentsInChildren)
			{
				Il2CppRefer

Mods/S1API.Mono.MelonLoader.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using FishNet;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Client;
using FishNet.Managing.Object;
using FishNet.Managing.Scened;
using FishNet.Managing.Server;
using FishNet.Managing.Transporting;
using FishNet.Object;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using S1API;
using S1API.AssetBundles;
using S1API.Avatar;
using S1API.Building;
using S1API.Casino;
using S1API.Conditions;
using S1API.Console;
using S1API.Economy;
using S1API.Entities;
using S1API.Entities.Appearances.AccessoryFields;
using S1API.Entities.Appearances.Base;
using S1API.Entities.Appearances.BodyLayerFields;
using S1API.Entities.Appearances.CustomizationFields;
using S1API.Entities.Appearances.FaceLayerFields;
using S1API.Entities.Behaviour;
using S1API.Entities.Customer;
using S1API.Entities.Dealer;
using S1API.Entities.Dialogue;
using S1API.Entities.Interfaces;
using S1API.Entities.Relation;
using S1API.Entities.Schedule;
using S1API.GameTime;
using S1API.Graffiti;
using S1API.Internal;
using S1API.Internal.Abstraction;
using S1API.Internal.Entities;
using S1API.Internal.Items;
using S1API.Internal.Lifecycle;
using S1API.Internal.Map;
using S1API.Internal.Patches;
using S1API.Internal.Shops;
using S1API.Internal.Utils;
using S1API.Items;
using S1API.Law;
using S1API.Lifecycle;
using S1API.Logging;
using S1API.Map;
using S1API.Map.Buildings;
using S1API.Map.DeliveryLocations;
using S1API.Messaging;
using S1API.Money;
using S1API.PhoneApp;
using S1API.PhoneCalls;
using S1API.PhoneCalls.Constants;
using S1API.Products;
using S1API.Products.Packaging;
using S1API.Properties;
using S1API.Properties.Interfaces;
using S1API.Properties.Internal;
using S1API.Properties.Tokens;
using S1API.Property;
using S1API.Quests;
using S1API.Quests.Constants;
using S1API.Quests.Identifiers;
using S1API.Rendering;
using S1API.Saveables;
using S1API.Shops;
using S1API.Storage;
using S1API.Storages;
using S1API.Utils;
using S1API.Vehicles;
using ScheduleOne;
using ScheduleOne.AvatarFramework;
using ScheduleOne.AvatarFramework.Animation;
using ScheduleOne.AvatarFramework.Customization;
using ScheduleOne.AvatarFramework.Equipping;
using ScheduleOne.Building;
using ScheduleOne.Calling;
using ScheduleOne.Cartel;
using ScheduleOne.Casino;
using ScheduleOne.Clothing;
using ScheduleOne.Combat;
using ScheduleOne.DevUtilities;
using ScheduleOne.Dialogue;
using ScheduleOne.Doors;
using ScheduleOne.Economy;
using ScheduleOne.Effects;
using ScheduleOne.EntityFramework;
using ScheduleOne.Equipping;
using ScheduleOne.GameTime;
using ScheduleOne.Graffiti;
using ScheduleOne.Growing;
using ScheduleOne.Interaction;
using ScheduleOne.ItemFramework;
using ScheduleOne.Law;
using ScheduleOne.Levelling;
using ScheduleOne.Management;
using ScheduleOne.Map;
using ScheduleOne.Messaging;
using ScheduleOne.Misc;
using ScheduleOne.Money;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.Actions;
using ScheduleOne.NPCs.Behaviour;
using ScheduleOne.NPCs.Relation;
using ScheduleOne.NPCs.Responses;
using ScheduleOne.NPCs.Schedules;
using ScheduleOne.Noise;
using ScheduleOne.ObjectScripts;
using ScheduleOne.Persistence;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.Persistence.Loaders;
using ScheduleOne.PlayerScripts;
using ScheduleOne.PlayerScripts.Health;
using ScheduleOne.Police;
using ScheduleOne.Product;
using ScheduleOne.Product.Packaging;
using ScheduleOne.Property;
using ScheduleOne.Quests;
using ScheduleOne.ScriptableObjects;
using ScheduleOne.Storage;
using ScheduleOne.Trash;
using ScheduleOne.UI;
using ScheduleOne.UI.MainMenu;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Phone.ContactsApp;
using ScheduleOne.UI.Phone.Messages;
using ScheduleOne.UI.Phone.ProductManagerApp;
using ScheduleOne.UI.Relations;
using ScheduleOne.UI.Shop;
using ScheduleOne.UI.WorldspacePopup;
using ScheduleOne.Variables;
using ScheduleOne.Vehicles;
using ScheduleOne.Vehicles.Modification;
using ScheduleOne.Vision;
using ScheduleOne.VoiceOver;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
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(global::S1API.S1API), "S1API (Forked by Bars)", "2.9.2", "KaBooMa", null)]
[assembly: MelonPriority(int.MinValue)]
[assembly: MelonIncompatibleAssemblies(new string[] { "ModManager&PhoneApp", "AutoClearCompletedDeals" })]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ifBars")]
[assembly: AssemblyConfiguration("MonoMelon")]
[assembly: AssemblyDescription("A Schedule One Mono / Il2Cpp Cross Compatibility Layer (Forked from the original S1API by Kabooma)")]
[assembly: AssemblyFileVersion("2.9.2.0")]
[assembly: AssemblyInformationalVersion("2.9.2+623ba0bc66e3fd4bebc9967c20b451020fa6a3a2")]
[assembly: AssemblyProduct("S1API")]
[assembly: AssemblyTitle("S1API")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ifBars/S1API")]
[assembly: AssemblyVersion("2.9.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class ClickHandler
{
	private readonly UnityAction _callback;

	public ClickHandler(UnityAction callback)
	{
		_callback = callback;
	}

	public void OnClick()
	{
		_callback.Invoke();
	}
}
namespace S1API
{
	public class S1API : MelonMod
	{
		public override void OnPreSupportModule()
		{
			VersionChecker.CheckMelonLoaderVersion();
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				GameLifecycle.Initialize();
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: true);
			if (sceneName == "Main")
			{
				GameLifecycle.Reset();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			NPCNetworkBootstrap.EnsurePrefabsWarmup();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: false);
		}
	}
	public static class VersionChecker
	{
		private const string PROBLEMATIC_VERSION = "0.7.1";

		private const string RECOMMENDED_VERSION_1 = "0.7.0";

		private const string RECOMMENDED_VERSION_2 = "0.7.2-nightly";

		public static void CheckMelonLoaderVersion()
		{
			try
			{
				string melonLoaderVersion = GetMelonLoaderVersion();
				if (string.IsNullOrEmpty(melonLoaderVersion))
				{
					MelonLogger.Warning("[S1API VersionChecker] Could not determine MelonLoader version!");
					return;
				}
				MelonLogger.Msg("========================================");
				MelonLogger.Msg("[S1API VersionChecker] MelonLoader Version Detected: " + melonLoaderVersion);
				MelonLogger.Msg("========================================");
				if (IsProblematicVersion(melonLoaderVersion))
				{
					ShowBigWarning(melonLoaderVersion);
				}
				else
				{
					MelonLogger.Msg("[S1API VersionChecker] Your MelonLoader version appears to be compatible!");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[S1API VersionChecker] Version check failed: " + ex.Message);
			}
		}

		private static string GetMelonLoaderVersion()
		{
			try
			{
				Assembly assembly = typeof(MelonMod).Assembly;
				PropertyInfo propertyInfo = assembly.GetType("MelonLoader.Properties.BuildInfo")?.GetProperty("VersionNumber");
				if (propertyInfo?.GetValue(null) != null)
				{
					object value = propertyInfo.GetValue(null);
					return value.ToString() ?? GetVersionFromAssembly(assembly);
				}
				return GetVersionFromAssembly(assembly);
			}
			catch
			{
				try
				{
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly2 in assemblies)
					{
						string name = assembly2.GetName().Name;
						if (name != null && (name.Equals("MelonLoader") || name.Equals("MelonLoader.Core")))
						{
							return GetVersionFromAssembly(assembly2);
						}
					}
				}
				catch
				{
				}
				return null;
			}
		}

		private static string GetVersionFromAssembly(Assembly assembly)
		{
			Version version = assembly.GetName().Version;
			if (version != null)
			{
				return $"{version.Major}.{version.Minor}.{version.Build}";
			}
			return null;
		}

		private static bool IsProblematicVersion(string version)
		{
			if (string.IsNullOrEmpty(version))
			{
				return false;
			}
			return version.StartsWith("0.7.1", StringComparison.OrdinalIgnoreCase);
		}

		private static void ShowBigWarning(string detectedVersion)
		{
			string text = string.Format("\r\n╔════════════════════════════════════════════════════════════════════════╗\r\n║                                                                        ║\r\n║                        !!! URGENT WARNING !!!                          ║\r\n║                                                                        ║\r\n║                YOU ARE USING MELONLOADER VERSION {0,-21} ║\r\n║                                                                        ║\r\n║      This version is KNOWN TO HAVE CRITICAL ISSUES and may cause:      ║\r\n║                                                                        ║\r\n║                - Game crashes and unexpected behavior                  ║\r\n║                - Mod incompatibility and loading failures              ║\r\n║                - Performance issues and memory leaks                   ║\r\n║                - Random errors and instability                         ║\r\n║                                                                        ║\r\n║           PLEASE UPDATE IMMEDIATELY to one of these versions:          ║\r\n║                                                                        ║\r\n║                ► {1,-27} (Stable Release)          ║\r\n║                ► {2,-27} (Latest Nightly)          ║\r\n║                                                                        ║\r\n║      Download: https://melonwiki.xyz/#/?id=automated-installation      ║\r\n║                                                                        ║\r\n╚════════════════════════════════════════════════════════════════════════╝", detectedVersion, "0.7.0", "0.7.2-nightly");
			MelonLogger.Error(text);
			MelonLogger.Error("[S1API VersionChecker] DETECTED PROBLEMATIC MELONLOADER VERSION: " + detectedVersion);
			MelonLogger.Error("[S1API VersionChecker] PLEASE UPDATE TO 0.7.0 OR 0.7.2-nightly");
			MelonLogger.Error(string.Concat(Enumerable.Repeat(Environment.NewLine, 2)));
			MelonLogger.Warning("[S1API VersionChecker] IMPORTANT: This message will be available in logs for your reference at \n" + Path.Combine(MelonEnvironment.MelonLoaderLogsDirectory, "Latest.log"));
		}
	}
}
namespace S1API.Vehicles
{
	public class LandVehicle
	{
		internal LandVehicle S1LandVehicle = null;

		internal bool _isDeferredByName = false;

		internal StorageInstance _storage;

		private static readonly Log _logger = new Log("S1API.LandVehicle");

		private static readonly FieldInfo? VehiclePriceField = typeof(LandVehicle).GetField("vehiclePrice", BindingFlags.NonPublic);

		private NetworkConnection? _conn;

		private string _guid = string.Empty;

		public float VehiclePrice
		{
			get
			{
				return S1LandVehicle.VehiclePrice;
			}
			set
			{
				VehiclePriceField?.SetValue(S1LandVehicle, value);
			}
		}

		public float TopSpeed
		{
			get
			{
				return S1LandVehicle.TopSpeed;
			}
			set
			{
				S1LandVehicle.TopSpeed = value;
			}
		}

		public bool IsPlayerOwned
		{
			get
			{
				return S1LandVehicle.IsPlayerOwned;
			}
			set
			{
				SetIsPlayerOwned(value);
			}
		}

		public bool IsOccupied
		{
			get
			{
				return S1LandVehicle.IsOccupied;
			}
			set
			{
				S1LandVehicle.IsOccupied = value;
			}
		}

		public VehicleColor Color
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Expected I4, but got Unknown
				return (VehicleColor)S1LandVehicle.OwnedColor;
			}
			set
			{
				SetColor(value);
			}
		}

		public string GUID => _guid;

		public StorageInstance Storage => _storage;

		public event Action OnVehicleStart
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStart = (Action)Delegate.Combine(s1LandVehicle.onVehicleStart, value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStart = (Action)Delegate.Remove(s1LandVehicle.onVehicleStart, value);
			}
		}

		public event Action OnVehicleStop
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStop = (Action)Delegate.Combine(s1LandVehicle.onVehicleStop, value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onVehicleStop = (Action)Delegate.Remove(s1LandVehicle.onVehicleStop, value);
			}
		}

		public event Action OnHandbrakeApplied
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onHandbrakeApplied = (Action)Delegate.Combine(s1LandVehicle.onHandbrakeApplied, value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onHandbrakeApplied = (Action)Delegate.Remove(s1LandVehicle.onHandbrakeApplied, value);
			}
		}

		public event Action<Collision> OnCollision
		{
			add
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onCollision = (Action<Collision>)Delegate.Combine(s1LandVehicle.onCollision, value);
			}
			remove
			{
				LandVehicle s1LandVehicle = S1LandVehicle;
				s1LandVehicle.onCollision = (Action<Collision>)Delegate.Remove(s1LandVehicle.onCollision, value);
			}
		}

		public LandVehicle(string vehicleCode)
		{
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(vehicleCode);
			if ((Object)(object)vehiclePrefab == (Object)null)
			{
				_logger.Error("SpawnVehicle: '" + vehicleCode + "' is not a valid vehicle code!");
				return;
			}
			LandVehicle component = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject).GetComponent<LandVehicle>();
			component.SetGUID(GUIDManager.GenerateUniqueGUID());
			NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component);
			S1LandVehicle = component;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(component.Storage);
		}

		public void Spawn(Vector3 position, Quaternion rotation)
		{
			//IL_0046: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServer)
			{
				_logger.Warning("Spawn can only be called on the server!");
				return;
			}
			if ((Object)(object)S1LandVehicle == (Object)null)
			{
				throw new Exception("Unable to spawn vehicle, S1LandVehicle is null!");
			}
			((Component)S1LandVehicle).transform.position = position;
			((Component)S1LandVehicle).transform.rotation = rotation;
			((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).Spawn(((Component)S1LandVehicle).gameObject, (NetworkConnection)null, default(Scene));
		}

		public void AlignTo(Transform target, ParkingAlignment type, bool network = false)
		{
			if ((Object)(object)S1LandVehicle == (Object)null)
			{
				throw new Exception("Unable to align to position, S1LandVehicle is null!");
			}
			S1LandVehicle.AlignTo(target, (EParkingAlignment)type, network);
		}

		public void ExitPark(bool moveToExitPoint = true)
		{
			S1LandVehicle.ExitPark(moveToExitPoint);
		}

		public void SetVisible(bool vis)
		{
			S1LandVehicle.SetVisible(vis);
		}

		public void DestroyVehichle()
		{
			S1LandVehicle.DestroyVehicle();
		}

		public void ApplyColor(VehicleColor col)
		{
			S1LandVehicle.ApplyColor((EVehicleColor)col);
		}

		public void Park(ParkingData parkData, bool network)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			ParkData val = new ParkData
			{
				lotGUID = Guid.Parse(parkData.LotId),
				spotIndex = parkData.Index,
				alignment = (EParkingAlignment)parkData.Alignment
			};
			S1LandVehicle.Park(_conn, val, network);
		}

		internal LandVehicle(LandVehicle landVehicle)
		{
			S1LandVehicle = landVehicle;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(landVehicle.Storage);
			_isDeferredByName = false;
		}

		internal LandVehicle(string vehicleName, bool isDeferred)
		{
			_isDeferredByName = isDeferred;
		}

		private void SetConnection()
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if (networkManager.IsClientOnly)
			{
				NetworkConnection connection = InstanceFinder.ClientManager.Connection;
				if (connection != (NetworkConnection)null && connection.IsValid)
				{
					_conn = connection;
				}
			}
			else if (networkManager.IsServerOnly || (networkManager.IsServer && !networkManager.IsClient))
			{
				NetworkConnection owner = ((NetworkBehaviour)S1LandVehicle).Owner;
				if (owner != (NetworkConnection)null && owner.IsValid)
				{
					_conn = owner;
				}
			}
		}

		private void SetIsPlayerOwned(bool isPlayerOwned)
		{
			S1LandVehicle.SetIsPlayerOwned(_conn, isPlayerOwned);
			if (isPlayerOwned)
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(S1LandVehicle);
			}
			else
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Remove(S1LandVehicle);
			}
		}

		private void SetColor(VehicleColor color)
		{
			MethodInfo method = typeof(LandVehicle).GetMethod("SetOwnedColor", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method == null)
			{
				_logger.Error("SetOwnedColor method not found!");
				return;
			}
			method.Invoke(S1LandVehicle, new object[2]
			{
				_conn,
				(object)(EVehicleColor)color
			});
		}

		private void UpdateGuidFromGame()
		{
			try
			{
				PropertyInfo property = typeof(LandVehicle).GetProperty("GUID", BindingFlags.Instance | BindingFlags.Public);
				if (!(property == null))
				{
					_guid = ((Guid)(property.GetValue(S1LandVehicle) ?? ((object)Guid.Empty))).ToString();
				}
			}
			catch
			{
			}
		}
	}
	public enum ParkingAlignment
	{
		FrontToKerb,
		RearToKerb
	}
	public enum VehicleColor
	{
		Black,
		DarkGrey,
		LightGrey,
		White,
		Yellow,
		Orange,
		Red,
		DullRed,
		Pink,
		Purple,
		Navy,
		DarkBlue,
		LightBlue,
		Cyan,
		LightGreen,
		DarkGreen,
		Custom
	}
	public static class VehicleRegistry
	{
		private static readonly Dictionary<object, LandVehicle> _cache = new Dictionary<object, LandVehicle>();

		public static LandVehicle[] GetAll()
		{
			try
			{
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles == null)
				{
					return Array.Empty<LandVehicle>();
				}
				List<LandVehicle> list = new List<LandVehicle>();
				foreach (LandVehicle item in allVehicles)
				{
					if ((Object)(object)item != (Object)null)
					{
						LandVehicle landVehicle = Wrap(item);
						if (landVehicle != null)
						{
							list.Add(landVehicle);
						}
					}
				}
				return list.ToArray();
			}
			catch
			{
				return Array.Empty<LandVehicle>();
			}
		}

		public static LandVehicle GetByGUID(string guid)
		{
			if (string.IsNullOrEmpty(guid))
			{
				return null;
			}
			try
			{
				Guid guid2 = new Guid(guid);
				LandVehicle @object = GUIDManager.GetObject<LandVehicle>(guid2);
				if ((Object)(object)@object == (Object)null)
				{
					return null;
				}
				return Wrap(@object);
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle GetByName(string gameObjectName)
		{
			if (string.IsNullOrEmpty(gameObjectName))
			{
				return null;
			}
			try
			{
				GameObject val = GameObject.Find(gameObjectName);
				if ((Object)(object)val != (Object)null)
				{
					LandVehicle component = val.GetComponent<LandVehicle>();
					if ((Object)(object)component != (Object)null)
					{
						return Wrap(component);
					}
				}
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles != null)
				{
					for (int i = 0; i < allVehicles.Count; i++)
					{
						LandVehicle val2 = allVehicles[i];
						if ((Object)(object)val2 != (Object)null && ((Object)((Component)val2).gameObject).name == gameObjectName)
						{
							return Wrap(val2);
						}
					}
				}
				if (DeferredMapResolver.IsMenuScene())
				{
					LandVehicle deferredVehicle = new LandVehicle(gameObjectName, isDeferred: true);
					DeferredMapResolver.RegisterDeferredLookup(new DeferredLookup(gameObjectName, delegate(object resolved)
					{
						if (resolved is LandVehicle landVehicle && landVehicle != null && (Object)(object)landVehicle.S1LandVehicle != (Object)null)
						{
							deferredVehicle.S1LandVehicle = landVehicle.S1LandVehicle;
							deferredVehicle._isDeferredByName = false;
						}
					}));
					return deferredVehicle;
				}
				return null;
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle CreateVehicle(string vehicleCode)
		{
			if (!string.IsNullOrEmpty(vehicleCode))
			{
				try
				{
					return new LandVehicle(vehicleCode);
				}
				catch
				{
					return null;
				}
			}
			return null;
		}

		public static void RemoveVehicle(string guidString)
		{
			if (string.IsNullOrEmpty(guidString))
			{
				return;
			}
			VehicleManager instance = NetworkSingleton<VehicleManager>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Guid g = new Guid(guidString);
			int? num = null;
			LandVehicle val = null;
			List<LandVehicle> allVehicles = instance.AllVehicles;
			if (allVehicles != null)
			{
				for (int i = 0; i < allVehicles.Count; i++)
				{
					LandVehicle obj = allVehicles[i];
					if (obj != null && obj.GUID.Equals(g))
					{
						num = i;
						val = allVehicles[i];
						break;
					}
				}
			}
			int? num2 = null;
			List<LandVehicle> playerOwnedVehicles = instance.PlayerOwnedVehicles;
			if (playerOwnedVehicles != null)
			{
				for (int j = 0; j < playerOwnedVehicles.Count; j++)
				{
					LandVehicle obj2 = playerOwnedVehicles[j];
					if (obj2 != null && obj2.GUID.Equals(g))
					{
						num2 = j;
						break;
					}
				}
			}
			if (num.HasValue)
			{
				allVehicles?.RemoveAt(num.Value);
			}
			if (num2.HasValue)
			{
				playerOwnedVehicles?.RemoveAt(num2.Value);
			}
			if ((Object)(object)val != (Object)null && _cache.ContainsKey(val))
			{
				_cache.Remove(val);
			}
		}

		private static LandVehicle Wrap(LandVehicle veh)
		{
			if ((Object)(object)veh == (Object)null)
			{
				return null;
			}
			if (_cache.TryGetValue(veh, out LandVehicle value))
			{
				return value;
			}
			LandVehicle landVehicle = new LandVehicle(veh);
			_cache[veh] = landVehicle;
			return landVehicle;
		}
	}
}
namespace S1API.Utils
{
	public static class ArrayExtensions
	{
		public static T[] AddItemToArray<T>(this T[]? array, T item)
		{
			return global::S1API.Internal.Utils.ArrayExtensions.AddItemToArray(array, item);
		}
	}
	public static class ButtonUtils
	{
		public static void AddListener(Button button, Action action)
		{
			global::S1API.Internal.Utils.ButtonUtils.AddListener(button, action);
		}

		public static void RemoveListener(Button button, Action action)
		{
			global::S1API.Internal.Utils.ButtonUtils.RemoveListener(button, action);
		}

		public static void ClearListeners(Button button)
		{
			global::S1API.Internal.Utils.ButtonUtils.ClearListeners(button);
		}

		public static void Enable(Button button, Text? label = null, string? text = null)
		{
			global::S1API.Internal.Utils.ButtonUtils.Enable(button, label, text);
		}

		public static void Disable(Button button, Text? label = null, string? text = null)
		{
			global::S1API.Internal.Utils.ButtonUtils.Disable(button, label, text);
		}

		public static void SetLabel(Text label, string text)
		{
			global::S1API.Internal.Utils.ButtonUtils.SetLabel(label, text);
		}

		public static void SetStyle(Button button, Text label, string text, Color bg)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Utils.ButtonUtils.SetStyle(button, label, text, bg);
		}
	}
	public static class ColorUtils
	{
		public static Color ToColor(this uint hexColor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return global::S1API.Internal.Utils.ColorUtils.ToColor(hexColor);
		}
	}
	public static class ImageUtils
	{
		public static Sprite? LoadImage(string fileName)
		{
			return global::S1API.Internal.Utils.ImageUtils.LoadImage(fileName);
		}

		public static Sprite? LoadImageRaw(byte[] data)
		{
			return global::S1API.Internal.Utils.ImageUtils.LoadImageRaw(data);
		}

		public static Sprite? TextureToSprite(Texture2D? texture, float pixelsPerUnit = 100f)
		{
			return global::S1API.Internal.Utils.ImageUtils.TextureToSprite(texture, pixelsPerUnit);
		}

		public static Sprite? LoadImageFromResource(Assembly assembly, string resourceName, float pixelsPerUnit = 100f, FilterMode filterMode = 1)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return global::S1API.Internal.Utils.ImageUtils.LoadImageFromResource(assembly, resourceName, pixelsPerUnit, filterMode);
		}
	}
	public static class RandomUtils
	{
		public static T PickOne<T>(this IList<T> list)
		{
			return global::S1API.Internal.Utils.RandomUtils.PickOne(list);
		}

		public static T PickUnique<T>(this IList<T> list, Func<T, bool> isDuplicate, int maxTries = 10)
		{
			return global::S1API.Internal.Utils.RandomUtils.PickUnique(list, isDuplicate, maxTries);
		}

		public static List<T> PickMany<T>(this IList<T> list, int count)
		{
			return global::S1API.Internal.Utils.RandomUtils.PickMany(list, count);
		}

		public static int RangeInt(int minInclusive, int maxExclusive)
		{
			return global::S1API.Internal.Utils.RandomUtils.RangeInt(minInclusive, maxExclusive);
		}
	}
	public static class ReflectionUtils
	{
		public static MethodInfo? GetMethod(Type? type, string methodName, BindingFlags bindingFlags)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetMethod(type, methodName, bindingFlags);
		}

		public static bool IsValueTuple(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.IsValueTuple(obj);
		}

		public static object[]? GetValueTupleItems(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetValueTupleItems(obj);
		}

		public static bool TrySetFieldOrProperty(object target, string memberName, object value)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TrySetFieldOrProperty(target, memberName, value);
		}

		public static object? TryGetFieldOrProperty(object target, string memberName)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(target, memberName);
		}
	}
	public static class ToggleUtils
	{
		public static void AddListener(Toggle toggle, Action<bool> listener)
		{
			global::S1API.Internal.Utils.ToggleUtils.AddListener(toggle, listener);
		}

		public static void RemoveListener(Toggle toggle, Action<bool> listener)
		{
			global::S1API.Internal.Utils.ToggleUtils.RemoveListener(toggle, listener);
		}

		public static void ClearListeners(Toggle toggle)
		{
			global::S1API.Internal.Utils.ToggleUtils.ClearListeners(toggle);
		}

		public static void SetGraphic(Toggle toggle, Graphic graphic)
		{
			global::S1API.Internal.Utils.ToggleUtils.SetGraphic(toggle, graphic);
		}

		public static Graphic? GetGraphic(Toggle toggle)
		{
			return global::S1API.Internal.Utils.ToggleUtils.GetGraphic(toggle);
		}
	}
}
namespace S1API.UI
{
	public static class CharacterCreatorManager
	{
		[CompilerGenerated]
		private sealed class <RestoreAfterClose>d__27 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = RestoreGameState();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					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 <RestoreGameState>d__28 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private PlayerCamera <camera>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (PlayerSingleton<PlayerCamera>.InstanceExists)
					{
						<camera>5__1 = PlayerSingleton<PlayerCamera>.Instance;
						PlayerCamera obj = <camera>5__1;
						CharacterCreator s1Creator = _s1Creator;
						obj.RemoveActiveUIElement(((s1Creator != null) ? ((Object)s1Creator).name : null) ?? "CharacterCreator");
						if (<camera>5__1.activeUIElementCount == 0)
						{
							<camera>5__1.StopTransformOverride(0f, true, false);
							<camera>5__1.StopFOVOverride(0f);
							<camera>5__1.SetCanLook(true);
							<camera>5__1.LockMouse();
						}
						<camera>5__1 = null;
					}
					if (PlayerSingleton<PlayerMovement>.InstanceExists)
					{
						PlayerSingleton<PlayerMovement>.Instance.CanMove = true;
					}
					if (PlayerSingleton<PlayerInventory>.InstanceExists)
					{
						PlayerSingleton<PlayerInventory>.Instance.SetInventoryEnabled(true);
					}
					if (Singleton<HUD>.InstanceExists)
					{
						((Behaviour)Singleton<HUD>.Instance.canvas).enabled = true;
					}
					return false;
				}
			}

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

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

		private static readonly Log Logger = new Log("CharacterCreatorManager");

		private static CharacterCreator _s1Creator;

		private static bool _isInitialized;

		private static bool _eventsRegistered;

		public static bool IsOpen
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				return s1Creator != null && s1Creator.IsOpen;
			}
		}

		public static BasicAvatarSettings ActiveSettings
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				if ((Object)(object)((s1Creator != null) ? s1Creator.ActiveSettings : null) == (Object)null)
				{
					return null;
				}
				return new BasicAvatarSettings(_s1Creator.ActiveSettings);
			}
		}

		public static event Action OnOpened;

		public static event Action OnClosed;

		public static event Action<BasicAvatarSettings> OnCompleted;

		public static void Open(BasicAvatarSettings initialSettings = null, bool showUI = true)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is already open");
				return;
			}
			RegisterEvents();
			if (initialSettings == null)
			{
				initialSettings = GetPlayerAvatarSettings();
			}
			if (showUI && PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
			BasicAvatarSettings val = initialSettings?.S1BasicAvatarSettings;
			_s1Creator.Open(val, showUI);
			try
			{
				CharacterCreatorManager.OnOpened?.Invoke();
			}
			catch (Exception arg)
			{
				Logger.Error($"Error in OnOpened event handler: {arg}");
			}
		}

		public static void Close()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
				return;
			}
			_s1Creator.Close();
			MelonCoroutines.Start(RestoreAfterClose());
			try
			{
				CharacterCreatorManager.OnClosed?.Invoke();
			}
			catch (Exception arg)
			{
				Logger.Error($"Error in OnClosed event handler: {arg}");
			}
		}

		public static void Complete()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
			}
			else
			{
				_s1Creator.Done();
			}
		}

		public static void SelectPreset(string presetName)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to select a preset");
			}
			else if (string.IsNullOrWhiteSpace(presetName))
			{
				Logger.Warning("Preset name cannot be null or empty");
			}
			else
			{
				_s1Creator.SelectPreset(presetName);
			}
		}

		public static string[] GetAvailablePresets()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null || _s1Creator.Presets == null)
			{
				return Array.Empty<string>();
			}
			List<string> list = new List<string>();
			for (int i = 0; i < _s1Creator.Presets.Count; i++)
			{
				BasicAvatarSettings val = _s1Creator.Presets[i];
				if ((Object)(object)val != (Object)null && !string.IsNullOrWhiteSpace(((Object)val).name))
				{
					list.Add(((Object)val).name);
				}
			}
			return list.ToArray();
		}

		public static void SetRigRotation(float normalizedValue)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to set rig rotation");
			}
			else
			{
				_s1Creator.SliderChanged(Mathf.Clamp01(normalizedValue));
			}
		}

		public static void PreRegisterAsActiveUI()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Warning("CharacterCreator singleton is not available for pre-registration");
			}
			else if (PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
		}

		private static void EnsureInitialized()
		{
			if (_isInitialized)
			{
				return;
			}
			try
			{
				_s1Creator = Singleton<CharacterCreator>.Instance;
				if ((Object)(object)_s1Creator == (Object)null)
				{
					Logger.Warning("CharacterCreator singleton not found. Make sure you're in the correct scene.");
				}
				_isInitialized = true;
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to initialize CharacterCreatorManager: {arg}");
				_isInitialized = true;
			}
		}

		private static void RegisterEvents()
		{
			if (_eventsRegistered || (Object)(object)_s1Creator == (Object)null)
			{
				return;
			}
			try
			{
				if (_s1Creator.onComplete != null)
				{
					_s1Creator.onComplete.AddListener((UnityAction<BasicAvatarSettings>)OnCreatorCompleted);
				}
				_eventsRegistered = true;
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to register CharacterCreator events: {arg}");
			}
		}

		private static void OnCreatorCompleted(BasicAvatarSettings s1Settings)
		{
			try
			{
				if ((Object)(object)s1Settings == (Object)null)
				{
					Logger.Warning("CharacterCreator completed with null settings");
					return;
				}
				BasicAvatarSettings obj = new BasicAvatarSettings(s1Settings);
				MelonCoroutines.Start(RestoreGameState());
				CharacterCreatorManager.OnCompleted?.Invoke(obj);
			}
			catch (Exception arg)
			{
				Logger.Error($"Error in OnCompleted event handler: {arg}");
			}
		}

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

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

		private static BasicAvatarSettings GetPlayerAvatarSettings()
		{
			try
			{
				Player local = Player.Local;
				if (local == null || (Object)(object)local.S1Player == (Object)null)
				{
					Logger.Warning("Local player not available");
					return null;
				}
				BasicAvatarSettings currentAvatarSettings = local.S1Player.CurrentAvatarSettings;
				if ((Object)(object)currentAvatarSettings == (Object)null)
				{
					Logger.Msg("Player has no current avatar settings, using default");
					return null;
				}
				BasicAvatarSettings settings = Object.Instantiate<BasicAvatarSettings>(currentAvatarSettings);
				return new BasicAvatarSettings(settings);
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to get player avatar settings: {arg}");
				return null;
			}
		}
	}
	public sealed class MainMenuRig
	{
		internal readonly MainMenuRig S1MainMenuRig;

		public global::S1API.Avatar.Avatar? Avatar
		{
			get
			{
				if ((Object)(object)S1MainMenuRig == (Object)null || (Object)(object)S1MainMenuRig.Avatar == (Object)null)
				{
					return null;
				}
				return new global::S1API.Avatar.Avatar(S1MainMenuRig.Avatar);
			}
		}

		internal MainMenuRig(MainMenuRig mainMenuRig)
		{
			S1MainMenuRig = mainMenuRig;
		}

		public static MainMenuRig[] FindInScene(bool includeInactive = false)
		{
			MainMenuRig[] array = Object.FindObjectsOfType<MainMenuRig>(includeInactive);
			if (array == null || array.Length == 0)
			{
				return Array.Empty<MainMenuRig>();
			}
			return (from r in array
				where (Object)(object)r != (Object)null
				select new MainMenuRig(r)).ToArray();
		}
	}
	public static class UIFactory
	{
		private static Sprite roundedSprite;

		public static GameObject Panel(string name, Transform parent, Color bgColor, Vector2? anchorMin = null, Vector2? anchorMax = null, bool fullAnchor = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			if (fullAnchor)
			{
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
			}
			else
			{
				val2.anchorMin = (Vector2)(((??)anchorMin) ?? new Vector2(0.5f, 0.5f));
				val2.anchorMax = (Vector2)(((??)anchorMax) ?? new Vector2(0.5f, 0.5f));
			}
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			return val;
		}

		public static Text Text(string name, string content, Transform parent, int fontSize = 14, TextAnchor anchor = 0, FontStyle style = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0035: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			Text val3 = val.AddComponent<Text>();
			val3.text = content;
			val3.fontSize = fontSize;
			val3.alignment = anchor;
			val3.fontStyle = style;
			val3.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			((Graphic)val3).color = Color.white;
			val3.horizontalOverflow = (HorizontalWrapMode)0;
			val3.verticalOverflow = (VerticalWrapMode)1;
			return val3;
		}

		public static RectTransform ScrollableVerticalList(string name, Transform parent, out ScrollRect scrollRect)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0084: 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_009c: 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)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0186: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			scrollRect = val.AddComponent<ScrollRect>();
			scrollRect.horizontal = false;
			GameObject val3 = new GameObject("Viewport");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			((Graphic)val3.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.05f);
			val3.AddComponent<Mask>().showMaskGraphic = false;
			scrollRect.viewport = val4;
			GameObject val5 = new GameObject("Content");
			val5.transform.SetParent(val3.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = new Vector2(0f, 1f);
			val6.anchorMax = new Vector2(1f, 1f);
			val6.pivot = new Vector2(0.5f, 1f);
			VerticalLayoutGroup val7 = val5.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val7).spacing = 10f;
			((LayoutGroup)val7).padding = new RectOffset(10, 10, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val7).childForceExpandHeight = false;
			val5.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			scrollRect.content = val6;
			return val6;
		}

		public static void FitContentHeight(RectTransform content)
		{
			ContentSizeFitter val = ((Component)content).gameObject.GetComponent<ContentSizeFitter>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
			}
			val.verticalFit = (FitMode)2;
		}

		public static (GameObject, Button, Text) RoundedButtonWithLabel(string name, string label, Transform parent, Color bgColor, float width, float height, int fontSize, Color textColor)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00af: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name + "_RoundedMask");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(width, height);
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.preferredWidth = width;
			val3.preferredHeight = height;
			Image val4 = val.AddComponent<Image>();
			val4.sprite = GetRoundedSprite();
			val4.type = (Type)1;
			((Graphic)val4).color = Color.white;
			Mask val5 = val.AddComponent<Mask>();
			val5.showMaskGraphic = true;
			GameObject val6 = new GameObject(name);
			val6.transform.SetParent(val.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = Vector2.zero;
			val7.offsetMax = Vector2.zero;
			Image val8 = val6.AddComponent<Image>();
			((Graphic)val8).color = bgColor;
			val8.sprite = GetRoundedSprite();
			val8.type = (Type)1;
			Button val9 = val6.AddComponent<Button>();
			((Selectable)val9).targetGraphic = (Graphic)(object)val8;
			GameObject val10 = new GameObject("Label");
			val10.transform.SetParent(val6.transform, false);
			RectTransform val11 = val10.AddComponent<RectTransform>();
			val11.anchorMin = Vector2.zero;
			val11.anchorMax = Vector2.one;
			val11.offsetMin = Vector2.zero;
			val11.offsetMax = Vector2.zero;
			Text val12 = val10.AddComponent<Text>();
			val12.text = label;
			val12.alignment = (TextAnchor)4;
			val12.fontSize = fontSize;
			val12.fontStyle = (FontStyle)1;
			((Graphic)val12).color = textColor;
			val12.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val9, val12);
		}

		private static Sprite GetRoundedSprite()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)roundedSprite != (Object)null)
			{
				return roundedSprite;
			}
			int num = 32;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			Color32 val3 = default(Color32);
			((Color32)(ref val3))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			float num2 = 6f;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					bool flag = ((float)j < num2 && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, num2)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, num2)) > num2) || ((float)j < num2 && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, (float)num - num2 - 1f)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, (float)num - num2 - 1f)) > num2);
					val.SetPixel(j, i, Color32.op_Implicit(flag ? val2 : val3));
				}
			}
			val.Apply();
			Vector4 val4 = default(Vector4);
			((Vector4)(ref val4))..ctor(8f, 8f, 8f, 8f);
			roundedSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val4);
			return roundedSprite;
		}

		public static GameObject ButtonRow(string name, Transform parent, float spacing = 12f, TextAnchor alignment = 4)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val3).spacing = spacing;
			((LayoutGroup)val3).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false;
			return val;
		}

		public static (GameObject, Button, Text) ButtonWithLabel(string name, string label, Transform parent, Color bgColor, float Width, float Height)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(Height, Width);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			val3.sprite = Resources.GetBuiltinResource<Sprite>("UI/Skin/UISprite.psd");
			val3.type = (Type)1;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			GameObject val5 = new GameObject("Label");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			Text val7 = val5.AddComponent<Text>();
			val7.text = label;
			val7.alignment = (TextAnchor)4;
			val7.fontSize = 16;
			val7.fontStyle = (FontStyle)1;
			((Graphic)val7).color = Color.white;
			val7.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val4, val7);
		}

		public static void SetIcon(Sprite sprite, Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Icon");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image val3 = val.AddComponent<Image>();
			val3.sprite = sprite;
			val3.preserveAspect = true;
		}

		public static void CreateTextBlock(Transform parent, string title, string subtitle, bool isCompleted)
		{
			Text(((Object)parent).name + "Title", title, parent, 16, (TextAnchor)3, (FontStyle)1);
			Text(((Object)parent).name + "Subtitle", subtitle, parent, 14, (TextAnchor)0, (FontStyle)0);
			if (isCompleted)
			{
				Text("CompletedLabel", "<color=#888888><i>Already Delivered</i></color>", parent, 12, (TextAnchor)0, (FontStyle)0);
			}
		}

		public static void CreateRowButton(GameObject go, UnityAction clickHandler, bool enabled)
		{
			Button val = go.AddComponent<Button>();
			Image component = go.GetComponent<Image>();
			((Selectable)val).targetGraphic = (Graphic)(object)component;
			((Selectable)val).interactable = enabled;
			((UnityEvent)val.onClick).AddListener(clickHandler);
		}

		public static void ClearChildren(Transform parent)
		{
			for (int num = parent.childCount - 1; num >= 0; num--)
			{
				Transform child = parent.GetChild(num);
				Object.Destroy((Object)(object)((Component)child).gameObject);
			}
		}

		public static void VerticalLayoutOnGO(GameObject go, int spacing = 10, RectOffset? padding = null)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			VerticalLayoutGroup val = go.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).padding = (RectOffset)(((object)padding) ?? ((object)new RectOffset(10, 10, 10, 10)));
		}

		public static GameObject CreateQuestRow(string name, Transform parent, out GameObject iconPanel, out GameObject textPanel)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0182: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Row_" + name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(0f, 90f);
			val.AddComponent<LayoutElement>().minHeight = 50f;
			((Shadow)val.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.2f);
			GameObject val3 = Panel("Separator", val.transform, new Color(1f, 1f, 1f, 0.05f));
			val3.GetComponent<RectTransform>().sizeDelta = new Vector2(300f, 1f);
			Image val4 = val.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.12f, 0.12f, 0.12f);
			Button val5 = val.AddComponent<Button>();
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			HorizontalLayoutGroup val6 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val6).spacing = 20f;
			((LayoutGroup)val6).padding = new RectOffset(75, 10, 10, 10);
			((LayoutGroup)val6).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false;
			LayoutElement val7 = val.AddComponent<LayoutElement>();
			val7.minHeight = 90f;
			val7.flexibleWidth = 1f;
			iconPanel = Panel("IconPanel", val.transform, new Color(0.12f, 0.12f, 0.12f));
			RectTransform component = iconPanel.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(80f, 80f);
			LayoutElement val8 = iconPanel.AddComponent<LayoutElement>();
			val8.preferredWidth = 80f;
			val8.preferredHeight = 80f;
			textPanel = Panel("TextPanel", val.transform, Color.clear);
			VerticalLayoutOnGO(textPanel, 2);
			LayoutElement val9 = textPanel.AddComponent<LayoutElement>();
			val9.minWidth = 200f;
			val9.flexibleWidth = 1f;
			return val;
		}

		public static GameObject TopBar(string name, Transform parent, string title, float topbarSize, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			GameObject val = Panel(name, parent, new Color(0.15f, 0.15f, 0.15f), (Vector2?)new Vector2(0f, topbarSize), (Vector2?)new Vector2(1f, 1f), fullAnchor: false);
			HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)val2).padding = new RectOffset(paddingLeft, paddingRight, paddingTop, paddingBottom);
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 20f;
			((LayoutGroup)val2).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = true;
			Text val3 = Text("TopBarTitle", title, val.transform, 26, (TextAnchor)3, (FontStyle)1);
			LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
			val4.minWidth = 300f;
			val4.flexibleWidth = 1f;
			return val;
		}

		public static void HorizontalLayoutOnGO(GameObject go, int spacing = 10, int padLeft = 0, int padRight = 0, int padTop = 0, int padBottom = 0, TextAnchor alignment = 4)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			HorizontalLayoutGroup val = go.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((LayoutGroup)val).padding = new RectOffset(padLeft, padRight, padTop, padBottom);
		}

		public static void SetLayoutGroupPadding(LayoutGroup layoutGroup, int left, int right, int top, int bottom)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			layoutGroup.padding = new RectOffset(left, right, top, bottom);
		}

		public static void BindAcceptButton(Button btn, Text label, string text, UnityAction callback)
		{
			label.text = text;
			((UnityEventBase)btn.onClick).RemoveAllListeners();
			((UnityEvent)btn.onClick).AddListener(callback);
		}
	}
}
namespace S1API.Storage
{
	public sealed class StorageEntity
	{
		private static readonly Log Logger = new Log("StorageEntity");

		internal readonly StorageEntity S1StorageEntity;

		internal readonly PlaceableStorageEntity S1PlaceableStorageEntity;

		public string Name
		{
			get
			{
				return S1StorageEntity.StorageEntityName;
			}
			set
			{
				S1StorageEntity.StorageEntityName = value;
			}
		}

		public int SlotCount
		{
			get
			{
				return S1StorageEntity.SlotCount;
			}
			set
			{
				if (value < 0)
				{
					Logger.Warning("Cannot set SlotCount to negative value");
					return;
				}
				if (value > MaxSlots)
				{
					Logger.Warning($"Cannot set SlotCount to {value}, maximum is {MaxSlots}");
					return;
				}
				int count = S1StorageEntity.ItemSlots.Count;
				if (value > count)
				{
					AddSlots(value - count);
				}
				else if (value < count)
				{
					RemoveSlots(count - value);
				}
			}
		}

		public int MaxSlots { get; set; } = 20;


		public int DisplayRowCount
		{
			get
			{
				return S1StorageEntity.DisplayRowCount;
			}
			set
			{
				S1StorageEntity.DisplayRowCount = value;
			}
		}

		public bool SlotsAreFilterable => S1StorageEntity.SlotsAreFilterable;

		public ItemInstance ItemInstance
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				if (((s1PlaceableStorageEntity != null) ? ((BuildableItem)s1PlaceableStorageEntity).ItemInstance : null) == null)
				{
					return null;
				}
				return new ItemInstance(((BuildableItem)S1PlaceableStorageEntity).ItemInstance);
			}
		}

		public string ItemId
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object result;
				if (s1PlaceableStorageEntity == null)
				{
					result = null;
				}
				else
				{
					ItemInstance itemInstance = ((BuildableItem)s1PlaceableStorageEntity).ItemInstance;
					result = ((itemInstance == null) ? null : itemInstance.Definition?.ID);
				}
				return (string)result;
			}
		}

		public bool IsPlaceable => (Object)(object)S1PlaceableStorageEntity != (Object)null;

		public string CustomName
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object result;
				if (s1PlaceableStorageEntity == null)
				{
					result = null;
				}
				else
				{
					EntityConfiguration configuration = s1PlaceableStorageEntity.Configuration;
					if (configuration == null)
					{
						result = null;
					}
					else
					{
						StringField name = configuration.Name;
						result = ((name != null) ? name.Value : null);
					}
				}
				return (string)result;
			}
			set
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object obj;
				if (s1PlaceableStorageEntity == null)
				{
					obj = null;
				}
				else
				{
					EntityConfiguration configuration = s1PlaceableStorageEntity.Configuration;
					obj = ((configuration != null) ? configuration.Name : null);
				}
				if (obj != null && !string.IsNullOrEmpty(value))
				{
					S1PlaceableStorageEntity.Configuration.Name.SetValue(value, true);
				}
			}
		}

		public bool HasCustomName => !string.IsNullOrEmpty(CustomName);

		internal StorageEntity(StorageEntity storageEntity, PlaceableStorageEntity placeableStorage = null)
		{
			S1StorageEntity = storageEntity ?? throw new ArgumentNullException("storageEntity");
			S1PlaceableStorageEntity = placeableStorage;
		}

		public void SyncCustomNameToDisplayName()
		{
			if (HasCustomName)
			{
				Name = CustomName;
			}
		}

		public bool AddSlots(int count)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			if (count <= 0)
			{
				Logger.Warning("AddSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			int num = count2 + count;
			if (num > MaxSlots)
			{
				Logger.Warning($"Cannot add {count} slots, would exceed MaxSlots ({MaxSlots})");
				return false;
			}
			try
			{
				for (int i = 0; i < count; i++)
				{
					ItemSlot val = new ItemSlot(S1StorageEntity.SlotsAreFilterable);
					val.SetSlotOwner((IItemSlotOwner)(object)S1StorageEntity);
				}
				S1StorageEntity.SlotCount = num;
				if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
				{
					int count3 = S1StorageEntity.ItemSlots.Count;
					for (int j = count2; j < count3; j++)
					{
						ItemSlot item = S1StorageEntity.ItemSlots[j];
						S1PlaceableStorageEntity.InputSlots.Add(item);
						S1PlaceableStorageEntity.OutputSlots.Add(item);
					}
				}
				if (num > 6 && DisplayRowCount < 2)
				{
					DisplayRowCount = 2;
				}
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to add slots: " + ex.Message);
				return false;
			}
		}

		public bool RemoveSlots(int count)
		{
			if (count <= 0)
			{
				Logger.Warning("RemoveSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			if (count > count2)
			{
				Logger.Warning($"Cannot remove {count} slots, only {count2} exist");
				return false;
			}
			try
			{
				for (int i = count2 - count; i < count2; i++)
				{
					if (S1StorageEntity.ItemSlots[i].ItemInstance != null)
					{
						Logger.Warning($"Cannot remove slot {i}, it contains an item");
						return false;
					}
				}
				for (int j = 0; j < count; j++)
				{
					int index = S1StorageEntity.ItemSlots.Count - 1;
					ItemSlot item = S1StorageEntity.ItemSlots[index];
					if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
					{
						S1PlaceableStorageEntity.InputSlots.Remove(item);
						S1PlaceableStorageEntity.OutputSlots.Remove(item);
					}
					S1StorageEntity.ItemSlots.RemoveAt(index);
				}
				S1StorageEntity.SlotCount = count2 - count;
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to remove slots: " + ex.Message);
				return false;
			}
		}

		public bool SetSlotCount(int targetSlotCount)
		{
			if (targetSlotCount < 0)
			{
				Logger.Warning("Cannot set negative slot count");
				return false;
			}
			int count = S1StorageEntity.ItemSlots.Count;
			int num = targetSlotCount - count;
			if (num > 0)
			{
				return AddSlots(num);
			}
			if (num < 0)
			{
				return RemoveSlots(-num);
			}
			return true;
		}

		public int GetEmptySlotCount()
		{
			int num = 0;
			foreach (ItemSlot itemSlot in S1StorageEntity.ItemSlots)
			{
				if (itemSlot.ItemInstance == null)
				{
					num++;
				}
			}
			return num;
		}

		public int GetOccupiedSlotCount()
		{
			return S1StorageEntity.ItemSlots.Count - GetEmptySlotCount();
		}

		public bool HasItems()
		{
			foreach (ItemSlot itemSlot in S1StorageEntity.ItemSlots)
			{
				if (itemSlot.ItemInstance != null)
				{
					return true;
				}
			}
			return false;
		}

		public bool IsEmpty()
		{
			return !HasItems();
		}
	}
	public class StorageEventArgs
	{
		public StorageEntity Storage { get; internal set; }

		public string ItemId => Storage?.ItemId;

		internal StorageEventArgs(StorageEntity storage)
		{
			Storage = storage;
		}
	}
	public class StorageLoadingEventArgs : StorageEventArgs
	{
		public int ItemCountBeingLoaded { get; internal set; }

		public int CurrentSlotCount => base.Storage?.SlotCount ?? 0;

		public bool NeedsMoreSlots => ItemCountBeingLoaded > CurrentSlotCount;

		public int AdditionalSlotsNeeded => Math.Max(0, ItemCountBeingLoaded - CurrentSlotCount);

		internal StorageLoadingEventArgs(StorageEntity storage, int itemCount)
			: base(storage)
		{
			ItemCountBeingLoaded = itemCount;
		}
	}
	public static class StorageEvents
	{
		private static readonly Log Logger = new Log("StorageEvents");

		public static event Action<StorageEventArgs> OnStorageCreated;

		public static event Action<StorageLoadingEventArgs> OnStorageLoading;

		public static event Action<StorageEventArgs> OnStorageOpening;

		internal static void RaiseStorageCreated(StorageEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageCreated?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error("Exception in OnStorageCreated handler for storage '" + args.ItemId + "': " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		internal static void RaiseStorageLoading(StorageLoadingEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageLoading?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error("Exception in OnStorageLoading handler for storage '" + args.ItemId + "': " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		internal static void RaiseStorageOpening(StorageEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageOpening?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error("Exception in OnStorageOpening handler for storage '" + args.ItemId + "': " + ex.Message + "\n" + ex.StackTrace);
			}
		}
	}
}
namespace S1API.Storages
{
	public enum StorageAccessSettings
	{
		Closed,
		SinglePlayerOnly,
		Full
	}
	public class StorageInstance
	{
		internal readonly StorageEntity S1Storage;

		public string Name => S1Storage.StorageEntityName;

		public string Subtitle => S1Storage.StorageEntitySubtitle;

		public int SlotCount => S1Storage.SlotCount;

		public int ItemCount => S1Storage.ItemCount;

		public StorageAccessSettings AccessSettings
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected I4, but got Unknown
				return (StorageAccessSettings)S1Storage.AccessSettings;
			}
			set
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				S1Storage.AccessSettings = (EAccessSettings)value;
			}
		}

		public bool IsOpened => S1Storage.IsOpened;

		public ItemSlotInstance[] Slots => (from itemSlot in S1Storage.ItemSlots.ToArray()
			select new ItemSlotInstance(itemSlot)).ToArray();

		public event Action OnOpened
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened = (Action)Delegate.Combine(s1Storage.onOpened, h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened = (Action)Delegate.Remove(s1Storage.onOpened, h);
				});
			}
		}

		public event Action OnClosed
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed = (Action)Delegate.Combine(s1Storage.onClosed, h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed = (Action)Delegate.Remove(s1Storage.onClosed, h);
				});
			}
		}

		public event Action OnContentsChanged
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged = (Action)Delegate.Combine(s1Storage.onContentsChanged, h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged = (Action)Delegate.Remove(s1Storage.onContentsChanged, h);
				});
			}
		}

		internal StorageInstance(StorageEntity storage)
		{
			S1Storage = storage;
		}

		public static StorageInstance? FromGameObject(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				Debug.LogWarning((object)"[StorageInstance] FromGameObject called with null GameObject");
				return null;
			}
			Debug.Log((object)("[StorageInstance] Searching for StorageEntity on GameObject '" + ((Object)gameObject).name + "'"));
			StorageEntity component = gameObject.GetComponent<StorageEntity>();
			if ((Object)(object)component != (Object)null)
			{
				Debug.Log((object)("[StorageInstance] Found StorageEntity directly on '" + ((Object)gameObject).name + "'"));
				return new StorageInstance(component);
			}
			Debug.Log((object)("[StorageInstance] StorageEntity not found directly, searching parent hierarchy of '" + ((Object)gameObject).name + "'"));
			component = gameObject.GetComponentInParent<StorageEntity>();
			if ((Object)(object)component != (Object)null)
			{
				Debug.Log((object)("[StorageInstance] Found StorageEntity in parent hierarchy of '" + ((Object)gameObject).name + "' on object '" + ((Object)((Component)component).gameObject).name + "'"));
				return new StorageInstance(component);
			}
			Debug.LogWarning((object)("[StorageInstance] No StorageEntity found on '" + ((Object)gameObject).name + "' or its parents"));
			return null;
		}

		public static StorageInstance? FromGameObjectInChildren(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				Debug.LogWarning((object)"[StorageInstance] FromGameObjectInChildren called with null GameObject");
				return null;
			}
			Debug.Log((object)("[StorageInstance] Searching for StorageEntity in children of '" + ((Object)gameObject).name + "'"));
			StorageEntity componentInChildren = gameObject.GetComponentInChildren<StorageEntity>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Debug.LogWarning((object)("[StorageInstance] No StorageEntity found in children of '" + ((Object)gameObject).name + "'"));
				return null;
			}
			Debug.Log((object)("[StorageInstance] Found StorageEntity in children of '" + ((Object)gameObject).name + "' on object '" + ((Object)((Component)componentInChildren).gameObject).name + "'"));
			return new StorageInstance(componentInChildren);
		}

		public ItemInstance[] GetItems()
		{
			List<ItemInstance> allItems = S1Storage.GetAllItems();
			if (allItems == null || allItems.Count == 0)
			{
				return Array.Empty<ItemInstance>();
			}
			ItemInstance[] array = new ItemInstance[allItems.Count];
			for (int i = 0; i < allItems.Count; i++)
			{
				array[i] = new ItemInstance(allItems[i]);
			}
			return array;
		}

		public Dictionary<ItemInstance, int> GetContentsDictionary()
		{
			Dictionary<StorableItemInstance, int> contentsDictionary = S1Storage.GetContentsDictionary();
			Dictionary<ItemInstance, int> dictionary = new Dictionary<ItemInstance, int>();
			foreach (KeyValuePair<StorableItemInstance, int> item in contentsDictionary)
			{
				if (item.Key != null)
				{
					dictionary[new ItemInstance((ItemInstance)(object)item.Key)] = item.Value;
				}
			}
			return dictionary;
		}

		public bool CanItemFit(ItemInstance itemInstance, int quantity = 1)
		{
			return S1Storage.CanItemFit(itemInstance.S1ItemInstance, quantity);
		}

		public void AddItem(ItemInstance itemInstance)
		{
			S1Storage.InsertItem(itemInstance.S1ItemInstance, true);
		}

		public int RemoveItem(ItemInstance itemInstance)
		{
			if (itemInstance == null)
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance == itemInstance.S1ItemInstance)
				{
					int quantity = val.Quantity;
					val.ClearStoredInstance(false);
					num += quantity;
					break;
				}
			}
			return num;
		}

		public int TryRemoveQuantity(string itemDefinitionId, int quantity)
		{
			if (string.IsNullOrEmpty(itemDefinitionId) || quantity <= 0)
			{
				return 0;
			}
			int num = quantity;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				if (num <= 0)
				{
					break;
				}
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					int quantity2 = val.Quantity;
					int num2 = Math.Min(num, quantity2);
					num -= num2;
					if (num2 >= quantity2)
					{
						val.ClearStoredInstance(false);
					}
					else
					{
						val.ChangeQuantity(-num2, false);
					}
				}
			}
			return quantity - num;
		}

		public int RemoveAllOfDefinition(string itemDefinitionId)
		{
			if (string.IsNullOrEmpty(itemDefinitionId))
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					num += val.Quantity;
					val.ClearStoredInstance(false);
				}
			}
			return num;
		}
	}
	public static class StorageManager
	{
		public static StorageInstance[] GetAll()
		{
			List<StorageInstance> list = new List<StorageInstance>();
			if (WorldStorageEntity.All == null)
			{
				return list.ToArray();
			}
			foreach (WorldStorageEntity item in WorldStorageEntity.All)
			{
				if ((Object)(object)item != (Object)null)
				{
					list.Add(new StorageInstance((StorageEntity)(object)item));
				}
			}
			return list.ToArray();
		}

		public static StorageInstance? FindByName(string name)
		{
			if (string.IsNullOrEmpty(name) || WorldStorageEntity.All == null)
			{
				return null;
			}
			foreach (WorldStorageEntity item in WorldStorageEntity.All)
			{
				if ((Object)(object)item != (Object)null && ((StorageEntity)item).StorageEntityName == name)
				{
					return new StorageInstance((StorageEntity)(object)item);
				}
			}
			return null;
		}

		public static StorageInstance[] FindByPredicate(Func<StorageInstance, bool> predicate)
		{
			if (predicate == null || WorldStorageEntity.All == null)
			{
				return Array.Empty<StorageInstance>();
			}
			List<StorageInstance> list = new List<StorageInstance>();
			foreach (WorldStorageEntity item in WorldStorageEntity.All)
			{
				if ((Object)(object)item != (Object)null)
				{
					StorageInstance storageInstance = new StorageInstance((StorageEntity)(object)item);
					if (predicate(storageInstance))
					{
						list.Add(storageInstance);
					}
				}
			}
			return list.ToArray();
		}
	}
}
namespace S1API.Shops
{
	public sealed class Shop
	{
		internal ShopInterface S1ShopInterface { get; }

		public string Name => S1ShopInterface.ShopName;

		internal Shop(ShopInterface shopInterface)
		{
			S1ShopInterface = shopInterface;
		}

		public bool HasItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			foreach (ShopListing listing in S1ShopInterface.Listings)
			{
				if (((ItemDefinition)(listing?.Item?)).ID == itemId)
				{
					return true;
				}
			}
			return false;
		}

		public bool SellsCategory(ItemCategory category)
		{
			//IL_0002: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			EItemCategory val = (EItemCategory)category;
			foreach (ShopListing listing in S1ShopInterface.Listings)
			{
				if ((Object)(object)listing?.Item != (Object)null && ((ItemDefinition)listing.Item).Category == val)
				{
					return true;
				}
			}
			return false;
		}

		public string[] GetItemIds()
		{
			List<string> list = new List<string>();
			foreach (ShopListing listing in S1ShopInterface.Listings)
			{
				if ((Object)(object)listing?.Item != (Object)null)
				{
					list.Add(((ItemDefinition)listing.Item).ID);
				}
			}
			return list.ToArray();
		}

		public bool AddItem(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return false;
			}
			if (HasItem(item.ID))
			{
				return false;
			}
			return ShopIntegration.AddItemToShop(this, item, customPrice);
		}

		public bool RemoveItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			return ShopIntegration.RemoveItemFromShop(this, itemId);
		}
	}
	public static class ShopManager
	{
		private static readonly Log Logger = new Log("ShopManager");

		private static readonly List<Shop> _cachedShops = new List<Shop>();

		private static bool _cacheValid = false;

		public static Shop[] GetAllShops()
		{
			RefreshCacheIfNeeded();
			return _cachedShops.ToArray();
		}

		public static Shop GetShopByName(string shopName)
		{
			string shopName2 = shopName;
			if (string.IsNullOrEmpty(shopName2))
			{
				return null;
			}
			return GetAllShops().FirstOrDefault((Shop s) => string.Equals(s.Name, shopName2, StringComparison.OrdinalIgnoreCase));
		}

		public static Shop[] FindShopsByCategory(ItemCategory category)
		{
			return (from s in GetAllShops()
				where s.SellsCategory(category)
				select s).ToArray();
		}

		public static Shop[] FindShopsByItem(string itemId)
		{
			string itemId2 = itemId;
			if (string.IsNullOrEmpty(itemId2))
			{
				return Array.Empty<Shop>();
			}
			return (from s in GetAllShops()
				where s.HasItem(itemId2)
				select s).ToArray();
		}

		public static int AddToCompatibleShops(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return 0;
			}
			Shop[] array = FindShopsByCategory(item.Category);
			int num = 0;
			Shop[] array2 = array;
			foreach (Shop shop in array2)
			{
				if (shop.AddItem(item, customPrice))
				{
					num++;
				}
			}
			if (num > 0)
			{
				Logger.Msg($"Added item '{item.Name}' to {num} compatible shop(s)");
			}
			return num;
		}

		public static int AddToShops(ItemDefinition item, params string[] shopNames)
		{
			return AddToShops(item, null, shopNames);
		}

		public static int AddToShops(ItemDefinition item, float? customPrice, params string[] shopNames)
		{
			if (item == null || shopNames == null || shopNames.Length == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (string shopName in shopNames)
			{
				Shop shopByName = GetShopByName(shopName);
				if (shopByName != null && shopByName.AddItem(item, customPrice))
				{
					num++;
				}
			}
			return num;
		}

		public static int RefreshItemIcon(ItemDefinition item)
		{
			if (item == null)
			{
				return 0;
			}
			return ShopIntegration.RefreshItemIconInShops(item);
		}

		public static int RefreshItemIcon(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return 0;
			}
			Shop[] array = FindShopsByItem(itemId);
			if (array.Length == 0)
			{
				return 0;
			}
			Shop[] array2 = array;
			foreach (Shop shop in array2)
			{
				foreach (ShopListing listing in shop.S1ShopInterface.Listings)
				{
					if (((ItemDefinition)(listing?.Item?)).ID == itemId)
					{
						ItemDefinition itemDefinition = ItemManager.GetItemDefinition(itemId);
						if (itemDefinition != null)
						{
							return RefreshItemIcon(itemDefinition);
						}
						return 0;
					}
				}
			}
			return 0;
		}

		internal static void InvalidateCache()
		{
			_cacheValid = false;
			_cachedShops.Clear();
		}

		private static void RefreshCacheIfNeeded()
		{
			if (_cacheValid)
			{
				return;
			}
			_cachedShops.Clear();
			try
			{
				List<ShopInterface> allShops = ShopInterface.AllShops;
				if (allShops == null)
				{
					_cacheValid = true;
					return;
				}
				foreach (ShopInterface item in allShops)
				{
					if ((Object)(object)item != (Object)null)
					{
						_cachedShops.Add(new Shop(item));
					}
				}
				_cacheValid = true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to refresh shop cache: " + ex.Message);
				_cacheValid = false;
			}
		}
	}
}
namespace S1API.Saveables
{
	internal static class SaveableAutoRegistry
	{
		[CompilerGenerated]
		private sealed class <GetOrCreateInstances>d__7 : IEnumerable<Saveable>, IEnumerable, IEnumerator<Saveable>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Saveable <>2__current;

			private int <>l__initialThreadId;

			private List<Type>.Enumerator <>s__1;

			private Type <saveableType>5__2;

			private Saveable <instance>5__3;

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

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

			[DebuggerHidden]
			public <GetOrCreateInstances>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = default(List<Type>.Enumerator);
				<saveableType>5__2 = null;
				<instance>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00eb;
					}
					<>1__state = -1;
					<>s__1 = _discoveredSaveableTypes.GetEnumerator();
					<>1__state = -3;
					goto IL_00fa;
					IL_00eb:
					<instance>5__3 = null;
					<saveableType>5__2 = null;
					goto IL_00fa;
					IL_00fa:
					if (<>s__1.MoveNext())
					{
						<saveableType>5__2 = <>s__1.Current;
						if (!_instances.TryGetValue(<saveableType>5__2, out <instance>5__3))
						{
							try
							{
								<instance>5__3 = (Saveable)Activator.CreateInstance(<saveableType>5__2, nonPublic: true);
								if (<instance>5__3 != null)
								{
									_instances[<saveableType>5__2] = <instance>5__3;
								}
							}
							catch
							{
							}
						}
						if (<instance>5__3 != null)
						{
							<>2__current = <instance>5__3;
							<>1__state = 1;
							return true;
						}
						goto IL_00eb;
					}
					<>m__Finally1();
					<>s__1 = default(List<Type>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<Saveable> IEnumerable<Saveable>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetOrCreateInstances>d__7(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Saveable>)this).GetEnumerator();
			}
		}

		private static readonly List<Type> _discoveredSaveableTypes = new List<Type>();

		private static readonly Dictionary<Type, Saveable> _instances = new Dictionary<Type, Saveable>();

		private static bool _discoveryPerformed = false;

		private static readonly object _lock = new object();

		public static IEnumerable<Saveable> GetRegisteredSaveables()
		{
			lock (_lock)
			{
				if (!_discoveryPerformed)
				{
					DiscoverSaveableTypes();
					_discoveryPerformed = true;
				}
				return GetOrCreateInstances();
			}
		}

		private static void DiscoverSaveableTypes()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					try
					{
						if (assembly == executingAssembly)
						{
							continue;
						}
						string? fullName = assembly.FullName;
						if (fullName != null && fullName.StartsWith("System"))
						{
							continue;
						}
						string? fullName2 = assembly.FullName;
						if (fullName2 != null && fullName2.StartsWith("Unity"))
						{
							continue;
						}
						string? fullName3 = assembly.FullName;
						if (fullName3 != null && fullName3.StartsWith("mscorlib"))
						{
							continue;
						}
						string? fullName4 = assembly.FullName;
						if (fullName4 != null && fullName4.StartsWith("netstandard"))
						{
							continue;
						}
						string? fullName5 = assembly.FullName;
						if (fullName5 != null && fullName5.StartsWith("Microsoft"))
						{
							continue;
						}
						string? fullName6 = assembly.FullName;
						if (fullName6 != null && fullName6.StartsWith("Il2Cpp"))
						{
							continue;
						}
						string? fullName7 = assembly.FullName;
						if (fullName7 != null && fullName7.StartsWith("MelonLoader"))
						{
							continue;
						}
						string? fullName8 = assembly.FullName;
						if ((fullName8 != null && fullName8.StartsWith("0Harmony")) || assembly.IsDynamic)
						{
							continue;
						}
						Type[] array;
						try
						{
							array = assembly.GetTypes();
						}
						catch (ReflectionTypeLoadException ex)
						{
							array = ex.Types.Where((Type t) => t != null).ToArray();
						}
						catch
						{
							goto end_IL_0020;
						}
						Type[] array2 = array;
						foreach (Type type in array2)
						{
							try
							{
								if (!(type == null) && !type.IsAbstract && !type.IsInterface && !type.IsGenericTypeDefinition && IsDirectSaveableInheritor(type))
								{
									_discoveredSaveableTypes.Add(type);
								}
							}
							catch
							{
							}
						}
						end_IL_0020:;
					}
					catch
					{
					}
				}
			}
			catch (Exception ex2)
			{
				try
				{
					MelonLogger.Warning("[S1API] Error during saveable type discovery: " + ex2.Message);
				}
				catch
				{
				}
			}
		}

		private static bool IsDirectSaveableInheritor(Type type)
		{
			if (!typeof(Saveable).IsAssignableFrom(type))
			{
				return false;
			}
			if (type.IsAbstract || type.IsInterface)
			{
				return false;
			}
			Type baseType = type.BaseType;
			return baseType == typeof(Saveable);
		}

		[IteratorStateMachine(typeof(<GetOrCreateInstances>d__7))]
		private static IEnumerable<Saveable> GetOrCreateInstances()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetOrCreateInstances>d__7(-2);
		}

		internal static void ClearCache()
		{
			lock (_lock)
			{
				_discoveredSaveableTypes.Clear();
				_instances.Clear();
				_discoveryPerformed = false;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class SaveableField : Attribute
	{
		internal string SaveName { get; }

		public SaveableField(string saveName)
		{
			SaveName = saveName;
		}
	}
	public enum SaveableLoadOrder
	{
		BeforeBaseGame,
		AfterBaseGame
	}
}
namespace S1API.Rendering
{
	public static class AccessoryFactory
	{
		private static readonly Log Logger = new Log("AccessoryFactory");

		internal static readonly Dictionary<string, Dictionary<string, Texture2D>> _accessoryTextureRegistry = new Dictionary<string, Dictionary<string, Texture2D>>();

		public static GameObject CloneAccessoryWithCustomTextures(string sourceResourcePath, string newName, Dictionary<string, Texture2D> textureReplacements = null, Color? colorTint = null, string targetResourcePath = null)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = Resources.Load<GameObject>(sourceResourcePath);
				if ((Object)(object)val == (Object)null)
				{
					Logger.Error("Failed to load source accessory at path: " + sourceResourcePath);
					return null;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val);
				((Object)val2).name = newName;
				Object.DontDestroyOnLoad((Object)(object)val2);
				val2.SetActive(false);
				Accessory component = val2.GetComponent<Accessory>();
				if ((Object)(object)component != (Object)null)
				{
					component.AssetPath = targetResourcePath ?? sourceResourcePath;
					component.Name = newName;
				}
				if (textureReplacements != null && textureReplacements.Count > 0)
				{
					ApplyTexturesToAccessory(val2, textureReplacements);
				}
				if (colorTint.HasValue && (Object)(object)component != (Object)null)
				{
					component.ApplyColor(colorTint.Value);
				}
				val2.SetActive(true);
				return val2;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to clone accessory '" + sourceResourcePath + "': " + ex.Message);
				Logger.Error(ex.StackTrace);
				return null;
			}
		}

		private static void ApplyTexturesToAccessory(GameObject accessory, Dictionary<string, Texture2D> textureReplacements)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Renderer[] componentsInChildren = accessory.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Material[] materials = val.materials;
				for (int j = 0; j < materials.Length; j++)
				{
					Material val2 = new Material(materials[j]);
					foreach (KeyValuePair<string, Texture2D> textureReplacement in textureReplacements)
					{
						if (val2.HasProperty(textureReplacement.Key))
						{
							val2.SetTexture(textureReplacement.Key, (Texture)(object)textureReplacement.Value);
						}
					}
					materials[j] = val2;
				}
				val.materials = materials;
			}
		}

		public static bool RegisterAccessory(string resourcePath, GameObject accessory)
		{
			if ((Object)(object)accessory == (Object)null)
			{
				Logger.Error("Cannot register null accessory");
				return false;
			}
			Accessory component = accessory.GetComponent<Accessory>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.Warning("GameObject '" + ((Object)accessory).name + "' does not have an Accessory component. It may not work correctly as clothing.");
			}
			return RuntimeResourceRegistry.RegisterGameObject(resourcePath, accessory);
		}

		public static bool CreateAndRegisterAccessory(string sourceResourcePath, string targetResourcePath, string newName, Dictionary<string, Texture2D> textureReplacements = null, Color? colorTint = null)
		{
			GameObject val = CloneAccessoryWithCustomTextures(sourceResourcePath, newName, textureReplacements, colorTint, targetResourcePath);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (textureReplacements != null && textureReplacements.Count > 0)
			{
				_accessoryTextureRegistry[targetResourcePath] = textureReplacements;
			}
			return RegisterAccessory(targetResourcePath, val);
		}

		internal static Dictionary<string, Texture2D> GetTextureReplacements(string resourcePath)
		{
			_accessoryTextureRegistry.TryGetValue(resourcePath, out Dictionary<string, Texture2D> value);
			return value;
		}
	}
	public static class IconFactory
	{
		private class SkinnedMeshRendererState
		{
			public SkinnedMeshRenderer SkinnedRenderer { get; set; }

			public MeshFilter? MeshFilter { get; set; }

			public MeshRenderer? MeshRenderer { get; set; }

			public Mesh? BakedMesh { get; set; }

			public SkinnedMeshRendererState(SkinnedMeshRenderer skinnedRenderer)
			{
				SkinnedRenderer = skinnedRenderer;
			}
		}

		private class AccessoryIconRequest
		{
			public string AccessoryPath { get; set; }

			public Color AccessoryColor { get; set; }

			public int IconSize { get; set; }

			public Action<Texture2D> Callback { get; set; }
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass19_0
		{
			public Texture2D capturedTexture;

			public AccessoryIconRequest next;

			public bool completed;

			internal void <ProcessAccessoryIconQueue>b__0(Texture2D generatedMugshot)
			{
				try
				{
					if ((Object)(object)generatedMugshot != (Object)null)
					{
						generatedMugshot.Apply();
						capturedTexture = generatedMugshot;
						Logger.Msg($"Generated accessory icon for '{next.AccessoryPath}': {((Texture)generatedMugshot).width}x{((Texture)generatedMugshot).height}");
					}
					else
					{
						Logger.Error("Failed to generate accessory icon for '" + next.AccessoryPath + "': texture is null");
					}
				}
				catch (Exception ex)
				{
					Logger.Error("Failed to finalize accessory icon: " + ex.Message);
				}
				finally
				{
					completed = true;
				}
			}
		}

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

			private object <>2__current;

			private <>c__DisplayClass19_0 <>8__1;

			private MugshotGenerator <generator>5__2;

			private Avatar <mugshotRig>5__3;

			private IconGenerator <iconGenerator>5__4;

			private Tran

Plugins/S1APILoader.MelonLoader.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using MelonLoader;
using Microsoft.CodeAnalysis;
using S1APILoader;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::S1APILoader.S1APILoader), "S1APILoader", "2.4.4", "KaBooMa", null)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("S1APILoader")]
[assembly: AssemblyConfiguration("MonoMelon")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b99ac756c0cc4be3aad62571f3f21a58d1301be9")]
[assembly: AssemblyProduct("S1APILoader")]
[assembly: AssemblyTitle("S1APILoader")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace S1APILoader
{
	public class S1APILoader : MelonPlugin
	{
		private const string BuildFolderName = "S1API";

		public override void OnPreModsLoaded()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (directoryName == null)
			{
				throw new Exception("Failed to identify plugins folder.");
			}
			string fullPath = Path.GetFullPath(Path.Combine(directoryName, "../Mods"));
			string folder = Path.Combine(directoryName, "S1API");
			string text = (MelonUtils.IsGameIl2Cpp() ? "Il2Cpp" : "Mono");
			string build = ((!MelonUtils.IsGameIl2Cpp()) ? "Il2Cpp" : "Mono");
			MelonLogger.Msg("Loading S1API for " + text + "...");
			NormalizeBuild(fullPath, text, shouldBeEnabled: true, "S1API.{0}.MelonLoader.dll");
			NormalizeBuild(fullPath, build, shouldBeEnabled: false, "S1API.{0}.MelonLoader.dll");
			NormalizeBuild(folder, text, shouldBeEnabled: true, "S1API.{0}.dll");
			NormalizeBuild(folder, build, shouldBeEnabled: false, "S1API.{0}.dll");
			MelonLogger.Msg("Successfully loaded S1API for " + text + "!");
		}

		private static void NormalizeBuild(string folder, string build, bool shouldBeEnabled, string fileNamePattern)
		{
			if (!Directory.Exists(folder))
			{
				return;
			}
			string path = string.Format(fileNamePattern, build);
			string text = Path.Combine(folder, path);
			string text2 = text + ".disabled";
			bool flag = File.Exists(text);
			bool flag2 = File.Exists(text2);
			if (!flag && !flag2)
			{
				return;
			}
			if (shouldBeEnabled)
			{
				if (flag && !flag2)
				{
					return;
				}
				string text3 = null;
				if (flag2)
				{
					text3 = text2;
				}
				if (flag)
				{
					text3 = ChooseNewest(text3, text);
				}
				if (text3 != null)
				{
					if (StringComparer.OrdinalIgnoreCase.Equals(text3, text2))
					{
						SafeDelete(text);
						SafeMoveReplace(text2, text);
					}
					else if (flag2)
					{
						SafeDelete(text2);
					}
				}
			}
			else
			{
				if ((!flag && flag2) || !flag)
				{
					return;
				}
				SafeDelete(text2);
				if (!SafeMoveReplace(text, text2) || File.Exists(text))
				{
					MelonLogger.Warning("Failed to disable '" + text + "'. File may be locked or in use.");
					if (File.Exists(text))
					{
						TryCopyAndDelete(text, text2);
					}
				}
			}
		}

		private static string ChooseNewest(string? currentBestPath, string candidatePath)
		{
			if (currentBestPath == null)
			{
				return candidatePath;
			}
			Version version = TryGetAssemblyVersion(currentBestPath);
			Version version2 = TryGetAssemblyVersion(candidatePath);
			if (version != null && version2 != null)
			{
				return (version2 > version) ? candidatePath : currentBestPath;
			}
			DateTime safeWriteTimeUtc = GetSafeWriteTimeUtc(currentBestPath);
			DateTime safeWriteTimeUtc2 = GetSafeWriteTimeUtc(candidatePath);
			return (safeWriteTimeUtc2 > safeWriteTimeUtc) ? candidatePath : currentBestPath;
		}

		private static Version? TryGetAssemblyVersion(string path)
		{
			try
			{
				return AssemblyName.GetAssemblyName(path).Version;
			}
			catch
			{
				return null;
			}
		}

		private static DateTime GetSafeWriteTimeUtc(string path)
		{
			try
			{
				return File.GetLastWriteTimeUtc(path);
			}
			catch
			{
				return DateTime.MinValue;
			}
		}

		private static bool SafeMoveReplace(string sourcePath, string destinationPath)
		{
			try
			{
				if (File.Exists(destinationPath))
				{
					File.Delete(destinationPath);
				}
				File.Move(sourcePath, destinationPath);
				return true;
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Failed to move '" + sourcePath + "' to '" + destinationPath + "': " + ex.Message);
				return false;
			}
		}

		private static void TryCopyAndDelete(string sourcePath, string destinationPath)
		{
			try
			{
				if (File.Exists(destinationPath))
				{
					File.Delete(destinationPath);
				}
				File.Copy(sourcePath, destinationPath, overwrite: true);
				try
				{
					File.Delete(sourcePath);
				}
				catch
				{
					MelonLogger.Warning("Copied '" + sourcePath + "' to '" + destinationPath + "' but could not delete source. You may need to manually delete it.");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Failed to copy '" + sourcePath + "' to '" + destinationPath + "': " + ex.Message);
			}
		}

		private static void SafeDelete(string path)
		{
			try
			{
				if (File.Exists(path))
				{
					File.Delete(path);
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Failed to delete '" + path + "': " + ex.Message);
			}
		}
	}
}