Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of S1API Forked v3.2.3
Mods/S1API.Mono.MelonLoader.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
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
The result has been truncated due to the large size, download it to view full contents!
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 agousing 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); } } } }