Decompiled source of S1API Forked v3.2.3

Mods/S1API.Mono.MelonLoader.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Managing.Server;
using FishNet.Managing.Transporting;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using S1API;
using S1API.AssetBundles;
using S1API.Avatar;
using S1API.Building;
using S1API.Casino;
using S1API.Conditions;
using S1API.Console;
using S1API.Cutscenes;
using S1API.DeadDrops;
using S1API.Deliveries;
using S1API.Dialogues;
using S1API.Economy;
using S1API.Entities;
using S1API.Entities.Actions;
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.Equippables;
using S1API.Entities.Impostors;
using S1API.Entities.Interfaces;
using S1API.Entities.Relation;
using S1API.Entities.Schedule;
using S1API.Entities.Supplier;
using S1API.Entities.Voices;
using S1API.ExternalHosting;
using S1API.GameTime;
using S1API.Graffiti;
using S1API.Growing;
using S1API.Interaction;
using S1API.Internal;
using S1API.Internal.Abstraction;
using S1API.Internal.Building;
using S1API.Internal.Compatibility;
using S1API.Internal.Console;
using S1API.Internal.Cutscenes;
using S1API.Internal.Deliveries;
using S1API.Internal.Diagnostics;
using S1API.Internal.Entities;
using S1API.Internal.Entities.Suppliers;
using S1API.Internal.Interaction;
using S1API.Internal.Items;
using S1API.Internal.Lifecycle;
using S1API.Internal.Map;
using S1API.Internal.NPCWorkbench;
using S1API.Internal.Patches;
using S1API.Internal.Phone;
using S1API.Internal.Products;
using S1API.Internal.Properties;
using S1API.Internal.Rendering;
using S1API.Internal.Shops;
using S1API.Internal.Temperature;
using S1API.Internal.Utils;
using S1API.Internal.Vehicles;
using S1API.Internal.Weather;
using S1API.Items;
using S1API.Items.Additive;
using S1API.Items.Buildable;
using S1API.Items.Clothing;
using S1API.Items.Quality;
using S1API.Items.Storable;
using S1API.Law;
using S1API.Leveling;
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.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.Stations;
using S1API.Storage;
using S1API.Storages;
using S1API.TVApp;
using S1API.Trash;
using S1API.Utils;
using S1API.Vehicles;
using S1API.Weather;
using ScheduleOne;
using ScheduleOne.Avatar;
using ScheduleOne.Avatar.Player;
using ScheduleOne.Avatar.Tools;
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.CharacterCreator;
using ScheduleOne.Clothing;
using ScheduleOne.Combat;
using ScheduleOne.Core;
using ScheduleOne.Core.Avatar;
using ScheduleOne.Core.Avatar.Properties;
using ScheduleOne.Core.Equipping.Framework;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.Core.Weather;
using ScheduleOne.Cutscenes;
using ScheduleOne.Delivery;
using ScheduleOne.DevUtilities;
using ScheduleOne.Dialogue;
using ScheduleOne.Doors;
using ScheduleOne.Economy;
using ScheduleOne.Effects;
using ScheduleOne.Effects.MixMaps;
using ScheduleOne.Employees;
using ScheduleOne.EntityFramework;
using ScheduleOne.Equipping;
using ScheduleOne.Equipping.Framework;
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.Framework;
using ScheduleOne.NPCs.Other;
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.StationFramework;
using ScheduleOne.Storage;
using ScheduleOne.TV;
using ScheduleOne.Temperature;
using ScheduleOne.Tiles;
using ScheduleOne.Tools;
using ScheduleOne.Trash;
using ScheduleOne.UI;
using ScheduleOne.UI.Items;
using ScheduleOne.UI.MainMenu;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Phone.ContactsApp;
using ScheduleOne.UI.Phone.Delivery;
using ScheduleOne.UI.Phone.Map;
using ScheduleOne.UI.Phone.Messages;
using ScheduleOne.UI.Phone.ProductManagerApp;
using ScheduleOne.UI.Relations;
using ScheduleOne.UI.Shop;
using ScheduleOne.UI.Stations;
using ScheduleOne.UI.WorldspacePopup;
using ScheduleOne.Variables;
using ScheduleOne.Vehicles;
using ScheduleOne.Vehicles.Modification;
using ScheduleOne.Vision;
using ScheduleOne.VoiceOver;
using ScheduleOne.Weather;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
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: InternalsVisibleTo("S1API.Tests")]
[assembly: InternalsVisibleTo("S1API.CustomProductLifecycleSmoke")]
[assembly: MelonInfo(typeof(global::S1API.S1API), "S1API (Forked by Bars)", "3.2.3", "KaBooMa", null)]
[assembly: MelonPriority(int.MinValue)]
[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("3.2.3.0")]
[assembly: AssemblyInformationalVersion("3.2.3+c81076db53242c4e7df4190c3bb342ba4e627cf8")]
[assembly: AssemblyProduct("S1API")]
[assembly: AssemblyTitle("S1API")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ifBars/S1API")]
[assembly: AssemblyVersion("3.2.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 OnInitializeMelon()
		{
			S1APIPreferences.Initialize();
			MelonPreferences_Entry<bool>? enableUnityNullReferenceTraceLogging = S1APIPreferences.EnableUnityNullReferenceTraceLogging;
			if (enableUnityNullReferenceTraceLogging != null && enableUnityNullReferenceTraceLogging.Value)
			{
				MelonLogger.Warning("Exception trace logging is enabled. If you are not a mod developer, you probably do not need this enabled.");
				UnityExceptionTraceHook.Install();
			}
		}

		public override void OnDeinitializeMelon()
		{
			VehicleSeats.Clear();
			AvatarCompatibility.ResetRendering();
			IconFactory.ResetAccessoryIconState();
			WeatherRuntime.ResetBindings();
			NPCWorkbenchRuntime.Close();
			PresentationWorkbenchRuntime.Close();
			ProductPackagingContentRuntime.ResetForSceneChange();
			CutsceneManager.Deinitialize();
			MapPOIManager.RemoveAll();
			UnityExceptionTraceHook.Remove();
		}

		public override void OnUpdate()
		{
			VehicleSeats.Tick();
			WeatherRuntime.Tick();
			PresentationWorkbenchRuntime.Tick();
			CutsceneManager.Tick(Time.unscaledDeltaTime);
			NPCWorkbenchRuntime.Tick();
		}

		public override void OnGUI()
		{
			CutsceneManager.DrawPresentation();
		}

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

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			VehicleSeats.Clear();
			NPCWorkbenchRuntime.Close();
			PresentationWorkbenchRuntime.Close();
			CutsceneManager.CleanupForSceneChange();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: true);
			if (sceneName == "Main" || sceneName == "Tutorial")
			{
				ProductPackagingContentRuntime.ResetForSceneChange();
				MapPOIManager.ResetForSceneChange();
			}
			if (sceneName == "Main")
			{
				GameLifecycle.Reset();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			NPCNetworkBootstrap.EnsurePrefabsWarmup();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: false);
		}
	}
}
namespace S1API.Weather
{
	public static class WeatherManager
	{
		private static readonly Log Logger = new Log("WeatherManager");

		private static readonly IReadOnlyList<string> EmptySequenceIds = new ReadOnlyCollection<string>(Array.Empty<string>());

		private static WeatherState? _current;

		public static WeatherState? Current => _current;

		public static IReadOnlyList<string> KnownSequenceIds => WeatherRuntime.GetKnownSequenceIds();

		public static event Action<WeatherState>? OnWeatherChanged;

		internal static void NotifyWeatherChanged(WeatherState state)
		{
			if (_current.HasValue && _current.Value.Equals(state))
			{
				return;
			}
			_current = state;
			Action<WeatherState> onWeatherChanged = WeatherManager.OnWeatherChanged;
			if (onWeatherChanged == null)
			{
				return;
			}
			Delegate[] invocationList = onWeatherChanged.GetInvocationList();
			foreach (Delegate obj in invocationList)
			{
				try
				{
					((Action<WeatherState>)obj)(state);
				}
				catch (Exception exception)
				{
					TryLogSubscriberFailure(exception);
				}
			}
		}

		private static void TryLogSubscriberFailure(Exception exception)
		{
			try
			{
				Logger.Warning("A WeatherManager.OnWeatherChanged subscriber failed: " + exception.Message);
			}
			catch
			{
			}
		}

		internal static void ResetState()
		{
			_current = null;
		}

		internal static IReadOnlyList<string> SnapshotSequenceIds(IEnumerable<string?> sequenceIds)
		{
			if (sequenceIds == null)
			{
				return EmptySequenceIds;
			}
			List<string> list = new List<string>();
			foreach (string sequenceId in sequenceIds)
			{
				if (!string.IsNullOrEmpty(sequenceId))
				{
					list.Add(sequenceId);
				}
			}
			IReadOnlyList<string> result;
			if (list.Count != 0)
			{
				IReadOnlyList<string> readOnlyList = new ReadOnlyCollection<string>(list);
				result = readOnlyList;
			}
			else
			{
				result = EmptySequenceIds;
			}
			return result;
		}
	}
	public readonly struct WeatherState : IEquatable<WeatherState>
	{
		public float Sunny { get; }

		public float Cloudy { get; }

		public float Rainy { get; }

		public float Stormy { get; }

		public float Snowy { get; }

		public float Foggy { get; }

		public float Windy { get; }

		public float Hail { get; }

		public float Sleet { get; }

		public WeatherState(float sunny, float cloudy, float rainy, float stormy, float snowy, float foggy, float windy, float hail, float sleet)
		{
			Sunny = sunny;
			Cloudy = cloudy;
			Rainy = rainy;
			Stormy = stormy;
			Snowy = snowy;
			Foggy = foggy;
			Windy = windy;
			Hail = hail;
			Sleet = sleet;
		}

		internal static WeatherState FromNativeComponents(float sunny, float cloudy, float rainy, float stormy, float snowy, float foggy, float windy, float hail, float sleet)
		{
			return new WeatherState(sunny, cloudy, rainy, stormy, snowy, foggy, windy, hail, sleet);
		}

		public bool Equals(WeatherState other)
		{
			return Sunny.Equals(other.Sunny) && Cloudy.Equals(other.Cloudy) && Rainy.Equals(other.Rainy) && Stormy.Equals(other.Stormy) && Snowy.Equals(other.Snowy) && Foggy.Equals(other.Foggy) && Windy.Equals(other.Windy) && Hail.Equals(other.Hail) && Sleet.Equals(other.Sleet);
		}

		public override bool Equals(object? obj)
		{
			return obj is WeatherState other && Equals(other);
		}

		public override int GetHashCode()
		{
			int hashCode = Sunny.GetHashCode();
			hashCode = (hashCode * 397) ^ Cloudy.GetHashCode();
			hashCode = (hashCode * 397) ^ Rainy.GetHashCode();
			hashCode = (hashCode * 397) ^ Stormy.GetHashCode();
			hashCode = (hashCode * 397) ^ Snowy.GetHashCode();
			hashCode = (hashCode * 397) ^ Foggy.GetHashCode();
			hashCode = (hashCode * 397) ^ Windy.GetHashCode();
			hashCode = (hashCode * 397) ^ Hail.GetHashCode();
			return (hashCode * 397) ^ Sleet.GetHashCode();
		}

		public static bool operator ==(WeatherState left, WeatherState right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(WeatherState left, WeatherState right)
		{
			return !left.Equals(right);
		}
	}
}
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 NetworkConnection? _conn;

		private string _guid = string.Empty;

		public IReadOnlyList<VehicleSeatInfo> Seats => VehicleSeats.Get(S1LandVehicle);

		public float VehiclePrice
		{
			get
			{
				return S1LandVehicle.VehiclePrice;
			}
			set
			{
				global::S1API.Internal.Utils.ReflectionUtils.TrySetFieldOrProperty(S1LandVehicle, "vehiclePrice", 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))/*cast due to .constrained prefix*/).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 VehicleColorCatalog
	{
		private static readonly IReadOnlyList<VehicleColorMetadata> EmptyColors = new ReadOnlyCollection<VehicleColorMetadata>(Array.Empty<VehicleColorMetadata>());

		private static IVehicleColorMetadataProvider _provider = new NativeVehicleColorMetadataProvider();

		public static IReadOnlyList<VehicleColorMetadata> Colors => GetColors();

		public static VehicleColorMetadata? GetColor(VehicleColor color)
		{
			TryGetColor(color, out VehicleColorMetadata metadata);
			return metadata;
		}

		public static bool TryGetColor(VehicleColor color, out VehicleColorMetadata? metadata)
		{
			if (!Enum.IsDefined(typeof(VehicleColor), color))
			{
				metadata = null;
				return false;
			}
			return _provider.TryGetColor(color, out metadata);
		}

		internal static void ResetForTesting(IVehicleColorMetadataProvider provider)
		{
			_provider = provider ?? throw new ArgumentNullException("provider");
		}

		internal static void RestoreProviderForTesting()
		{
			_provider = new NativeVehicleColorMetadataProvider();
		}

		private static IReadOnlyList<VehicleColorMetadata> GetColors()
		{
			if (!_provider.TryGetColors(out IReadOnlyList<VehicleColorMetadata> metadata) || metadata == null || metadata.Count == 0)
			{
				return EmptyColors;
			}
			return new ReadOnlyCollection<VehicleColorMetadata>(new List<VehicleColorMetadata>(metadata));
		}
	}
	internal interface IVehicleColorMetadataProvider
	{
		bool TryGetColors(out IReadOnlyList<VehicleColorMetadata>? metadata);

		bool TryGetColor(VehicleColor color, out VehicleColorMetadata? metadata);
	}
	internal sealed class NativeVehicleColorMetadataProvider : IVehicleColorMetadataProvider
	{
		public bool TryGetColors(out IReadOnlyList<VehicleColorMetadata>? metadata)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected I4, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			metadata = null;
			try
			{
				if (!Singleton<VehicleColors>.InstanceExists)
				{
					return false;
				}
				VehicleColors instance = Singleton<VehicleColors>.Instance;
				if (instance.colorLibrary == null)
				{
					return false;
				}
				List<VehicleColorMetadata> list = new List<VehicleColorMetadata>(instance.colorLibrary.Count);
				for (int i = 0; i < instance.colorLibrary.Count; i++)
				{
					VehicleColorData val = instance.colorLibrary[i];
					if (val != null)
					{
						VehicleColor vehicleColor = (VehicleColor)val.color;
						if (Enum.IsDefined(typeof(VehicleColor), vehicleColor))
						{
							list.Add(new VehicleColorMetadata(vehicleColor, val.colorName, val.MaterialColor, val.UIColor));
						}
					}
				}
				if (list.Count == 0)
				{
					return false;
				}
				metadata = new ReadOnlyCollection<VehicleColorMetadata>(list);
				return true;
			}
			catch
			{
				return false;
			}
		}

		public bool TryGetColor(VehicleColor color, out VehicleColorMetadata? metadata)
		{
			metadata = null;
			if (!TryGetColors(out IReadOnlyList<VehicleColorMetadata> metadata2) || metadata2 == null)
			{
				return false;
			}
			for (int i = 0; i < metadata2.Count; i++)
			{
				VehicleColorMetadata vehicleColorMetadata = metadata2[i];
				if (vehicleColorMetadata.Color == color)
				{
					metadata = vehicleColorMetadata;
					return true;
				}
			}
			return false;
		}
	}
	public sealed class VehicleColorMetadata
	{
		public VehicleColor Color { get; }

		public string? DisplayName { get; }

		public Color MaterialColor { get; }

		public Color32 UIColor { get; }

		internal VehicleColorMetadata(VehicleColor color, string? displayName, Color materialColor, Color32 uiColor)
		{
			//IL_0017: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Color = color;
			DisplayName = displayName;
			MaterialColor = materialColor;
			UIColor = uiColor;
		}
	}
	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 val = GUIDManager.GetObject<LandVehicle>(guid2);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				return Wrap(val);
			}
			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);
			}
		}

		internal 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;
		}
	}
	public sealed class VehicleSeatInfo
	{
		private VehicleSeat? _seat;

		private Player? _observedOccupant;

		private Player? _observedPlayer;

		public int Index { get; }

		public bool IsDriverSeat { get; }

		public bool IsOccupied => ReadOccupant() != null;

		public Player? Occupant => ResolvePlayer(ReadOccupant());

		public event Action<Player?, Player?>? OccupantChanged;

		internal VehicleSeatInfo(int index, VehicleSeat? seat)
		{
			Index = index;
			_seat = seat;
			IsDriverSeat = seat != null && (Object)(object)seat != (Object)null && seat.isDriverSeat;
			_observedOccupant = ReadOccupant();
			_observedPlayer = ResolvePlayer(_observedOccupant);
		}

		internal void Refresh()
		{
			Player val = ReadOccupant();
			Player player = ResolvePlayer(val);
			if (SameIdentity(_observedOccupant, val))
			{
				_observedPlayer = player;
				return;
			}
			Player previous = _observedPlayer ?? ResolvePlayer(_observedOccupant);
			_observedOccupant = val;
			_observedPlayer = player;
			NotifyOccupantChanged(previous, player);
		}

		internal void Invalidate()
		{
			_seat = null;
			_observedOccupant = null;
			_observedPlayer = null;
			this.OccupantChanged = null;
		}

		internal void NotifyOccupantChanged(Player? previous, Player? current)
		{
			Action<Player, Player> action = this.OccupantChanged;
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action<Player, Player> action2 = (Action<Player, Player>)invocationList[i];
				try
				{
					action2(previous, current);
				}
				catch (Exception ex)
				{
					try
					{
						new Log("VehicleSeatInfo").Warning("An OccupantChanged subscriber failed: " + ex.Message);
					}
					catch
					{
					}
				}
			}
		}

		private Player? ReadOccupant()
		{
			if (_seat == null || (Object)(object)_seat == (Object)null)
			{
				return null;
			}
			Player occupant = _seat.Occupant;
			return (occupant == null || (Object)(object)occupant == (Object)null) ? null : occupant;
		}

		private static bool SameIdentity(Player? left, Player? right)
		{
			return left == right;
		}

		private static Player? ResolvePlayer(Player? native)
		{
			if (native == null)
			{
				return null;
			}
			foreach (Player item in Player.All)
			{
				if (SameIdentity(item.S1Player, native))
				{
					return item;
				}
			}
			return null;
		}
	}
}
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.ToColorInternal(hexColor);
		}
	}
	public static class EventHelper
	{
		internal static void AddListener(Action listener, Action<Action> subscribe)
		{
			global::S1API.Internal.Abstraction.EventHelper.AddListener(listener, subscribe);
		}

		internal static void RemoveListener(Action listener, Action<Action> unsubscribe)
		{
			global::S1API.Internal.Abstraction.EventHelper.RemoveListener(listener, unsubscribe);
		}

		public static void AddListener(Action listener, UnityEvent unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.AddListener(listener, unityEvent);
		}

		public static void RemoveListener(Action listener, UnityEvent unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.RemoveListener(listener, unityEvent);
		}

		public static void AddListener<T>(Action<T> listener, UnityEvent<T> unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.AddListener(listener, unityEvent);
		}

		public static void RemoveListener<T>(Action<T> listener, UnityEvent<T> unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.RemoveListener(listener, unityEvent);
		}

		public static void AddEventTrigger(EventTrigger trigger, EventTriggerType eventType, Action listener)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Abstraction.EventHelper.AddEventTrigger(trigger, eventType, listener);
		}

		public static void AddEventTrigger(EventTrigger trigger, EventTriggerType eventType, Action<BaseEventData> listener)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Abstraction.EventHelper.AddEventTrigger(trigger, eventType, listener);
		}

		public static void RemoveEventTrigger(EventTrigger trigger, EventTriggerType eventType, Action<BaseEventData> listener)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Abstraction.EventHelper.RemoveEventTrigger(trigger, eventType, listener);
		}
	}
	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 = (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);
		}
	}
	public static class TransformUtils
	{
		public static Transform? FindDescendant(Transform root, string name)
		{
			return global::S1API.Internal.Utils.TransformUtils.FindDescendant(root, name);
		}
	}
}
namespace S1API.UI
{
	public static class CharacterCreatorManager
	{
		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();
				if ((Object)(object)_s1Creator == (Object)null || !_s1Creator.IsOpen)
				{
					return null;
				}
				object? obj = global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(_s1Creator, "_currentState");
				CharacterCreatorState val = (CharacterCreatorState)((obj is CharacterCreatorState) ? obj : null);
				return (val?.Appearance == null) ? null : BasicAvatarSettings.FromPlayerAppearance(val.Appearance);
			}
		}

		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 || !showUI)
			{
				Logger.Warning("Schedule I 0.4.7 no longer accepts legacy initial settings or a hidden character-creator canvas; opening the native creator with its defaults.");
			}
			_s1Creator.Open();
			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;
			}
			typeof(CharacterCreator).GetMethod("Close", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(_s1Creator, null);
			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
			{
				Logger.Warning("Character-creator presets are not available in Schedule I 0.4.7.");
			}
		}

		public static string[] GetAvailablePresets()
		{
			EnsureInitialized();
			return Array.Empty<string>();
		}

		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.SetAvatarRotation(Mathf.Clamp01(normalizedValue) * 359f);
			}
		}

		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
			{
				_s1Creator.OnComplete += OnCreatorCompleted;
				_eventsRegistered = true;
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to register CharacterCreator events: {arg}");
			}
		}

		private static void OnCreatorCompleted(CharacterCreatorState state)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected I4, but got Unknown
			//IL_005c: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (state?.Appearance == null)
				{
					Logger.Warning("CharacterCreator completed with null settings");
					return;
				}
				BasicAvatarSettings basicAvatarSettings = BasicAvatarSettings.Create();
				basicAvatarSettings.Gender = (int)state.Appearance.Gender;
				basicAvatarSettings.Weight = state.Appearance.Weight;
				basicAvatarSettings.SkinColor = state.Appearance.SkinColor;
				basicAvatarSettings.HairStyle = state.Appearance.HairStyleId ?? string.Empty;
				basicAvatarSettings.HairColor = state.Appearance.HairColor;
				basicAvatarSettings.Mouth = state.Appearance.FaceId ?? string.Empty;
				basicAvatarSettings.FacialHair = state.Appearance.FacialHairId ?? string.Empty;
				basicAvatarSettings.FacialDetails = state.Appearance.FacialDetailId ?? string.Empty;
				basicAvatarSettings.FacialDetailsIntensity = state.Appearance.FacialDetailIntensity;
				basicAvatarSettings.EyeballColor = state.Appearance.EyeballColor;
				basicAvatarSettings.PupilDilation = state.Appearance.PupilDilation;
				basicAvatarSettings.UpperEyeLidRestingPosition = state.Appearance.UpperEyelidPosition;
				basicAvatarSettings.LowerEyeLidRestingPosition = state.Appearance.LowerEyelidPosition;
				basicAvatarSettings.EyebrowScale = state.Appearance.EyebrowScale;
				basicAvatarSettings.EyebrowThickness = state.Appearance.EyebrowThickness;
				basicAvatarSettings.EyebrowRestingHeight = state.Appearance.EyebrowHeight;
				basicAvatarSettings.EyebrowRestingAngle = state.Appearance.EyebrowAngle;
				MelonCoroutines.Start(RestoreGameState());
				CharacterCreatorManager.OnCompleted?.Invoke(basicAvatarSettings);
			}
			catch (Exception arg)
			{
				Logger.Error($"Error in OnCompleted event handler: {arg}");
			}
		}

		private static IEnumerator RestoreAfterClose()
		{
			yield return RestoreGameState();
		}

		private static IEnumerator RestoreGameState()
		{
			yield return null;
			yield return (object)new WaitForSeconds(0.1f);
			if (PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerCamera camera = PlayerSingleton<PlayerCamera>.Instance;
				CharacterCreator? s1Creator = _s1Creator;
				camera.RemoveActiveUIElement(((s1Creator != null) ? ((Object)s1Creator).name : null) ?? "CharacterCreator");
				if (GetActiveUIElementCount(camera) == 0)
				{
					camera.StopTransformOverride(0f, true, false);
					camera.StopFOVOverride(0f);
					camera.SetCanLook(true);
					camera.LockMouse(true);
				}
			}
			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;
			}
		}

		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 currentBasicAvatarSettings = local.GetCurrentBasicAvatarSettings();
				if (currentBasicAvatarSettings == null)
				{
					Logger.Debug("Player has no current avatar settings, using default");
					return null;
				}
				BasicAvatarSettings settings = Object.Instantiate<BasicAvatarSettings>(currentBasicAvatarSettings.S1BasicAvatarSettings);
				return new BasicAvatarSettings(settings);
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to get player avatar settings: {arg}");
				return null;
			}
		}

		private static int GetActiveUIElementCount(PlayerCamera camera)
		{
			if ((Object)(object)camera == (Object)null)
			{
				return 0;
			}
			if (global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(camera, "activeUIElementCount") is int result)
			{
				return result;
			}
			return 0;
		}
	}
	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 = (TextAnchor)0, FontStyle style = (FontStyle)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 = (TextAnchor)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(Width, Height);
			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 = (TextAnchor)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.TVApp
{
	public abstract class TVApp : Registerable
	{
		protected static readonly Log Logger = new Log("TVApp");

		private GameObject? _appRoot;

		private Canvas? _canvas;

		private CanvasGroup? _canvasGroup;

		private GameObject? _container;

		private TVHomeScreen? _homeScreen;

		private ExitDelegate? _exitDelegate;

		private bool _isOpen;

		private bool _isPaused;

		private bool _uiCreated;

		protected abstract string AppName { get; }

		protected abstract string AppTitle { get; }

		protected abstract Sprite Icon { get; }

		public bool IsOpen => _isOpen;

		public bool IsPaused => _isPaused;

		protected abstract void OnCreatedUI(GameObject container);

		protected virtual void OnUpdate()
		{
		}

		protected virtual void OnOpened()
		{
		}

		protected virtual void OnClosed()
		{
		}

		protected virtual void OnPaused()
		{
		}

		protected virtual void OnResumed()
		{
		}

		public void Open()
		{
			if (_isOpen)
			{
				return;
			}
			try
			{
				_isOpen = true;
				_isPaused = false;
				if ((Object)(object)_appRoot != (Object)null)
				{
					_appRoot.SetActive(true);
				}
				if ((Object)(object)_canvasGroup != (Object)null)
				{
					_canvasGroup.alpha = 1f;
				}
				if ((Object)(object)_container != (Object)null)
				{
					_container.SetActive(true);
				}
				OnOpened();
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to open TV app " + AppName + ": " + ex.Message);
			}
		}

		public void Close()
		{
			if (!_isOpen)
			{
				return;
			}
			try
			{
				_isOpen = false;
				_isPaused = false;
				if ((Object)(object)_canvasGroup != (Object)null)
				{
					_canvasGroup.alpha = 0f;
				}
				if ((Object)(object)_container != (Object)null)
				{
					_container.SetActive(false);
				}
				if ((Object)(object)_appRoot != (Object)null)
				{
					_appRoot.SetActive(false);
				}
				OnClosed();
				TVHomeScreen? homeScreen = _homeScreen;
				if (homeScreen != null)
				{
					((TVApp)homeScreen).Open();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to close TV app " + AppName + ": " + ex.Message);
			}
		}

		internal void ForceClose()
		{
			if (!_isOpen)
			{
				return;
			}
			try
			{
				_isOpen = false;
				_isPaused = false;
				if ((Object)(object)_canvasGroup != (Object)null)
				{
					_canvasGroup.alpha = 0f;
				}
				if ((Object)(object)_container != (Object)null)
				{
					_container.SetActive(false);
				}
				if ((Object)(object)_appRoot != (Object)null)
				{
					_appRoot.SetActive(false);
				}
				OnClosed();
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to force close TV app " + AppName + ": " + ex.Message);
			}
		}

		public void Pause()
		{
			if (_isOpen && !_isPaused)
			{
				_isPaused = true;
				OnPaused();
			}
		}

		public void Resume()
		{
			if (_isOpen && _isPaused)
			{
				_isPaused = false;
				OnResumed();
			}
		}

		protected override void OnCreated()
		{
			TVAppRegistry.Register(this);
			ExternalAppCatalog.Register(ExternalAppFamily.TV, this, () => AppName, () => AppTitle, () => Icon);
		}

		protected override void OnDestroyed()
		{
			ExternalAppCatalog.Unregister(this);
			if (_exitDelegate != null)
			{
				GameInput.DeregisterExitListener(_exitDelegate);
				_exitDelegate = null;
			}
			if ((Object)(object)_appRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_appRoot);
				_appRoot = null;
			}
			_canvas = null;
			_canvasGroup = null;
			_container = null;
			_homeScreen = null;
			_uiCreated = false;
			_isOpen = false;
			_isPaused = false;
		}

		internal void SpawnUI(TVHomeScreen homeScreen)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			if (_uiCreated)
			{
				return;
			}
			_homeScreen = homeScreen;
			Transform parent = ((Component)homeScreen).transform.parent;
			if ((Object)(object)parent == (Object)null)
			{
				Logger.Error("Cannot find parent transform for TV app: " + AppName);
				return;
			}
			_appRoot = new GameObject(AppName + "_TVApp");
			_appRoot.transform.SetParent(parent, false);
			TVApp[] apps = homeScreen.Apps;
			if (apps != null && apps.Length != 0 && (Object)(object)apps[0].Canvas != (Object)null)
			{
				Transform transform = ((Component)apps[0].Canvas).transform;
				_appRoot.transform.localPosition = transform.localPosition;
				_appRoot.transform.localRotation = transform.localRotation;
				_appRoot.transform.localScale = transform.localScale;
			}
			_canvas = _appRoot.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)2;
			if (apps != null && apps.Length != 0 && (Object)(object)apps[0].Canvas != (Object)null)
			{
				Canvas canvas = apps[0].Canvas;
				_canvas.sortingOrder = canvas.sortingOrder;
				_canvas.worldCamera = canvas.worldCamera;
				_appRoot.layer = ((Component)apps[0].Canvas).gameObject.layer;
				RectTransform component = ((Component)canvas).GetComponent<RectTransform>();
				RectTransform component2 = _appRoot.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
				{
					component2.sizeDelta = component.sizeDelta;
				}
			}
			_canvasGroup = _appRoot.AddComponent<CanvasGroup>();
			_canvasGroup.alpha = 0f;
			_canvasGroup.interactable = true;
			_canvasGroup.blocksRaycasts = true;
			_appRoot.AddComponent<GraphicRaycaster>();
			_container = new GameObject("Container");
			_container.transform.SetParent(_appRoot.transform, false);
			RectTransform val = _container.AddComponent<RectTransform>();
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			val.offsetMin = Vector2.zero;
			val.offsetMax = Vector2.zero;
			OnCreatedUI(_container);
			TVAppUpdateHandler tVAppUpdateHandler = _appRoot.AddComponent<TVAppUpdateHandler>();
			tVAppUpdateHandler.tvApp = this;
			_exitDelegate = new ExitDelegate(HandleExit);
			GameInput.RegisterExitListener(_exitDelegate, 3);
			_appRoot.SetActive(false);
			_uiCreated = true;
		}

		internal void SpawnButton(TVHomeScreen homeScreen)
		{
			if ((Object)(object)homeScreen.AppButtonPrefab == (Object)null || (Object)(object)homeScreen.AppButtonContainer == (Object)null)
			{
				Logger.Error("Cannot create button for TV app " + AppName + ": missing prefab or container");
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(homeScreen.AppButtonPrefab, (Transform)(object)homeScreen.AppButtonContainer);
			((Object)val).name = "Button_" + AppName;
			Transform val2 = val.transform.Find("Icon");
			if ((Object)(object)val2 != (Object)null)
			{
				Image component = ((Component)val2).GetComponent<Image>();
				if ((Object)(object)component != (Object)null && (Object)(object)Icon != (Object)null)
				{
					component.sprite = Icon;
				}
			}
			Transform val3 = val.transform.Find("Name");
			if ((Object)(object)val3 != (Object)null)
			{
				TextMeshProUGUI component2 = ((Component)val3).GetComponent<TextMeshProUGUI>();
				if ((Object)(object)component2 != (Object)null)
				{
					((TMP_Text)component2).text = AppTitle;
				}
			}
			Button component3 = val.GetComponent<Button>();
			if ((Object)(object)component3 != (Object)null)
			{
				((UnityEventBase)component3.onClick).RemoveAllListeners();
				global::S1API.Utils.EventHelper.AddListener(OnButtonClicked, (UnityEvent)(object)component3.onClick);
			}
		}

		internal void InvokeUpdate()
		{
			if (_isOpen && !_isPaused)
			{
				OnUpdate();
			}
		}

		private void OnButtonClicked()
		{
			if ((Object)(object)_homeScreen == (Object)null)
			{
				return;
			}
			try
			{
				TVHomeScreen_Close_Patch.SkipInterfaceClose = true;
				((TVApp)_homeScreen).Close();
				Open();
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to open TV app " + AppName + ": " + ex.Message);
			}
		}

		private void HandleExit(ExitAction exit)
		{
			if (!exit.Used && _isOpen)
			{
				exit.Used = true;
				Close();
			}
		}
	}
	internal class TVAppUpdateHandler : MonoBehaviour
	{
		internal TVApp? tvApp;

		private void Update()
		{
			if (tvApp != null)
			{
				tvApp.InvokeUpdate();
			}
		}
	}
}
namespace S1API.Trash
{
	public sealed class Recycler
	{
		private readonly UnityEvent? _onStart;

		private readonly UnityEvent? _onStop;

		private readonly UnityAction _startListener;

		private readonly UnityAction _stopListener;

		private bool _listening;

		internal readonly Recycler S1Recycler;

		public RecyclerState State => (RecyclerState)S1Recycler.State;

		public bool IsHatchOpen => S1Recycler.IsHatchOpen;

		public Vector3 Position => ((Component)S1Recycler).transform.position;

		public GameObject GameObject => ((Component)S1Recycler).gameObject;

		internal Recycler(Recycler recycler)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			S1Recycler = recycler;
			_onStart = recycler.onStart;
			_onStop = recycler.onStop;
			_startListener = new UnityAction(NotifyProcessingStarted);
			_stopListener = new UnityAction(NotifyProcessingStopped);
			try
			{
				if (_onStart != null)
				{
					_onStart.AddListener(_startListener);
				}
				if (_onStop != null)
				{
					_onStop.AddListener(_stopListener);
				}
				_listening = true;
			}
			catch
			{
				Cleanup();
				throw;
			}
		}

		internal void Cleanup()
		{
			_listening = false;
			if (_onStart != null)
			{
				_onStart.RemoveListener(_startListener);
			}
			if (_onStop != null)
			{
				_onStop.RemoveListener(_stopListener);
			}
		}

		private void NotifyProcessingStarted()
		{
			if (_listening)
			{
				RecyclerRegistry.NotifyProcessingStarted(this);
			}
		}

		private void NotifyProcessingStopped()
		{
			if (_listening)
			{
				RecyclerRegistry.NotifyProcessingStopped(this);
			}
		}
	}
	public static class RecyclerRegistry
	{
		private static readonly Log Logger = new Log("RecyclerRegistry");

		private static readonly Dictionary<int, Recycler> Recyclers = new Dictionary<int, Recycler>();

		private static bool _lifecycleHooked;

		public static event Action<Recycler>? ProcessingStarted;

		public static event Action<Recycler>? ProcessingStopped;

		public static IReadOnlyList<Recycler> GetAll()
		{
			EnsureLifecycleHook();
			PruneDestroyedRecyclers();
			Recycler[] array = Object.FindObjectsOfType<Recycler>();
			List<Recycler> list = new List<Recycler>(array.Length);
			foreach (Recycler val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					list.Add(Wrap(val));
				}
			}
			return new ReadOnlyCollection<Recycler>(list);
		}

		internal static Recycler Wrap(Recycler native)
		{
			EnsureLifecycleHook();
			int instanceID = ((Object)native).GetInstanceID();
			if (Recyclers.TryGetValue(instanceID, out Recycler value))
			{
				if ((Object)(object)value.S1Recycler != (Object)null)
				{
					return value;
				}
				value.Cleanup();
				Recyclers.Remove(instanceID);
			}
			value = new Recycler(native);
			Recyclers.Add(instanceID, value);
			return value;
		}

		internal static void Remove(Recycler native)
		{
			int instanceID = ((Object)native).GetInstanceID();
			if (Recyclers.TryGetValue(instanceID, out Recycler value))
			{
				value.Cleanup();
				Recyclers.Remove(instanceID);
			}
		}

		internal static void NotifyProcessingStarted(Recycler recycler)
		{
			Invoke(RecyclerRegistry.ProcessingStarted, recycler, "ProcessingStarted");
		}

		internal static void NotifyProcessingStopped(Recycler recycler)
		{
			Invoke(RecyclerRegistry.ProcessingStopped, recycler, "ProcessingStopped");
		}

		private static void Invoke(Action<Recycler>? handlers, Recycler recycler, string eventName)
		{
			if (handlers == null)
			{
				return;
			}
			Delegate[] invocationList = handlers.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action<Recycler> action = (Action<Recycler>)invocationList[i];
				try
				{
					action(recycler);
				}
				catch (Exception ex)
				{
					Logger.Warning("A RecyclerRegistry." + eventName + " subscriber failed: " + ex.Message);
				}
			}
		}

		private static void EnsureLifecycleHook()
		{
			if (!_lifecycleHooked)
			{
				GameLifecycle.OnPreSceneChange += ClearSceneState;
				_lifecycleHooked = true;
			}
		}

		private static void PruneDestroyedRecyclers()
		{
			List<int> list = null;
			foreach (KeyValuePair<int, Recycler> recycler in Recyclers)
			{
				if (!((Object)(object)recycler.Value.S1Recycler != (Object)null))
				{
					recycler.Value.Cleanup();
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(recycler.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				Recyclers.Remove(item);
			}
		}

		private static void ClearSceneState()
		{
			foreach (Recycler value in Recyclers.Values)
			{
				value.Cleanup();
			}
			Recyclers.Clear();
		}
	}
	public enum RecyclerState
	{
		HatchClosed,
		HatchOpen,
		Processing
	}
	public sealed class TrashContainer
	{
		private abstract class TrashContainerRegistrationState
		{
			internal TrashContainer S1TrashContainer { get; }

			protected TrashContainerRegistrationState(TrashContainer trashContainer)
			{
				S1TrashContainer = trashContainer;
			}
		}

		private sealed class TrashAddedRegistrationState : TrashContainerRegistrationState
		{
			internal ManagedEventRegistrationTracker<Action<string>> Registrations { get; } = new ManagedEventRegistrationTracker<Action<string>>();

			internal TrashAddedRegistrationState(TrashContainer trashContainer)
				: base(trashContainer)
			{
			}
		}

		private sealed class TrashLevelChangedRegistrationState : TrashContainerRegistrationState
		{
			internal ManagedEventRegistrationTracker<Action> Registrations { get; } = new ManagedEventRegistrationTracker<Action>();

			internal TrashLevelChangedRegistrationState(TrashContainer trashContainer)
				: base(trashContainer)
			{
			}
		}

		private static readonly Dictionary<int, TrashAddedRegistrationState> TrashAddedRegistrations = new Dictionary<int, TrashAddedRegistrationState>();

		private static readonly Dictionary<int, TrashLevelChangedRegistrationState> TrashLevelChangedRegistrations = new Dictionary<int, TrashLevelChangedRegistrationState>();

		internal readonly TrashContainer S1TrashContainer;

		public GameObject? GameObject
		{
			get
			{
				TrashContainer s1TrashContainer = S1TrashContainer;
				return (s1TrashContainer != null) ? ((Component)s1TrashContainer).gameObject : null;
			}
		}

		public int Capacity => S1TrashContainer.TrashCapacity;

		public int Level => S1TrashContainer.TrashLevel;

		public float NormalizedLevel => S1TrashContainer.NormalizedTrashLevel;

		public IReadOnlyList<TrashContentEntry> Contents
		{
			get
			{
				List<Entry> list = S1TrashContainer.Content?.Entries;
				if (list == null || list.Count == 0)
				{
					return Array.Empty<TrashContentEntry>();
				}
				List<TrashContentEntry> list2 = new List<TrashContentEntry>(list.Count);
				for (int i = 0; i < list.Count; i++)
				{
					Entry val = list[i];
					if (val != null)
					{
						list2.Add(new TrashContentEntry(val.TrashID, val.Quantity, val.UnitSize, val.UnitValue));
					}
				}
				return list2.AsReadOnly();
			}
		}

		public bool CanBeBagged => S1TrashContainer.CanBeBagged();

		public event Action<string> OnTrashAdded
		{
			add
			{
				if (value != null)
				{
					Action<string> action = CreateNativeTrashAddedHandler(value);
					SubscribeTrashAdded(action);
					GetTrashAddedRegistrationState().Registrations.Add(value, action);
				}
			}
			remove
			{
				if (value != null && TryTakeTrashAddedRegistration(value, out TrashAddedRegistrationState state, out Action<string> nativeHandler))
				{
					try
					{
						UnsubscribeTrashAdded(nativeHandler);
					}
					catch
					{
						state.Registrations.Add(value, nativeHandler);
						throw;
					}
					if (state.Registrations.IsEmpty)
					{
						TrashAddedRegistrations.Remove(((Object)S1TrashContainer).GetInstanceID());
					}
				}
			}
		}

		public event Action OnTrashLevelChanged
		{
			add
			{
				if (value != null)
				{
					Action action = CreateNativeTrashLevelChangedHandler(value);
					SubscribeTrashLevelChanged(action);
					GetTrashLevelChangedRegistrationState().Registrations.Add(value, action);
				}
			}
			remove
			{
				if (value != null && TryTakeTrashLevelChangedRegistration(value, out TrashLevelChangedRegistrationState state, out Action nativeHandler))
				{
					try
					{
						UnsubscribeTrashLevelChanged(nativeHandler);
					}
					catch
					{
						state.Registrations.Add(value, nativeHandler);
						throw;
					}
					if (state.Registrations.IsEmpty)
					{
						TrashLevelChangedRegistrations.Remove(((Object)S1TrashContainer).GetInstanceID());
					}
				}
			}
		}

		internal TrashContainer(TrashContainer trashContainer)
		{
			S1TrashContainer = trashContainer;
		}

		public static TrashContainer? FromGameObject(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				throw new ArgumentNullException("gameObject");
			}
			PruneDestroyedRegistrationStates();
			TrashContainer component = gameObject.GetComponent<TrashContainer>();
			return ((Object)(object)component == (Object)null) ? null : new TrashContainer(component);
		}

		public static TrashContainer[] FindInScene(bool includeInactive = false)
		{
			PruneDestroyedRegistrationStates();
			TrashContainer[] array = Object.FindObjectsOfType<TrashContainer>(includeInactive);
			if (array == null || array.Length == 0)
			{
				return Array.Empty<TrashContainer>();
			}
			List<TrashContainer> list = new List<TrashContainer>(array.Length);
			foreach (TrashContainer val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					list.Add(new TrashContainer(val));
				}
			}
			return list.ToArray();
		}

		public bool TryBagTrash()
		{
			if (!InstanceFinder.IsServer || !S1TrashContainer.CanBeBagged())
			{
				return false;
			}
			S1TrashContainer.BagTrash();
			return true;
		}

		private static Action<string> CreateNativeTrashAddedHandler(Action<string> handler)
		{
			return delegate(string trashId)
			{
				handler(trashId);
			};
		}

		private static Action CreateNativeTrashLevelChangedHandler(Action handler)
		{
			return delegate
			{
				handler();
			};
		}

		private void SubscribeTrashAdded(Action<string> handler)
		{
			global::S1API.Utils.EventHelper.AddListener(handler, S1TrashContainer.onTrashAdded);
		}

		private void UnsubscribeTrashAdded(Action<string> handler)
		{
			global::S1API.Utils.EventHelper.RemoveListener(handler, S1TrashContainer.onTrashAdded);
		}

		private void SubscribeTrashLevelChanged(Action handler)
		{
			global::S1API.Utils.EventHelper.AddListener(handler, S1TrashContainer.onTrashLevelChanged);
		}

		private void UnsubscribeTrashLevelChanged(Action handler)
		{
			global::S1API.Utils.EventHelper.RemoveListener(handler, S1TrashContainer.onTrashLevelChanged);
		}

		private TrashAddedRegistrationState GetTrashAddedRegistrationState()
		{
			PruneDestroyedRegistrationStates();
			int instanceID = ((Object)S1TrashContainer).GetInstanceID();
			if (TrashAddedRegistrations.TryGetValue(instanceID, out TrashAddedRegistrationState value))
			{
				return value;
			}
			value = new TrashAddedRegistrationState(S1TrashContainer);
			TrashAddedRegistrations.Add(instanceID, value);
			return value;
		}

		private bool TryTakeTrashAddedRegistration(Action<string> managedHandler, out TrashAddedRegistrationState state, out Action<string> nativeHandler)
		{
			PruneDestroyedRegistrationStates();
			if (TrashAddedRegistrations.TryGetValue(((Object)S1TrashContainer).GetInstanceID(), out TrashAddedRegistrationState value) && value.Registrations.TryTakeLast(managedHandler, out nativeHandler))
			{
				state = value;
				return true;
			}
			state = null;
			nativeHandler = null;
			return false;
		}

		private TrashLevelChangedRegistrationState GetTrashLevelChangedRegistrationState()
		{
			PruneDestroyedRegistrationStates();
			int instanceID = ((Object)S1TrashContainer).GetInstanceID();
			if (TrashLevelChangedRegistrations.TryGetValue(instanceID, out TrashLevelChangedRegistrationState value))
			{
				return value;
			}
			value = new TrashLevelChangedRegistrationState(S1TrashContainer);
			TrashLevelChangedRegistrations.Add(instanceID, value);
			return value;
		}

		private bool TryTakeTrashLevelChangedRegistration(Action managedHandler, out TrashLevelChangedRegistrationState state, out Action nativeHandler)
		{
			PruneDestroyedRegistrationStates();
			if (TrashLevelChangedRegistrations.TryGetValue(((Object)S1TrashContainer).GetInstanceID(), out TrashLevelChangedRegistrationState value) && value.Registrations.TryTakeLast(managedHandler, out nativeHandler))
			{
				state = value;
				return true;
			}
			state = null;
			nativeHandler = null;
			return false;
		}

		private static void PruneDestroyedRegistrationStates()
		{
			PruneDestroyedRegistrationStates(TrashAddedRegistrations);
			PruneDestroyedRegistrationStates(TrashLevelChangedRegistrations);
		}

		private static void PruneDestroyedRegistrationStates<TState>(Dictionary<int, TState> registrations) where TState : TrashContainerRegistrationState
		{
			List<int> list = null;
			foreach (KeyValuePair<int, TState> registration in registrations)
			{
				if (!((Object)(object)registration.Value.S1TrashContainer != (Object)null))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(registration.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				registrations.Remove(item);
			}
		}
	}
	public readonly struct TrashContentEntry
	{
		public string? TrashId { get; }

		public int Quantity { get; }

		public int UnitSize { get; }

		public int UnitValue { get; }

		internal TrashContentEntry(string? trashId, int quantity, int unitSize, int unitValue)
		{
			TrashId = trashId;
			Quantity = quantity;
			UnitSize = unitSize;
			UnitValue = unitValue;
		}
	}
	public static class TrashManager
	{
		private static readonly Log Logger = new Log("TrashManager");

		private static readonly object RegistrationGate = new object();

		private static readonly Dictionary<string, TrashItem> RegisteredPrefabs = new Dictionary<string, TrashItem>(StringComparer.OrdinalIgnoreCase);

		private static GameObject? _prefabRoot;

		private static bool _lifecycleSubscribed;

		public const int TrashItemLimit = 2000;

		public static GameObject? CreateTrashItem(string id, Vector3 position, Quaternion rotation, Vector3 initialVelocity = default(Vector3), string guid = "")
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			TrashItem val = NetworkSingleton<TrashManager>.Instance.CreateTrashItem(id, position, rotation, initialVelocity, guid);
			return (val != null) ? ((Component)val).gameObject : null;
		}

		public static void DestroyAllTrash()
		{
			NetworkSingleton<TrashManager>.Instance.DestroyAllTrash();
		}

		public static GameObject? GetTrashPrefab(string id)
		{
			TrashManager instance = NetworkSingleton<TrashManager>.Instance;
			TrashItem val = (((Object)(object)instance != (Object)null) ? instance.GetTrashPrefab(id) : null);
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			lock (RegistrationGate)
			{
				TrashItem value;
				return (RegisteredPrefabs.TryGetValue(id, out value) && (Object)(object)value != (Object)null) ? ((Component)value).gameObject : null;
			}
		}

		public static GameObject RegisterTrashPrefab(string id, GameObject trashPrefab, bool replaceExisting = false)
		{
			if (string.IsNullOrWhiteSpace(id))
			{
				throw new ArgumentException("Trash ID is required.", "id");
			}
			if ((Object)(object)trashPrefab == (Object)null)
			{
				throw new ArgumentNullException("trashPrefab");
			}
			TrashItem component = trashPrefab.GetComponent<TrashItem>();
			if ((Object)(object)component == (Object)null)
			{
				throw new ArgumentException("Trash prefab must have a TrashItem component.", "trashPrefab");
			}
			TrashItem val;
			lock (RegistrationGate)
			{
				if (RegisteredPrefabs.TryGetValue(id, out TrashItem value) && (Object)(object)value != (Object)null)
				{
					if (!replaceExisting)
					{
						Logger.Warning("Trash ID '" + id + "' is already registered. Keeping '" + ((Object)((Component)value).gameObject).name + "' and ignoring '" + ((Object)trashPrefab).name + "'. Set replaceExisting to true to replace the existing prefab.");
						return ((Component)value).gameObject;
					}
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				GameObject orCreatePrefabRoot = GetOrCreatePrefabRoot();
				val = Object.Instantiate<TrashItem>(component, orCreatePrefabRoot.transform, false);
				((Object)val).name = "S1API_Trash_" + id;
				global::S1API.Internal.Utils.ReflectionUtils.Try

Mods/S1API.Il2Cpp.MelonLoader.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using HarmonyLib;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Broadcast;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Managing;
using Il2CppFishNet.Managing.Client;
using Il2CppFishNet.Managing.Object;
using Il2CppFishNet.Managing.Server;
using Il2CppFishNet.Managing.Transporting;
using Il2CppFishNet.Object;
using Il2CppFishNet.Serializing;
using Il2CppFishNet.Transporting;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Avatar;
using Il2CppScheduleOne.Avatar.Player;
using Il2CppScheduleOne.Avatar.Tools;
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.CharacterCreator;
using Il2CppScheduleOne.Clothing;
using Il2CppScheduleOne.Combat;
using Il2CppScheduleOne.Core;
using Il2CppScheduleOne.Core.Avatar;
using Il2CppScheduleOne.Core.Avatar.Properties;
using Il2CppScheduleOne.Core.Equipping.Framework;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.Core.Weather;
using Il2CppScheduleOne.Cutscenes;
using Il2CppScheduleOne.Delivery;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dialogue;
using Il2CppScheduleOne.Doors;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.Effects;
using Il2CppScheduleOne.Effects.MixMaps;
using Il2CppScheduleOne.Employees;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.Equipping.Framework;
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.Framework;
using Il2CppScheduleOne.NPCs.Other;
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.StationFramework;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.TV;
using Il2CppScheduleOne.Temperature;
using Il2CppScheduleOne.Tiles;
using Il2CppScheduleOne.Tools;
using Il2CppScheduleOne.Trash;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Items;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.ContactsApp;
using Il2CppScheduleOne.UI.Phone.Delivery;
using Il2CppScheduleOne.UI.Phone.Map;
using Il2CppScheduleOne.UI.Phone.Messages;
using Il2CppScheduleOne.UI.Phone.ProductManagerApp;
using Il2CppScheduleOne.UI.Relations;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.UI.Stations;
using Il2CppScheduleOne.UI.WorldspacePopup;
using Il2CppScheduleOne.Variables;
using Il2CppScheduleOne.Vehicles;
using Il2CppScheduleOne.Vehicles.Modification;
using Il2CppScheduleOne.Vision;
using Il2CppScheduleOne.VoiceOver;
using Il2CppScheduleOne.Weather;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using S1API;
using S1API.AssetBundles;
using S1API.Avatar;
using S1API.Building;
using S1API.Casino;
using S1API.Conditions;
using S1API.Console;
using S1API.Cutscenes;
using S1API.DeadDrops;
using S1API.Deliveries;
using S1API.Dialogues;
using S1API.Economy;
using S1API.Entities;
using S1API.Entities.Actions;
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.Equippables;
using S1API.Entities.Impostors;
using S1API.Entities.Interfaces;
using S1API.Entities.Relation;
using S1API.Entities.Schedule;
using S1API.Entities.Supplier;
using S1API.Entities.Voices;
using S1API.ExternalHosting;
using S1API.GameTime;
using S1API.Graffiti;
using S1API.Growing;
using S1API.Interaction;
using S1API.Internal;
using S1API.Internal.Abstraction;
using S1API.Internal.Building;
using S1API.Internal.Compatibility;
using S1API.Internal.Console;
using S1API.Internal.Cutscenes;
using S1API.Internal.Deliveries;
using S1API.Internal.Diagnostics;
using S1API.Internal.Entities;
using S1API.Internal.Entities.Suppliers;
using S1API.Internal.Interaction;
using S1API.Internal.Items;
using S1API.Internal.Lifecycle;
using S1API.Internal.Map;
using S1API.Internal.NPCWorkbench;
using S1API.Internal.Patches;
using S1API.Internal.Phone;
using S1API.Internal.Products;
using S1API.Internal.Properties;
using S1API.Internal.Rendering;
using S1API.Internal.Shops;
using S1API.Internal.Temperature;
using S1API.Internal.Utils;
using S1API.Internal.Vehicles;
using S1API.Internal.Weather;
using S1API.Items;
using S1API.Items.Additive;
using S1API.Items.Buildable;
using S1API.Items.Clothing;
using S1API.Items.Quality;
using S1API.Items.Storable;
using S1API.Law;
using S1API.Leveling;
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.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.Stations;
using S1API.Storage;
using S1API.Storages;
using S1API.TVApp;
using S1API.Trash;
using S1API.Utils;
using S1API.Vehicles;
using S1API.Weather;
using UnityEngine;
using UnityEngine.AI;
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: InternalsVisibleTo("S1API.Tests")]
[assembly: InternalsVisibleTo("S1API.CustomProductLifecycleSmoke")]
[assembly: MelonInfo(typeof(global::S1API.S1API), "S1API (Forked by Bars)", "3.2.3", "KaBooMa", null)]
[assembly: MelonPriority(int.MinValue)]
[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("3.2.3.0")]
[assembly: AssemblyInformationalVersion("3.2.3+c81076db53242c4e7df4190c3bb342ba4e627cf8")]
[assembly: AssemblyProduct("S1API")]
[assembly: AssemblyTitle("S1API")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ifBars/S1API")]
[assembly: AssemblyVersion("3.2.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 OnInitializeMelon()
		{
			S1APIPreferences.Initialize();
			MelonPreferences_Entry<bool>? enableUnityNullReferenceTraceLogging = S1APIPreferences.EnableUnityNullReferenceTraceLogging;
			if (enableUnityNullReferenceTraceLogging != null && enableUnityNullReferenceTraceLogging.Value)
			{
				MelonLogger.Warning("Exception trace logging is enabled. If you are not a mod developer, you probably do not need this enabled.");
				UnityExceptionTraceHook.Install();
			}
		}

		public override void OnDeinitializeMelon()
		{
			VehicleSeats.Clear();
			AvatarCompatibility.ResetRendering();
			IconFactory.ResetAccessoryIconState();
			WeatherRuntime.ResetBindings();
			NPCWorkbenchRuntime.Close();
			PresentationWorkbenchRuntime.Close();
			ProductPackagingContentRuntime.ResetForSceneChange();
			CutsceneManager.Deinitialize();
			MapPOIManager.RemoveAll();
			UnityExceptionTraceHook.Remove();
		}

		public override void OnUpdate()
		{
			VehicleSeats.Tick();
			WeatherRuntime.Tick();
			PresentationWorkbenchRuntime.Tick();
			CutsceneManager.Tick(Time.unscaledDeltaTime);
			NPCWorkbenchRuntime.Tick();
		}

		public override void OnGUI()
		{
			CutsceneManager.DrawPresentation();
		}

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

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			VehicleSeats.Clear();
			NPCWorkbenchRuntime.Close();
			PresentationWorkbenchRuntime.Close();
			CutsceneManager.CleanupForSceneChange();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: true);
			if (sceneName == "Main" || sceneName == "Tutorial")
			{
				ProductPackagingContentRuntime.ResetForSceneChange();
				MapPOIManager.ResetForSceneChange();
			}
			if (sceneName == "Main")
			{
				GameLifecycle.Reset();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			NPCNetworkBootstrap.EnsurePrefabsWarmup();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: false);
		}
	}
}
namespace S1API.Weather
{
	public static class WeatherManager
	{
		private static readonly Log Logger = new Log("WeatherManager");

		private static readonly IReadOnlyList<string> EmptySequenceIds = new ReadOnlyCollection<string>(Array.Empty<string>());

		private static WeatherState? _current;

		public static WeatherState? Current => _current;

		public static IReadOnlyList<string> KnownSequenceIds => WeatherRuntime.GetKnownSequenceIds();

		public static event Action<WeatherState>? OnWeatherChanged;

		internal static void NotifyWeatherChanged(WeatherState state)
		{
			if (_current.HasValue && _current.Value.Equals(state))
			{
				return;
			}
			_current = state;
			Action<WeatherState> onWeatherChanged = WeatherManager.OnWeatherChanged;
			if (onWeatherChanged == null)
			{
				return;
			}
			Delegate[] invocationList = onWeatherChanged.GetInvocationList();
			foreach (Delegate obj in invocationList)
			{
				try
				{
					((Action<WeatherState>)obj)(state);
				}
				catch (Exception exception)
				{
					TryLogSubscriberFailure(exception);
				}
			}
		}

		private static void TryLogSubscriberFailure(Exception exception)
		{
			try
			{
				Logger.Warning("A WeatherManager.OnWeatherChanged subscriber failed: " + exception.Message);
			}
			catch
			{
			}
		}

		internal static void ResetState()
		{
			_current = null;
		}

		internal static IReadOnlyList<string> SnapshotSequenceIds(IEnumerable<string?> sequenceIds)
		{
			if (sequenceIds == null)
			{
				return EmptySequenceIds;
			}
			List<string> list = new List<string>();
			foreach (string sequenceId in sequenceIds)
			{
				if (!string.IsNullOrEmpty(sequenceId))
				{
					list.Add(sequenceId);
				}
			}
			IReadOnlyList<string> result;
			if (list.Count != 0)
			{
				IReadOnlyList<string> readOnlyList = new ReadOnlyCollection<string>(list);
				result = readOnlyList;
			}
			else
			{
				result = EmptySequenceIds;
			}
			return result;
		}
	}
	public readonly struct WeatherState : IEquatable<WeatherState>
	{
		public float Sunny { get; }

		public float Cloudy { get; }

		public float Rainy { get; }

		public float Stormy { get; }

		public float Snowy { get; }

		public float Foggy { get; }

		public float Windy { get; }

		public float Hail { get; }

		public float Sleet { get; }

		public WeatherState(float sunny, float cloudy, float rainy, float stormy, float snowy, float foggy, float windy, float hail, float sleet)
		{
			Sunny = sunny;
			Cloudy = cloudy;
			Rainy = rainy;
			Stormy = stormy;
			Snowy = snowy;
			Foggy = foggy;
			Windy = windy;
			Hail = hail;
			Sleet = sleet;
		}

		internal static WeatherState FromNativeComponents(float sunny, float cloudy, float rainy, float stormy, float snowy, float foggy, float windy, float hail, float sleet)
		{
			return new WeatherState(sunny, cloudy, rainy, stormy, snowy, foggy, windy, hail, sleet);
		}

		public bool Equals(WeatherState other)
		{
			return Sunny.Equals(other.Sunny) && Cloudy.Equals(other.Cloudy) && Rainy.Equals(other.Rainy) && Stormy.Equals(other.Stormy) && Snowy.Equals(other.Snowy) && Foggy.Equals(other.Foggy) && Windy.Equals(other.Windy) && Hail.Equals(other.Hail) && Sleet.Equals(other.Sleet);
		}

		public override bool Equals(object? obj)
		{
			return obj is WeatherState other && Equals(other);
		}

		public override int GetHashCode()
		{
			int hashCode = Sunny.GetHashCode();
			hashCode = (hashCode * 397) ^ Cloudy.GetHashCode();
			hashCode = (hashCode * 397) ^ Rainy.GetHashCode();
			hashCode = (hashCode * 397) ^ Stormy.GetHashCode();
			hashCode = (hashCode * 397) ^ Snowy.GetHashCode();
			hashCode = (hashCode * 397) ^ Foggy.GetHashCode();
			hashCode = (hashCode * 397) ^ Windy.GetHashCode();
			hashCode = (hashCode * 397) ^ Hail.GetHashCode();
			return (hashCode * 397) ^ Sleet.GetHashCode();
		}

		public static bool operator ==(WeatherState left, WeatherState right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(WeatherState left, WeatherState right)
		{
			return !left.Equals(right);
		}
	}
}
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 NetworkConnection? _conn;

		private string _guid = string.Empty;

		public IReadOnlyList<VehicleSeatInfo> Seats => VehicleSeats.Get(S1LandVehicle);

		public float VehiclePrice
		{
			get
			{
				return S1LandVehicle.VehiclePrice;
			}
			set
			{
				global::S1API.Internal.Utils.ReflectionUtils.TrySetFieldOrProperty(S1LandVehicle, "vehiclePrice", 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 = ((object)(Guid)(property.GetValue(S1LandVehicle) ?? ((object)default(Guid)))/*cast due to .constrained prefix*/).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 VehicleColorCatalog
	{
		private static readonly IReadOnlyList<VehicleColorMetadata> EmptyColors = new ReadOnlyCollection<VehicleColorMetadata>(Array.Empty<VehicleColorMetadata>());

		private static IVehicleColorMetadataProvider _provider = new NativeVehicleColorMetadataProvider();

		public static IReadOnlyList<VehicleColorMetadata> Colors => GetColors();

		public static VehicleColorMetadata? GetColor(VehicleColor color)
		{
			TryGetColor(color, out VehicleColorMetadata metadata);
			return metadata;
		}

		public static bool TryGetColor(VehicleColor color, out VehicleColorMetadata? metadata)
		{
			if (!Enum.IsDefined(typeof(VehicleColor), color))
			{
				metadata = null;
				return false;
			}
			return _provider.TryGetColor(color, out metadata);
		}

		internal static void ResetForTesting(IVehicleColorMetadataProvider provider)
		{
			_provider = provider ?? throw new ArgumentNullException("provider");
		}

		internal static void RestoreProviderForTesting()
		{
			_provider = new NativeVehicleColorMetadataProvider();
		}

		private static IReadOnlyList<VehicleColorMetadata> GetColors()
		{
			if (!_provider.TryGetColors(out IReadOnlyList<VehicleColorMetadata> metadata) || metadata == null || metadata.Count == 0)
			{
				return EmptyColors;
			}
			return new ReadOnlyCollection<VehicleColorMetadata>(new List<VehicleColorMetadata>(metadata));
		}
	}
	internal interface IVehicleColorMetadataProvider
	{
		bool TryGetColors(out IReadOnlyList<VehicleColorMetadata>? metadata);

		bool TryGetColor(VehicleColor color, out VehicleColorMetadata? metadata);
	}
	internal sealed class NativeVehicleColorMetadataProvider : IVehicleColorMetadataProvider
	{
		public bool TryGetColors(out IReadOnlyList<VehicleColorMetadata>? metadata)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected I4, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			metadata = null;
			try
			{
				if (!Singleton<VehicleColors>.InstanceExists)
				{
					return false;
				}
				VehicleColors instance = Singleton<VehicleColors>.Instance;
				if (instance.colorLibrary == null)
				{
					return false;
				}
				List<VehicleColorMetadata> list = new List<VehicleColorMetadata>(instance.colorLibrary.Count);
				for (int i = 0; i < instance.colorLibrary.Count; i++)
				{
					VehicleColorData val = instance.colorLibrary[i];
					if (val != null)
					{
						VehicleColor vehicleColor = (VehicleColor)val.color;
						if (Enum.IsDefined(typeof(VehicleColor), vehicleColor))
						{
							list.Add(new VehicleColorMetadata(vehicleColor, val.colorName, val.MaterialColor, val.UIColor));
						}
					}
				}
				if (list.Count == 0)
				{
					return false;
				}
				metadata = new ReadOnlyCollection<VehicleColorMetadata>(list);
				return true;
			}
			catch
			{
				return false;
			}
		}

		public bool TryGetColor(VehicleColor color, out VehicleColorMetadata? metadata)
		{
			metadata = null;
			if (!TryGetColors(out IReadOnlyList<VehicleColorMetadata> metadata2) || metadata2 == null)
			{
				return false;
			}
			for (int i = 0; i < metadata2.Count; i++)
			{
				VehicleColorMetadata vehicleColorMetadata = metadata2[i];
				if (vehicleColorMetadata.Color == color)
				{
					metadata = vehicleColorMetadata;
					return true;
				}
			}
			return false;
		}
	}
	public sealed class VehicleColorMetadata
	{
		public VehicleColor Color { get; }

		public string? DisplayName { get; }

		public Color MaterialColor { get; }

		public Color32 UIColor { get; }

		internal VehicleColorMetadata(VehicleColor color, string? displayName, Color materialColor, Color32 uiColor)
		{
			//IL_0017: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Color = color;
			DisplayName = displayName;
			MaterialColor = materialColor;
			UIColor = uiColor;
		}
	}
	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 val2 = GUIDManager.GetObject<LandVehicle>(val);
				if ((Object)(object)val2 == (Object)null)
				{
					return null;
				}
				return Wrap(val2);
			}
			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);
			}
		}

		internal 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;
		}
	}
	public sealed class VehicleSeatInfo
	{
		private VehicleSeat? _seat;

		private Player? _observedOccupant;

		private Player? _observedPlayer;

		public int Index { get; }

		public bool IsDriverSeat { get; }

		public bool IsOccupied => ReadOccupant() != null;

		public Player? Occupant => ResolvePlayer(ReadOccupant());

		public event Action<Player?, Player?>? OccupantChanged;

		internal VehicleSeatInfo(int index, VehicleSeat? seat)
		{
			Index = index;
			_seat = seat;
			IsDriverSeat = seat != null && (Object)(object)seat != (Object)null && seat.isDriverSeat;
			_observedOccupant = ReadOccupant();
			_observedPlayer = ResolvePlayer(_observedOccupant);
		}

		internal void Refresh()
		{
			Player val = ReadOccupant();
			Player player = ResolvePlayer(val);
			if (SameIdentity(_observedOccupant, val))
			{
				_observedPlayer = player;
				return;
			}
			Player previous = _observedPlayer ?? ResolvePlayer(_observedOccupant);
			_observedOccupant = val;
			_observedPlayer = player;
			NotifyOccupantChanged(previous, player);
		}

		internal void Invalidate()
		{
			_seat = null;
			_observedOccupant = null;
			_observedPlayer = null;
			this.OccupantChanged = null;
		}

		internal void NotifyOccupantChanged(Player? previous, Player? current)
		{
			Action<Player, Player> action = this.OccupantChanged;
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action<Player, Player> action2 = (Action<Player, Player>)invocationList[i];
				try
				{
					action2(previous, current);
				}
				catch (Exception ex)
				{
					try
					{
						new Log("VehicleSeatInfo").Warning("An OccupantChanged subscriber failed: " + ex.Message);
					}
					catch
					{
					}
				}
			}
		}

		private Player? ReadOccupant()
		{
			if (_seat == null || (Object)(object)_seat == (Object)null)
			{
				return null;
			}
			Player occupant = _seat.Occupant;
			return (occupant == null || (Object)(object)occupant == (Object)null) ? null : occupant;
		}

		private static bool SameIdentity(Player? left, Player? right)
		{
			return ((left != null) ? ((Il2CppObjectBase)left).Pointer : IntPtr.Zero) == ((right != null) ? ((Il2CppObjectBase)right).Pointer : IntPtr.Zero);
		}

		private static Player? ResolvePlayer(Player? native)
		{
			if (native == null)
			{
				return null;
			}
			foreach (Player item in Player.All)
			{
				if (SameIdentity(item.S1Player, native))
				{
					return item;
				}
			}
			return null;
		}
	}
}
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.ToColorInternal(hexColor);
		}
	}
	public static class EventHelper
	{
		internal static void AddListener(Action listener, Action<Action> subscribe)
		{
			global::S1API.Internal.Abstraction.EventHelper.AddListener(listener, subscribe);
		}

		internal static void RemoveListener(Action listener, Action<Action> unsubscribe)
		{
			global::S1API.Internal.Abstraction.EventHelper.RemoveListener(listener, unsubscribe);
		}

		public static void AddListener(Action listener, UnityEvent unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.AddListener(listener, unityEvent);
		}

		public static void RemoveListener(Action listener, UnityEvent unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.RemoveListener(listener, unityEvent);
		}

		public static void AddListener<T>(Action<T> listener, UnityEvent<T> unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.AddListener(listener, unityEvent);
		}

		public static void RemoveListener<T>(Action<T> listener, UnityEvent<T> unityEvent)
		{
			global::S1API.Internal.Abstraction.EventHelper.RemoveListener(listener, unityEvent);
		}

		public static void AddEventTrigger(EventTrigger trigger, EventTriggerType eventType, Action listener)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Abstraction.EventHelper.AddEventTrigger(trigger, eventType, listener);
		}

		public static void AddEventTrigger(EventTrigger trigger, EventTriggerType eventType, Action<BaseEventData> listener)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Abstraction.EventHelper.AddEventTrigger(trigger, eventType, listener);
		}

		public static void RemoveEventTrigger(EventTrigger trigger, EventTriggerType eventType, Action<BaseEventData> listener)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			global::S1API.Internal.Abstraction.EventHelper.RemoveEventTrigger(trigger, eventType, listener);
		}
	}
	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 = (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);
		}
	}
	public static class TransformUtils
	{
		public static Transform? FindDescendant(Transform root, string name)
		{
			return global::S1API.Internal.Utils.TransformUtils.FindDescendant(root, name);
		}
	}
}
namespace S1API.UI
{
	public static class CharacterCreatorManager
	{
		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();
				if ((Object)(object)_s1Creator == (Object)null || !_s1Creator.IsOpen)
				{
					return null;
				}
				object? obj = global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(_s1Creator, "_currentState");
				CharacterCreatorState val = (CharacterCreatorState)((obj is CharacterCreatorState) ? obj : null);
				return (((val != null) ? val.Appearance : null) == null) ? null : BasicAvatarSettings.FromPlayerAppearance(val.Appearance);
			}
		}

		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 || !showUI)
			{
				Logger.Warning("Schedule I 0.4.7 no longer accepts legacy initial settings or a hidden character-creator canvas; opening the native creator with its defaults.");
			}
			_s1Creator.Open();
			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;
			}
			typeof(CharacterCreator).GetMethod("Close", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(_s1Creator, null);
			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
			{
				Logger.Warning("Character-creator presets are not available in Schedule I 0.4.7.");
			}
		}

		public static string[] GetAvailablePresets()
		{
			EnsureInitialized();
			return Array.Empty<string>();
		}

		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.SetAvatarRotation(Mathf.Clamp01(normalizedValue) * 359f);
			}
		}

		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
			{
				_s1Creator.OnComplete += Action<CharacterCreatorState>.op_Implicit((Action<CharacterCreatorState>)OnCreatorCompleted);
				_eventsRegistered = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to register CharacterCreator events: {value}");
			}
		}

		private static void OnCreatorCompleted(CharacterCreatorState state)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected I4, but got Unknown
			//IL_005c: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (((state != null) ? state.Appearance : null) == null)
				{
					Logger.Warning("CharacterCreator completed with null settings");
					return;
				}
				BasicAvatarSettings basicAvatarSettings = BasicAvatarSettings.Create();
				basicAvatarSettings.Gender = (int)state.Appearance.Gender;
				basicAvatarSettings.Weight = state.Appearance.Weight;
				basicAvatarSettings.SkinColor = state.Appearance.SkinColor;
				basicAvatarSettings.HairStyle = state.Appearance.HairStyleId ?? string.Empty;
				basicAvatarSettings.HairColor = state.Appearance.HairColor;
				basicAvatarSettings.Mouth = state.Appearance.FaceId ?? string.Empty;
				basicAvatarSettings.FacialHair = state.Appearance.FacialHairId ?? string.Empty;
				basicAvatarSettings.FacialDetails = state.Appearance.FacialDetailId ?? string.Empty;
				basicAvatarSettings.FacialDetailsIntensity = state.Appearance.FacialDetailIntensity;
				basicAvatarSettings.EyeballColor = state.Appearance.EyeballColor;
				basicAvatarSettings.PupilDilation = state.Appearance.PupilDilation;
				basicAvatarSettings.UpperEyeLidRestingPosition = state.Appearance.UpperEyelidPosition;
				basicAvatarSettings.LowerEyeLidRestingPosition = state.Appearance.LowerEyelidPosition;
				basicAvatarSettings.EyebrowScale = state.Appearance.EyebrowScale;
				basicAvatarSettings.EyebrowThickness = state.Appearance.EyebrowThickness;
				basicAvatarSettings.EyebrowRestingHeight = state.Appearance.EyebrowHeight;
				basicAvatarSettings.EyebrowRestingAngle = state.Appearance.EyebrowAngle;
				MelonCoroutines.Start(RestoreGameState());
				CharacterCreatorManager.OnCompleted?.Invoke(basicAvatarSettings);
			}
			catch (Exception value)
			{
				Logger.Error($"Error in OnCompleted event handler: {value}");
			}
		}

		private static IEnumerator RestoreAfterClose()
		{
			yield return RestoreGameState();
		}

		private static IEnumerator RestoreGameState()
		{
			yield return null;
			yield return (object)new WaitForSeconds(0.1f);
			if (PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerCamera camera = PlayerSingleton<PlayerCamera>.Instance;
				CharacterCreator? s1Creator = _s1Creator;
				camera.RemoveActiveUIElement(((s1Creator != null) ? ((Object)s1Creator).name : null) ?? "CharacterCreator");
				if (GetActiveUIElementCount(camera) == 0)
				{
					camera.StopTransformOverride(0f, true, false);
					camera.StopFOVOverride(0f);
					camera.SetCanLook(true);
					camera.LockMouse(true);
				}
			}
			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;
			}
		}

		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 currentBasicAvatarSettings = local.GetCurrentBasicAvatarSettings();
				if (currentBasicAvatarSettings == null)
				{
					Logger.Debug("Player has no current avatar settings, using default");
					return null;
				}
				BasicAvatarSettings settings = Object.Instantiate<BasicAvatarSettings>(currentBasicAvatarSettings.S1BasicAvatarSettings);
				return new BasicAvatarSettings(settings);
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to get player avatar settings: {value}");
				return null;
			}
		}

		private static int GetActiveUIElementCount(PlayerCamera camera)
		{
			if ((Object)(object)camera == (Object)null)
			{
				return 0;
			}
			if (global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(camera, "ActiveUIElementCount") is int result)
			{
				return result;
			}
			return 0;
		}
	}
	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 = (TextAnchor)0, FontStyle style = (FontStyle)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 = (TextAnchor)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(Width, Height);
			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 = (TextAnchor)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.TVApp
{
	public abstract class TVApp : Registerable
	{
		protected static readonly Log Logger = new Log("TVApp");

		private GameObject? _appRoot;

		private Canvas? _canvas;

		private CanvasGroup? _canvasGroup;

		private GameObject? _container;

		private TVHomeScreen? _homeScreen;

		private ExitDelegate? _exitDelegate;

		private bool _isOpen;

		private bool _isPaused;

		private bool _uiCreated;

		protected abstract string AppName { get; }

		protected abstract string AppTitle { get; }

		protected abstract Sprite Icon { get; }

		public bool IsOpen => _isOpen;

		public bool IsPaused => _isPaused;

		protected abstract void OnCreatedUI(GameObject container);

		protected virtual void OnUpdate()
		{
		}

		protected virtual void OnOpened()
		{
		}

		protected virtual void OnClosed()
		{
		}

		protected virtual void OnPaused()
		{
		}

		protected virtual void OnResumed()
		{
		}

		public void Open()
		{
			if (_isOpen)
			{
				return;
			}
			try
			{
				_isOpen = true;
				_isPaused = false;
				if ((Object)(object)_appRoot != (Object)null)
				{
					_appRoot.SetActive(true);
				}
				if ((Object)(object)_canvasGroup != (Object)null)
				{
					_canvasGroup.alpha = 1f;
				}
				if ((Object)(object)_container != (Object)null)
				{
					_container.SetActive(true);
				}
				OnOpened();
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to open TV app " + AppName + ": " + ex.Message);
			}
		}

		public void Close()
		{
			if (!_isOpen)
			{
				return;
			}
			try
			{
				_isOpen = false;
				_isPaused = false;
				if ((Object)(object)_canvasGroup != (Object)null)
				{
					_canvasGroup.alpha = 0f;
				}
				if ((Object)(object)_container != (Object)null)
				{
					_container.SetActive(false);
				}
				if ((Object)(object)_appRoot != (Object)null)
				{
					_appRoot.SetActive(false);
				}
				OnClosed();
				TVHomeScreen? homeScreen = _homeScreen;
				if (homeScreen != null)
				{
					((TVApp)homeScreen).Open();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to close TV app " + AppName + ": " + ex.Message);
			}
		}

		internal void ForceClose()
		{
			if (!_isOpen)
			{
				return;
			}
			try
			{
				_isOpen = false;
				_isPaused = false;
				if ((Object)(object)_canvasGroup != (Object)null)
				{
					_canvasGroup.alpha = 0f;
				}
				if ((Object)(object)_container != (Object)null)
				{
					_container.SetActive(false);
				}
				if ((Object)(object)_appRoot != (Object)null)
				{
					_appRoot.SetActive(false);
				}
				OnClosed();
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to force close TV app " + AppName + ": " + ex.Message);
			}
		}

		public void Pause()
		{
			if (_isOpen && !_isPaused)
			{
				_isPaused = true;
				OnPaused();
			}
		}

		public void Resume()
		{
			if (_isOpen && _isPaused)
			{
				_isPaused = false;
				OnResumed();
			}
		}

		protected override void OnCreated()
		{
			TVAppRegistry.Register(this);
			ExternalAppCatalog.Register(ExternalAppFamily.TV, this, () => AppName, () => AppTitle, () => Icon);
		}

		protected override void OnDestroyed()
		{
			ExternalAppCatalog.Unregister(this);
			if ((Delegate)(object)_exitDelegate != (Delegate)null)
			{
				GameInput.DeregisterExitListener(_exitDelegate);
				_exitDelegate = null;
			}
			if ((Object)(object)_appRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_appRoot);
				_appRoot = null;
			}
			_canvas = null;
			_canvasGroup = null;
			_container = null;
			_homeScreen = null;
			_uiCreated = false;
			_isOpen = false;
			_isPaused = false;
		}

		internal void SpawnUI(TVHomeScreen homeScreen)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			if (_uiCreated)
			{
				return;
			}
			_homeScreen = homeScreen;
			Transform parent = ((Component)homeScreen).transform.parent;
			if ((Object)(object)parent == (Object)null)
			{
				Logger.Error("Cannot find parent transform for TV app: " + AppName);
				return;
			}
			_appRoot = new GameObject(AppName + "_TVApp");
			_appRoot.transform.SetParent(parent, false);
			TVApp[] array = Il2CppArrayBase<TVApp>.op_Implicit((Il2CppArrayBase<TVApp>)(object)homeScreen.Apps);
			if (array != null && array.Length != 0 && (Object)(object)array[0].Canvas != (Object)null)
			{
				Transform transform = ((Component)array[0].Canvas).transform;
				_appRoot.transform.localPosition = transform.localPosition;
				_appRoot.transform.localRotation = transform.localRotation;
				_appRoot.transform.localScale = transform.localScale;
			}
			_canvas = _appRoot.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)2;
			if (array != null && array.Length != 0 && (Object)(object)array[0].Canvas != (Object)null)
			{
				Canvas canvas = array[0].Canvas;
				_canvas.sortingOrder = canvas.sortingOrder;
				_canvas.worldCamera = canvas.worldCamera;
				_appRoot.layer = ((Component)array[0].Canvas).gameObject.layer;
				RectTransform component = ((Component)canvas).GetComponent<RectTransform>();
				RectTransform component2 = _appRoot.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
				{
					component2.sizeDelta = component.sizeDelta;
				}
			}
			_canvasGroup = _appRoot.AddComponent<CanvasGroup>();
			_canvasGroup.alpha = 0f;
			_canvasGroup.interactable = true;
			_canvasGroup.blocksRaycasts = true;
			_appRoot.AddComponent<GraphicRaycaster>();
			_container = new GameObject("Container");
			_container.transform.SetParent(_appRoot.transform, false);
			RectTransform val = _container.AddComponent<RectTransform>();
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			val.offsetMin = Vector2.zero;
			val.offsetMax = Vector2.zero;
			OnCreatedUI(_container);
			TVAppUpdateHandler tVAppUpdateHandler = _appRoot.AddComponent<TVAppUpdateHandler>();
			tVAppUpdateHandler.tvApp = this;
			_exitDelegate = DelegateSupport.ConvertDelegate<ExitDelegate>((Delegate)new Action<ExitAction>(HandleExit));
			GameInput.RegisterExitListener(_exitDelegate, 3);
			_appRoot.SetActive(false);
			_uiCreated = true;
		}

		internal void SpawnButton(TVHomeScreen homeScreen)
		{
			if ((Object)(object)homeScreen.AppButtonPrefab == (Object)null || (Object)(object)homeScreen.AppButtonContainer == (Object)null)
			{
				Logger.Error("Cannot create button for TV app " + AppName + ": missing prefab or container");
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(homeScreen.AppButtonPrefab, (Transform)(object)homeScreen.AppButtonContainer);
			((Object)val).name = "Button_" + AppName;
			Transform val2 = val.transform.Find("Icon");
			if ((Object)(object)val2 != (Object)null)
			{
				Image component = ((Component)val2).GetComponent<Image>();
				if ((Object)(object)component != (Object)null && (Object)(object)Icon != (Object)null)
				{
					component.sprite = Icon;
				}
			}
			Transform val3 = val.transform.Find("Name");
			if ((Object)(object)val3 != (Object)null)
			{
				TextMeshProUGUI component2 = ((Component)val3).GetComponent<TextMeshProUGUI>();
				if ((Object)(object)component2 != (Object)null)
				{
					((TMP_Text)component2).text = AppTitle;
				}
			}
			Button component3 = val.GetComponent<Button>();
			if ((Object)(object)component3 != (Object)null)
			{
				((UnityEventBase)component3.onClick).RemoveAllListeners();
				global::S1API.Utils.EventHelper.AddListener(OnButtonClicked, (UnityEvent)(object)component3.onClick);
			}
		}

		internal void InvokeUpdate()
		{
			if (_isOpen && !_isPaused)
			{
				OnUpdate();
			}
		}

		private void OnButtonClicked()
		{
			if ((Object)(object)_homeScreen == (Object)null)
			{
				return;
			}
			try
			{
				TVHomeScreen_Close_Patch.SkipInterfaceClose = true;
				((TVApp)_homeScreen).Close();
				Open();
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to open TV app " + AppName + ": " + ex.Message);
			}
		}

		private void HandleExit(ExitAction exit)
		{
			if (!exit.Used && _isOpen)
			{
				exit.Used = true;
				Close();
			}
		}
	}
	[RegisterTypeInIl2Cpp]
	internal class TVAppUpdateHandler : MonoBehaviour
	{
		internal TVApp? tvApp;

		private void Update()
		{
			if (tvApp != null)
			{
				tvApp.InvokeUpdate();
			}
		}
	}
}
namespace S1API.Trash
{
	public sealed class Recycler
	{
		private readonly UnityEvent? _onStart;

		private readonly UnityEvent? _onStop;

		private readonly UnityAction _startListener;

		private readonly UnityAction _stopListener;

		private bool _listening;

		internal readonly Recycler S1Recycler;

		public RecyclerState State => (RecyclerState)S1Recycler.State;

		public bool IsHatchOpen => S1Recycler.IsHatchOpen;

		public Vector3 Position => ((Component)S1Recycler).transform.position;

		public GameObject GameObject => ((Component)S1Recycler).gameObject;

		internal Recycler(Recycler recycler)
		{
			S1Recycler = recycler;
			_onStart = recycler.onStart;
			_onStop = recycler.onStop;
			_startListener = UnityAction.op_Implicit((Action)NotifyProcessingStarted);
			_stopListener = UnityAction.op_Implicit((Action)NotifyProcessingStopped);
			try
			{
				if (_onStart != null)
				{
					_onStart.AddListener(_startListener);
				}
				if (_onStop != null)
				{
					_onStop.AddListener(_stopListener);
				}
				_listening = true;
			}
			catch
			{
				Cleanup();
				throw;
			}
		}

		internal void Cleanup()
		{
			_listening = false;
			if (_onStart != null)
			{
				_onStart.RemoveListener(_startListener);
			}
			if (_onStop != null)
			{
				_onStop.RemoveListener(_stopListener);
			}
		}

		private void NotifyProcessingStarted()
		{
			if (_listening)
			{
				RecyclerRegistry.NotifyProcessingStarted(this);
			}
		}

		private void NotifyProcessingStopped()
		{
			if (_listening)
			{
				RecyclerRegistry.NotifyProcessingStopped(this);
			}
		}
	}
	public static class RecyclerRegistry
	{
		private static readonly Log Logger = new Log("RecyclerRegistry");

		private static readonly Dictionary<int, Recycler> Recyclers = new Dictionary<int, Recycler>();

		private static bool _lifecycleHooked;

		public static event Action<Recycler>? ProcessingStarted;

		public static event Action<Recycler>? ProcessingStopped;

		public static IReadOnlyList<Recycler> GetAll()
		{
			EnsureLifecycleHook();
			PruneDestroyedRecyclers();
			Il2CppArrayBase<Recycler> val = Object.FindObjectsOfType<Recycler>();
			List<Recycler> list = new List<Recycler>(val.Length);
			for (int i = 0; i < val.Length; i++)
			{
				Recycler val2 = val[i];
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(Wrap(val2));
				}
			}
			return new ReadOnlyCollection<Recycler>(list);
		}

		internal static Recycler Wrap(Recycler native)
		{
			EnsureLifecycleHook();
			int instanceID = ((Object)native).GetInstanceID();
			if (Recyclers.TryGetValue(instanceID, out Recycler value))
			{
				if ((Object)(object)value.S1Recycler != (Object)null)
				{
					return value;
				}
				value.Cleanup();
				Recyclers.Remove(instanceID);
			}
			value = new Recycler(native);
			Recyclers.Add(instanceID, value);
			return value;
		}

		internal static void Remove(Recycler native)
		{
			int instanceID = ((Object)native).GetInstanceID();
			if (Recyclers.TryGetValue(instanceID, out Recycler value))
			{
				value.Cleanup();
				Recyclers.Remove(instanceID);
			}
		}

		internal static void NotifyProcessingStarted(Recycler recycler)
		{
			Invoke(RecyclerRegistry.ProcessingStarted, recycler, "ProcessingStarted");
		}

		internal static void NotifyProcessingStopped(Recycler recycler)
		{
			Invoke(RecyclerRegistry.ProcessingStopped, recycler, "ProcessingStopped");
		}

		private static void Invoke(Action<Recycler>? handlers, Recycler recycler, string eventName)
		{
			if (handlers == null)
			{
				return;
			}
			Delegate[] invocationList = handlers.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action<Recycler> action = (Action<Recycler>)invocationList[i];
				try
				{
					action(recycler);
				}
				catch (Exception ex)
				{
					Logger.Warning("A RecyclerRegistry." + eventName + " subscriber failed: " + ex.Message);
				}
			}
		}

		private static void EnsureLifecycleHook()
		{
			if (!_lifecycleHooked)
			{
				GameLifecycle.OnPreSceneChange += ClearSceneState;
				_lifecycleHooked = true;
			}
		}

		private static void PruneDestroyedRecyclers()
		{
			List<int> list = null;
			foreach (KeyValuePair<int, Recycler> recycler in Recyclers)
			{
				if (!((Object)(object)recycler.Value.S1Recycler != (Object)null))
				{
					recycler.Value.Cleanup();
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(recycler.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				Recyclers.Remove(item);
			}
		}

		private static void ClearSceneState()
		{
			foreach (Recycler value in Recyclers.Values)
			{
				value.Cleanup();
			}
			Recyclers.Clear();
		}
	}
	public enum RecyclerState
	{
		HatchClosed,
		HatchOpen,
		Processing
	}
	public sealed class TrashContainer
	{
		private abstract class TrashContainerRegistrationState
		{
			internal TrashContainer S1TrashContainer { get; }

			protected TrashContainerRegistrationState(TrashContainer trashContainer)
			{
				S1TrashContainer = trashContainer;
			}
		}

		private sealed class TrashAddedRegistrationState : TrashContainerRegistrationState
		{
			internal ManagedEventRegistrationTracker<UnityAction<string>> Registrations { get; } = new ManagedEventRegistrationTracker<UnityAction<string>>();

			internal TrashAddedRegistrationState(TrashContainer trashContainer)
				: base(trashContainer)
			{
			}
		}

		private sealed class TrashLevelChangedRegistrationState : TrashContainerRegistrationState
		{
			internal ManagedEventRegistrationTracker<UnityAction> Registrations { get; } = new ManagedEventRegistrationTracker<UnityAction>();

			internal TrashLevelChangedRegistrationState(TrashContainer trashContainer)
				: base(trashContainer)
			{
			}
		}

		private static readonly Dictionary<int, TrashAddedRegistrationState> TrashAddedRegistrations = new Dictionary<int, TrashAddedRegistrationState>();

		private static readonly Dictionary<int, TrashLevelChangedRegistrationState> TrashLevelChangedRegistrations = new Dictionary<int, TrashLevelChangedRegistrationState>();

		internal readonly TrashContainer S1TrashContainer;

		public GameObject? GameObject
		{
			get
			{
				TrashContainer s1TrashContainer = S1TrashContainer;
				return (s1TrashContainer != null) ? ((Component)s1TrashContainer).gameObject : null;
			}
		}

		public int Capacity => S1TrashContainer.TrashCapacity;

		public int Level => S1TrashContainer.TrashLevel;

		public float NormalizedLevel => S1TrashContainer.NormalizedTrashLevel;

		public IReadOnlyList<TrashContentEntry> Contents
		{
			get
			{
				TrashContent content = S1TrashContainer.Content;
				List<Entry> val = ((content != null) ? content.Entries : null);
				if (val == null || val.Count == 0)
				{
					return Array.Empty<TrashContentEntry>();
				}
				List<TrashContentEntry> list = new List<TrashContentEntry>(val.Count);
				for (int i = 0; i < val.Count; i++)
				{
					Entry val2 = val[i];
					if (val2 != null)
					{
						list.Add(new TrashContentEntry(val2.TrashID, val2.Quantity, val2.UnitSize, val2.UnitValue));
					}
				}
				return list.AsReadOnly();
			}
		}

		public bool CanBeBagged => S1TrashContainer.CanBeBagged();

		public event Action<string> OnTrashAdded
		{
			add
			{
				if (value != null)
				{
					UnityAction<string> val = CreateNativeTrashAddedHandler(value);
					SubscribeTrashAdded(val);
					GetTrashAddedRegistrationState().Registrations.Add(value, val);
				}
			}
			remove
			{
				if (value != null && TryTakeTrashAddedRegistration(value, out TrashAddedRegistrationState state, out UnityAction<string> nativeHandler))
				{
					try
					{
						UnsubscribeTrashAdded(nativeHandler);
					}
					catch
					{
						state.Registrations.Add(value, nativeHandler);
						throw;
					}
					if (state.Registrations.IsEmpty)
					{
						TrashAddedRegistrations.Remove(((Object)S1TrashContainer).GetInstanceID());
					}
				}
			}
		}

		public event Action OnTrashLevelChanged
		{
			add
			{
				if (value != null)
				{
					UnityAction val = CreateNativeTrashLevelChangedHandler(value);
					SubscribeTrashLevelChanged(val);
					GetTrashLevelChangedRegistrationState().Registrations.Add(value, val);
				}
			}
			remove
			{
				if (value != null && TryTakeTrashLevelChangedRegistration(value, out TrashLevelChangedRegistrationState state, out UnityAction nativeHandler))
				{
					try
					{
						UnsubscribeTrashLevelChanged(nativeHandler);
					}
					catch
					{
						state.Registrations.Add(value, nativeHandler);
						throw;
					}
					if (state.Registrations.IsEmpty)
					{
						TrashLevelChangedRegistrations.Remove(((Object)S1TrashContainer).GetInstanceID());
					}
				}
			}
		}

		internal TrashContainer(TrashContainer trashContainer)
		{
			S1TrashContainer = trashContainer;
		}

		public static TrashContainer? FromGameObject(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				throw new ArgumentNullException("gameObject");
			}
			PruneDestroyedRegistrationStates();
			TrashContainer component = gameObject.GetComponent<TrashContainer>();
			return ((Object)(object)component == (Object)null) ? null : new TrashContainer(component);
		}

		public static TrashContainer[] FindInScene(bool includeInactive = false)
		{
			PruneDestroyedRegistrationStates();
			Il2CppArrayBase<TrashContainer> val = Object.FindObjectsOfType<TrashContainer>(includeInactive);
			if (val == null || val.Length == 0)
			{
				return Array.Empty<TrashContainer>();
			}
			List<TrashContainer> list = new List<TrashContainer>(val.Length);
			for (int i = 0; i < val.Length; i++)
			{
				TrashContainer val2 = val[i];
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(new TrashContainer(val2));
				}
			}
			return list.ToArray();
		}

		public bool TryBagTrash()
		{
			if (!InstanceFinder.IsServer || !S1TrashContainer.CanBeBagged())
			{
				return false;
			}
			S1TrashContainer.BagTrash();
			return true;
		}

		private static UnityAction<string> CreateNativeTrashAddedHandler(Action<string> handler)
		{
			return DelegateSupport.ConvertDelegate<UnityAction<string>>((Delegate)handler) ?? throw new InvalidOperationException("Could not create the native trash-added delegate.");
		}

		private static UnityAction CreateNativeTrashLevelChangedHandler(Action handler)
		{
			return DelegateSupport.ConvertDelegate<UnityAction>((Delegate)handler) ?? throw new InvalidOperationException("Could not create the native trash-level delegate.");
		}

		private void SubscribeTrashAdded(UnityAction<string> handler)
		{
			S1TrashContainer.onTrashAdded.AddListener(handler);
		}

		private void UnsubscribeTrashAdded(UnityAction<string> handler)
		{
			S1TrashContainer.onTrashAdded.RemoveListener(handler);
		}

		private void SubscribeTrashLevelChanged(UnityAction handler)
		{
			S1TrashContainer.onTrashLevelChanged.AddListener(handler);
		}

		private void UnsubscribeTrashLevelChanged(UnityAction handler)
		{
			S1TrashContainer.onTrashLevelChanged.RemoveListener(handler);
		}

		private TrashAddedRegistrationState GetTrashAddedRegistrationState()
		{
			PruneDestroyedRegistrationStates();
			int instanceID = ((Object)S1TrashContainer).GetInstanceID();
			if (TrashAddedRegistrations.TryGetValue(instanceID, out TrashAddedRegistrationState value))
			{
				return value;
			}
			value = new TrashAddedRegistrationState(S1TrashContainer);
			TrashAddedRegistrations.Add(instanceID, value);
			return value;
		}

		private bool TryTakeTrashAddedRegistration(Action<string> managedHandler, out TrashAddedRegistrationState state, out UnityAction<string> nativeHandler)
		{
			PruneDestroyedRegistrationStates();
			if (TrashAddedRegistrations.TryGetValue(((Object)S1TrashContainer).GetInstanceID(), out TrashAddedRegistrationState value) && value.Registrations.TryTakeLast(managedHandler, out nativeHandler))
			{
				state = value;
				return true;
			}
			state = null;
			nativeHandler = null;
			return false;
		}

		private TrashLevelChangedRegistrationState GetTrashLevelChangedRegistrationState()
		{
			PruneDestroyedRegistrationStates();
			int instanceID = ((Object)S1TrashContainer).GetInstanceID();
			if (TrashLevelChangedRegistrations.TryGetValue(instanceID, out TrashLevelChangedRegistrationState value))
			{
				return value;
			}
			value = new TrashLevelChangedRegistrationState(S1TrashContainer);
			TrashLevelChangedRegistrations.Add(instanceID, value);
			return value;
		}

		private bool TryTakeTrashLevelChangedRegistration(Action managedHandler, out TrashLevelChangedRegistrationState state, out UnityAction nativeHandler)
		{
			PruneDestroyedRegistrationStates();
			if (TrashLevelChangedRegistrations.TryGetValue(((Object)S1TrashContainer).GetInstanceID(), out TrashLevelChangedRegistrationState value) && value.Registrations.TryTakeLast(managedHandler, out nativeHandler))
			{
				state = value;
				return true;
			}
			state = null;
			nativeHandler = null;
			return false;
		}

		private static void PruneDestroyedRegistrationStates()
		{
			PruneDestroyedRegistrationStates(TrashAddedRegistrations);
			PruneDestroyedRegistrationStates(TrashLevelChangedRegistrations);
		}

		private static void PruneDestroyedRegistrationStates<TState>(Dictionary<int, TState> registrations) where TState : TrashContainerRegistrationState
		{
			List<int> list = null;
			foreach (KeyValuePair<int, TState> registration in registrations)
			{
				if (!((Object)(object)registration.Value.S1TrashContainer != (Object)null))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(registration.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				registrations.Remove(item);
			}
		}
	}
	public readonly struct TrashContentEntry
	{
		public string? TrashId { get; }

		public int Quantity { get; }

		public int UnitSize { get; }

		public int UnitValue { get; }

		internal TrashContentEntry(string? trashId, int quantity, int unitSize, int unitValue)
		{
			TrashId = trashId;
			Quantity = quantity;
			UnitSize = unitSize;
			UnitValue = unitValue;
		}
	}
	public static class TrashManager
	{
		private static readonly Log Logger = new Log("TrashManager");

		private static readonly object RegistrationGate = new object();

		private static readonly Dictionary<string, TrashItem> RegisteredPrefabs = new Dictionary<string, TrashItem>(StringComparer.OrdinalIgnoreCas

Plugins/S1APILoader.MelonLoader.dll

Decompiled 2 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using MelonLoader;
using MelonLoader.Utils;
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.5.0", "KaBooMa & Bars", 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+c81076db53242c4e7df4190c3bb342ba4e627cf8")]
[assembly: AssemblyProduct("S1APILoader")]
[assembly: AssemblyTitle("S1APILoader")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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";

		private const string ProblematicMelonVersion = "0.7.1";

		private const int InteropFixRevision = 1;

		private const string InteropMarkerFileName = "S1API.InteropFix.marker";

		private static bool _earlyInteropFixAttempted;

		public override void OnApplicationEarlyStart()
		{
			TryApplyEarlyIl2CppInteropFix();
			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 TryApplyEarlyIl2CppInteropFix()
		{
			if (_earlyInteropFixAttempted)
			{
				return;
			}
			_earlyInteropFixAttempted = true;
			if (MelonUtils.IsGameIl2Cpp())
			{
				string melonLoaderVersion = GetMelonLoaderVersion();
				if (!string.IsNullOrEmpty(melonLoaderVersion) && melonLoaderVersion.StartsWith("0.7.1", StringComparison.OrdinalIgnoreCase))
				{
					MelonLogger.Warning("[S1APILoader] MelonLoader 0.7.1 detected. Applying early Il2CppInterop workaround...");
					RegisterAssemblyResolveFallback();
					InstallIl2CppInteropFixes();
					TryForceAssemblyRegenerationIfNeeded(melonLoaderVersion);
				}
			}
		}

		private static string? GetMelonLoaderVersion()
		{
			try
			{
				Assembly assembly = typeof(MelonPlugin).Assembly;
				object obj = (assembly.GetType("MelonLoader.Properties.BuildInfo")?.GetProperty("VersionNumber", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(null);
				if (obj != null)
				{
					return obj.ToString();
				}
				Version version = assembly.GetName().Version;
				if (version != null)
				{
					return $"{version.Major}.{version.Minor}.{version.Build}";
				}
			}
			catch
			{
			}
			return null;
		}

		private static void RegisterAssemblyResolveFallback()
		{
			AppDomain.CurrentDomain.AssemblyResolve += delegate(object _, ResolveEventArgs args)
			{
				string name = new AssemblyName(args.Name).Name;
				if (string.IsNullOrEmpty(name) || !name.StartsWith("Il2Cpp", StringComparison.Ordinal))
				{
					return (Assembly)null;
				}
				string strippedName = name.Substring("Il2Cpp".Length);
				return string.IsNullOrEmpty(strippedName) ? null : AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, strippedName, StringComparison.OrdinalIgnoreCase));
			};
		}

		private static void InstallIl2CppInteropFixes()
		{
			try
			{
				Assembly assembly = typeof(MelonPlugin).Assembly;
				MethodInfo methodInfo = assembly.GetType("MelonLoader.Fixes.Il2CppInteropFixes")?.GetMethod("Install", BindingFlags.Static | BindingFlags.NonPublic);
				if (methodInfo == null)
				{
					MelonLogger.Warning("[S1APILoader] Could not find Il2CppInteropFixes.Install().");
					return;
				}
				methodInfo.Invoke(null, null);
				MelonLogger.Msg("[S1APILoader] Early Il2CppInterop fixes applied.");
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[S1APILoader] Failed to apply early Il2CppInterop fixes: " + ex.Message);
			}
		}

		private static void TryForceAssemblyRegenerationIfNeeded(string melonVersion)
		{
			try
			{
				string interopMarkerPath = GetInteropMarkerPath();
				if (IsMarkerValid(interopMarkerPath, melonVersion))
				{
					MelonLogger.Msg("[S1APILoader] Interop fix marker found. Skipping assembly regeneration.");
					return;
				}
				if (!HasPreGeneratedIl2CppAssemblies())
				{
					MelonLogger.Msg("[S1APILoader] No pre-generated Il2Cpp assemblies found. MelonLoader will generate them normally.");
					WriteMarker(interopMarkerPath, melonVersion);
					return;
				}
				MelonLogger.Warning("[S1APILoader] Pre-generated Il2Cpp assemblies detected. Forcing regeneration...");
				if (ForceRunIl2CppAssemblyGenerator())
				{
					WriteMarker(interopMarkerPath, melonVersion);
					MelonLogger.Msg("[S1APILoader] Il2Cpp assembly regeneration completed successfully.");
				}
				else
				{
					MelonLogger.Warning("[S1APILoader] Il2Cpp assembly regeneration may have failed. Will retry on next launch.");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[S1APILoader] Error during assembly regeneration check: " + ex.Message);
			}
		}

		private static string GetInteropMarkerPath()
		{
			string userDataDirectory = MelonEnvironment.UserDataDirectory;
			if (!Directory.Exists(userDataDirectory))
			{
				Directory.CreateDirectory(userDataDirectory);
			}
			return Path.Combine(userDataDirectory, "S1API.InteropFix.marker");
		}

		private static bool IsMarkerValid(string markerPath, string melonVersion)
		{
			if (!File.Exists(markerPath))
			{
				return false;
			}
			try
			{
				string[] array = File.ReadAllLines(markerPath);
				if (array.Length < 2)
				{
					return false;
				}
				string text = null;
				int result = -1;
				string[] array2 = array;
				foreach (string text2 in array2)
				{
					if (text2.StartsWith("melonloader=", StringComparison.OrdinalIgnoreCase))
					{
						text = text2.Substring("melonloader=".Length).Trim();
					}
					else if (text2.StartsWith("fixrevision=", StringComparison.OrdinalIgnoreCase))
					{
						string s = text2.Substring("fixrevision=".Length).Trim();
						int.TryParse(s, out result);
					}
				}
				if (string.IsNullOrEmpty(text))
				{
					return false;
				}
				bool flag = text.Equals(melonVersion, StringComparison.OrdinalIgnoreCase);
				bool flag2 = result >= 1;
				return flag && flag2;
			}
			catch
			{
				return false;
			}
		}

		private static void WriteMarker(string markerPath, string melonVersion)
		{
			try
			{
				string contents = $"melonloader={melonVersion}{Environment.NewLine}fixrevision={1}{Environment.NewLine}timestamp={DateTime.UtcNow:O}";
				File.WriteAllText(markerPath, contents);
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[S1APILoader] Failed to write interop fix marker: " + ex.Message);
			}
		}

		private static bool HasPreGeneratedIl2CppAssemblies()
		{
			try
			{
				string il2CppAssembliesDirectory = MelonEnvironment.Il2CppAssembliesDirectory;
				if (!Directory.Exists(il2CppAssembliesDirectory))
				{
					return false;
				}
				string[] files = Directory.GetFiles(il2CppAssembliesDirectory, "Il2Cpp*.dll", SearchOption.TopDirectoryOnly);
				return files.Length != 0;
			}
			catch
			{
				return false;
			}
		}

		private static bool ForceRunIl2CppAssemblyGenerator()
		{
			Assembly assembly = typeof(MelonPlugin).Assembly;
			try
			{
				object obj = (assembly.GetType("MelonLoader.LoaderConfig")?.GetProperty("Current", BindingFlags.Static | BindingFlags.Public))?.GetValue(null);
				if (obj != null)
				{
					object obj2 = obj.GetType().GetProperty("UnityEngine", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj);
					if (obj2 != null)
					{
						PropertyInfo property = obj2.GetType().GetProperty("ForceRegeneration", BindingFlags.Instance | BindingFlags.Public);
						if (property != null && property.CanWrite)
						{
							property.SetValue(obj2, true);
							MelonLogger.Msg("[S1APILoader] Set LoaderConfig.Current.UnityEngine.ForceRegeneration=true");
						}
						else
						{
							MelonLogger.Warning("[S1APILoader] ForceRegeneration property is read-only or not found.");
						}
					}
					else
					{
						MelonLogger.Warning("[S1APILoader] UnityEngine config is null.");
					}
				}
				else
				{
					MelonLogger.Warning("[S1APILoader] LoaderConfig.Current is null.");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[S1APILoader] Error setting ForceRegeneration via LoaderConfig: " + ex.Message);
			}
			return true;
		}

		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);
			}
		}
	}
}