Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of FurnitureDelivery v2.0.0
FurnitureDelivery-IL2CPP.dll
Decompiled a month 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.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using FurnitureDelivery; using FurnitureDelivery.Builders; using FurnitureDelivery.Helpers; using FurnitureDelivery.Interop; using FurnitureDelivery.Patches; using FurnitureDelivery.Shops; using HarmonyLib; using Il2Cpp; using Il2CppFishNet; using Il2CppFishNet.Connection; using Il2CppFishNet.Object; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.Core.Items.Framework; using Il2CppScheduleOne.Delivery; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Money; using Il2CppScheduleOne.Networking; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.UI.Phone.Delivery; using Il2CppScheduleOne.UI.Shop; using Il2CppScheduleOne.Vehicles; using Il2CppScheduleOne.Vehicles.Modification; using Il2CppScheduleOne.Weather; using Il2CppSteamworks; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(global::FurnitureDelivery.FurnitureDelivery), "FurnitureDelivery", "2.0.0", "k073l", null)] [assembly: MelonColor(1, 255, 215, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonOptionalDependencies(new string[] { "MoreGuns", "Toileportation", "UpgradedTrashCans", "DeliveryApp++", "MetalStorage", "Absurdely Better Delivery" })] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("FurnitureDelivery-IL2CPP")] [assembly: AssemblyConfiguration("IL2CPP")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+473695fb8128dca38f84c694aa2d03ac6a1a0bd7")] [assembly: AssemblyProduct("FurnitureDelivery-IL2CPP")] [assembly: AssemblyTitle("FurnitureDelivery-IL2CPP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public class VehicleSync { [CompilerGenerated] private sealed class <WaitForPayload>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int <attempt>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPayload>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <attempt>5__1 = 0; break; case 1: <>1__state = -1; <attempt>5__1++; break; } if (<attempt>5__1 < 10) { if (GetPayload()) { Logger.Debug("Vehicle sync payload received successfully"); return false; } Logger.Debug($"Attempt {<attempt>5__1 + 1}/{10}: No payload received, waiting {1f} seconds..."); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } Logger.Error("Failed to receive vehicle sync payload after maximum attempts"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static Dictionary<int, (string, string)> AddedVehicles = new Dictionary<int, (string, string)>(); public static Instance Logger = new Instance("FurnitureDelivery-VehicleSync"); private const string VehiclesKey = "FurnitureDelivery_Vehicles"; private const string Version = "1.0.0"; public static bool isHost = Singleton<Lobby>.Instance.IsHost; public static bool isClient = !Singleton<Lobby>.Instance.IsHost && Singleton<Lobby>.Instance.IsInLobby; public static bool isSingleplayer = !Singleton<Lobby>.Instance.IsInLobby; public static void SyncVehicles() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (isSingleplayer) { Logger.Msg("Not in a lobby, skipping vehicle sync"); return; } Logger.Debug($"Syncing {AddedVehicles.Count} vehicles to clients"); if (isHost) { string text = SerializeVehicles(AddedVehicles); Logger.Debug("Syncing vehicles to clients: " + text); if (!SteamMatchmaking.SetLobbyData(Singleton<Lobby>.Instance.LobbySteamID, "FurnitureDelivery_Vehicles", text)) { Logger.Error("Failed to set lobby data for vehicle sync"); } } else if (isClient) { Logger.Debug("Client detected, waiting for vehicle sync payload"); if (GetPayload()) { Logger.Debug("Vehicle sync payload received successfully"); } else { MelonCoroutines.Start(WaitForPayload()); } } } [IteratorStateMachine(typeof(<WaitForPayload>d__8))] public static IEnumerator WaitForPayload() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPayload>d__8(0); } private static bool GetPayload() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) string lobbyData = SteamMatchmaking.GetLobbyData(Singleton<Lobby>.Instance.LobbySteamID, "FurnitureDelivery_Vehicles"); if (!string.IsNullOrEmpty(lobbyData)) { Logger.Debug("Received vehicle sync payload: " + lobbyData); AddedVehicles = DeserializeVehicles(lobbyData); Logger.Msg($"Synced {AddedVehicles.Count} vehicles from payload"); return true; } Logger.Debug("No vehicle sync payload found"); return false; } private static string SerializeVehicles(Dictionary<int, (string, string)> vehicles) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[email protected];"); foreach (KeyValuePair<int, (string, string)> vehicle in vehicles) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 3, stringBuilder2); handler.AppendFormatted(vehicle.Key); handler.AppendLiteral(":"); handler.AppendFormatted(vehicle.Value.Item1); handler.AppendLiteral(","); handler.AppendFormatted(vehicle.Value.Item2); handler.AppendLiteral(";"); stringBuilder2.Append(ref handler); } return stringBuilder.ToString(); } private static Dictionary<int, (string, string)> DeserializeVehicles(string data) { Dictionary<int, (string, string)> dictionary = new Dictionary<int, (string, string)>(); if (string.IsNullOrEmpty(data)) { return dictionary; } string[] array = data.Split(';'); if (array.Length == 0 || !array[0].StartsWith("[email protected]")) { Logger.Error("Invalid vehicle sync data format"); return dictionary; } string[] array2 = array; foreach (string text in array2) { if (string.IsNullOrEmpty(text)) { continue; } string[] array3 = text.Split(':'); if (array3.Length == 2) { int key = int.Parse(array3[0]); string[] array4 = array3[1].Split(','); if (array4.Length == 2) { dictionary[key] = (array4[0], array4[1]); } } } return dictionary; } public static LandVehicle GetVehicleById(int id) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) if (AddedVehicles.TryGetValue(id, out var value)) { var (text, text2) = value; Logger.Debug($"Searching for vehicle with ID {id}, Name: {text}, GUID: {text2}"); Scene sceneByName = SceneManager.GetSceneByName("Main"); if (!((Scene)(ref sceneByName)).isLoaded) { Logger.Error("Main scene is not loaded."); return null; } Il2CppReferenceArray<GameObject> rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects(); LandVehicle val = null; foreach (GameObject item in (Il2CppArrayBase<GameObject>)(object)rootGameObjects) { val = ((IEnumerable<LandVehicle>)item.GetComponentsInChildren<LandVehicle>(true)).FirstOrDefault((Func<LandVehicle, bool>)((LandVehicle v) => ((NetworkBehaviour)v).ObjectId == id)); if ((Object)(object)val != (Object)null) { break; } } if ((Object)(object)val == (Object)null) { Logger.Error($"Vehicle with ObjectId {id} not found in Main scene"); return null; } Guid val2 = default(Guid); Guid val3 = (Guid.TryParse(text2, ref val2) ? val2 : Guid.Empty); Logger.Debug($"Setting the vehicle GUID to {val3}"); val.SetGUID(val3); Logger.Debug("Setting the vehicle go name to " + text); ((Object)val).name = text; Logger.Debug("Setting the vehicle vehicleName to " + text); val.vehicleName = text; Logger.Debug($"Found vehicle: {((Object)val).name} with GUID {val.GUID} and ObjectId {((NetworkBehaviour)val).ObjectId}"); return val; } Logger.Error($"Vehicle with ID {id} not found in AddedVehicles dictionary"); return null; } public static LandVehicle GetVehicleByName(string name) { Logger.Debug("Searching for vehicle by name: " + name); int key = AddedVehicles.FirstOrDefault((KeyValuePair<int, (string, string)> kvp) => kvp.Value.Item1.Contains(name)).Key; return (key != 0) ? GetVehicleById(key) : null; } } namespace FurnitureDelivery { public static class BuildInfo { public const string Name = "FurnitureDelivery"; public const string Description = "Adds a custom delivery shops for furniture items"; public const string Author = "k073l"; public const string Version = "2.0.0"; } public class FurnitureDelivery : MelonMod { [CompilerGenerated] private sealed class <OnDeliveryManagerReady>d__10 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnDeliveryManagerReady>d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; MelonLogger.Debug("Delivery manager ready"); DeliveryManager instance = NetworkSingleton<DeliveryManager>.Instance; instance.onDeliveryCreated += Action<DeliveryInstance>.op_Implicit((Action<DeliveryInstance>)delegate(DeliveryInstance di) { ToileportationInterop.OnDeliveryCreated(di); }); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Sprite _stanMugshot; private static Instance MelonLogger { get; set; } internal static Sprite StanMugshot => GetIcon(ref _stanMugshot, "FurnitureDelivery.assets.stan_mugshot.png"); public override void OnInitializeMelon() { MelonLogger = ((MelonBase)this).LoggerInstance; MelonLogger.Msg("FurnitureDelivery initialized"); if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("MoreGuns"))) { MelonLogger.Msg("MoreGuns detected. Adding ak47 to Armory"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("Toileportation"))) { MelonLogger.Msg("Toileportation detected. Adding Golden Toilet to Herbert's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("UpgradedTrashCans"))) { MelonLogger.Msg("UpgradedTrashCans detected. Adding trash bins to Dan's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("MetalStorage"))) { MelonLogger.Msg("MetalStorage detected. Adding metal storage racks to Dan's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("BigSprinklerLogic"))) { MelonLogger.Msg("BigSprinklerLogic detected. Adding big sprinkler to Dan's shop"); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("Toileportation"))) { if (!(sceneName == "Main")) { if (sceneName == "Menu") { if ((Object)(object)NetworkSingleton<DeliveryManager>.Instance != (Object)null) { DeliveryManager instance = NetworkSingleton<DeliveryManager>.Instance; instance.onDeliveryCreated += Action<DeliveryInstance>.op_Implicit((Action<DeliveryInstance>)delegate(DeliveryInstance di) { ToileportationInterop.OnDeliveryCreated(di); }); } ToileportationInterop.GoldenToiletListing = null; } } else { MelonCoroutines.Start(Utils.WaitForNetworkSingleton<DeliveryManager>(OnDeliveryManagerReady())); } } if (!(sceneName == "Main")) { if (sceneName == "Menu") { } } else if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("DeliveryApp++"))) { MelonLogger.Msg("DeliveryAppPlusPlus detected. Applying patches"); DeliveryAppPlusPlusInterop.ApplyPatches(); } } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { if (sceneName == "Main") { DeliveryAppPatches.Start.Initialized = false; DeliveryAppPatches.Awake.AddedShops = false; Registries.Clear(); MelonLogger.Msg("Scene unloaded, reset initialization flags and registries"); } } [IteratorStateMachine(typeof(<OnDeliveryManagerReady>d__10))] private static IEnumerator OnDeliveryManagerReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnDeliveryManagerReady>d__10(0); } private static Sprite LoadEmbeddedPNG(string resourceName) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(resourceName); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2); if (!ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array))) { return null; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); if ((Object)(object)val2 != (Object)null) { ((Object)val2).name = resourceName; } return val2; } private static Sprite GetIcon(ref Sprite spriteField, string resourceName) { if ((Object)(object)spriteField == (Object)null) { spriteField = LoadEmbeddedPNG(resourceName); } return spriteField; } } [HarmonyPatch(typeof(VehicleCamera))] public static class VehicleCameraPatch { [HarmonyPrefix] [HarmonyPatch("LateUpdate")] public static bool SafeLateUpdatePrefix(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } [HarmonyPrefix] [HarmonyPatch("Update")] public static bool SafeUpdatePrefix(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } } [HarmonyPatch(typeof(DeliveryVehicle), "Deactivate")] public static class DeliveryVehicleDeactivatePatch { public static Instance Logger = new Instance("FurnitureDelivery-VehicleDeactivate"); public static bool Prefix(DeliveryVehicle __instance) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)__instance.Vehicle == (Object)null) { return true; } DeliveryInstance activeDelivery = __instance.ActiveDelivery; if (activeDelivery != null && (int)activeDelivery.Status == 3) { return true; } LandVehicle vehicle = __instance.Vehicle; string text = ((vehicle != null) ? ((Object)vehicle).name : null); if (string.IsNullOrEmpty(text)) { return true; } string text2 = null; if (text.Contains("Dan")) { text2 = "Dan"; } else if (text.Contains("Oscar")) { text2 = "Oscar"; } if (!string.IsNullOrEmpty(text2)) { DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; List<DeliveryShop> val = ((instance != null) ? instance.deliveryShops : null); if (val == null) { return true; } DeliveryManager instance2 = NetworkSingleton<DeliveryManager>.Instance; if ((Object)(object)instance2 == (Object)null) { Logger.Debug("NetworkSingleton<DeliveryManager>.Instance is null"); return true; } Enumerator<DeliveryShop> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { DeliveryShop current = enumerator.Current; if (instance2.GetActiveShopDelivery(current) != null) { Logger.Warning(text2 + " is currently delivering an order, not deactivating the vehicle"); return false; } } } return true; } } [HarmonyPatch(typeof(ListingUI))] public static class ListingUICanAddToCartPatch { [HarmonyPatch("CanAddToCart")] [HarmonyPrefix] public static bool PrefixCanAddToCart(ListingUI __instance, ref bool __result) { if (__instance.Listing == null) { __result = false; return false; } return true; } [HarmonyPatch("UpdateButtons")] [HarmonyPrefix] public static bool PrefixUpdateButtons(ListingUI __instance) { if ((Object)(object)__instance == (Object)null) { return false; } if ((Object)(object)__instance.BuyButton == (Object)null) { return false; } if (!((Behaviour)__instance.BuyButton).isActiveAndEnabled) { return false; } if ((Object)(object)__instance.DropdownButton == (Object)null) { return false; } if (!((Behaviour)__instance.DropdownButton).isActiveAndEnabled) { return false; } if (__instance.Listing == null) { return false; } return true; } } [HarmonyPatch(typeof(Wheel))] internal class WheelPatch { [HarmonyPatch("OnWeatherChange")] [HarmonyPrefix] private static bool ExitIfNull(Wheel __instance, WeatherConditions newConditions) { if ((Object)(object)((__instance != null) ? __instance.vehicle : null) == (Object)null) { return false; } if (newConditions != null) { _ = newConditions.Rainy; if (0 == 0) { return true; } } return false; } } [HarmonyPatch(typeof(DeliveryVehicle))] internal static class DeliveryVehicleAwakePatch { [HarmonyPatch("Awake")] [HarmonyPrefix] [HarmonyPriority(800)] private static bool ExitIfNull(DeliveryVehicle __instance) { Guid val = default(Guid); if (Guid.TryParse(__instance.GUID, ref val)) { return true; } if ((Object)(object)((Component)__instance).GetComponent<LandVehicle>() == (Object)null) { return false; } __instance.Vehicle = ((Component)__instance).GetComponent<LandVehicle>(); __instance.Deactivate(); return false; } } [HarmonyPatch(typeof(ShopInterface))] internal static class ShopInterfacePatch { public static Instance Logger => new Instance("FurnitureDelivery-ShopInterfacePatch"); [HarmonyPatch("Awake")] [HarmonyPrefix] private static void EnsureInAllShops(ShopInterface __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { if (!ShopInterface.AllShops.Contains(__instance)) { ShopInterface.AllShops.Add(__instance); Logger.Debug("Added ShopInterface to AllShops: " + __instance.ShopName); } } catch (Exception ex) { Logger.Error("Failed to add ShopInterface to AllShops: " + ex.Message); } } [HarmonyPatch("RefreshShownItems")] [HarmonyPrefix] private static bool ExitIfUINull(ShopInterface __instance) { if (((__instance != null) ? __instance.listingUI : null) == null || (Object)(object)__instance.DetailPanel == (Object)null) { return false; } return true; } [HarmonyPatch("Start")] [HarmonyPrefix] private static void AddMissingMembers(ShopInterface __instance) { if ((Object)(object)__instance.Canvas == (Object)null) { __instance.Canvas = ((Component)__instance).GetComponent<Canvas>() ?? ((Component)__instance).gameObject.AddComponent<Canvas>(); } if ((Object)(object)__instance.Container == (Object)null) { __instance.Container = ((Component)__instance).GetComponent<RectTransform>() ?? ((Component)__instance).gameObject.AddComponent<RectTransform>(); } } } public static class ShopRegistry { private static readonly List<ICustomShop> _shops = new List<ICustomShop>(4) { new DanShop(), new HerbertShop(), new OscarShop(), new StanShop() }; public static IReadOnlyList<ICustomShop> Shops => _shops.AsReadOnly(); public static string GetShopName(this ICustomShop shop) { return shop.ShopName; } } } namespace FurnitureDelivery.Shops { public class DanShop : ICustomShop { public static Instance Logger = new Instance("FurnitureDelivery-DanShop"); public string ShopName => "DeliveryShop_Dan's Furniture"; public List<string> ItemIDs => new List<string> { "coffeetable", "metalsquaretable", "woodsquaretable", "plastictable", "toilet", "trashcan", "trash_bin", "trash_compactor", "bed", "locker", "TV", "acunit", "floorlamp", "growtent", "plasticpot", "halogengrowlight", "ledgrowlight", "suspensionrack", "soilpourer", "potsprinkler", "bigsprinkler", "largestoragerack", "mediumstoragerack", "smallstoragerack", "metallargestoragerack", "metalmediumstoragerack", "metalsmallstoragerack", "smallstoragecloset", "mediumstoragecloset", "largestoragecloset", "hugestoragecloset" }; public DeliveryShop CreateShop(DeliveryApp app) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Dan's Furniture shop"); LandVehicle val = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable<LandVehicle>().FirstOrDefault((Func<LandVehicle, bool>)((LandVehicle item) => (Object)(object)item != (Object)null && ((Object)item).name.Contains("Dan"))); Logger.Debug($"Found delivery vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Dan's Furniture").WithShopDescription("General furniture").WithShopColor(new Color(0.06f, 0.56f, 0.87f)) .WithShopImage(Utils.FindSprite("Dan_Mugshot")) .WithDeliveryFee(300f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(4); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((BaseItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding item " + ((Object)item).name + " to Dan's shop"); deliveryShopBuilder.AddListing(item); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Dan's Furniture created"); return val2; } } public class HerbertShop : ICustomShop { public static Instance Logger = new Instance("FurnitureDelivery-HerbertShop"); public string ShopName => "DeliveryShop_Herbert"; public List<string> ItemIDs => new List<string> { "woodensign", "metalsign", "wallmountedshelf", "antiquewalllamp", "modernwalllamp", "wallclock", "grandfatherclock", "safe", "jukebox", "goldenskateboard", "filingcabinet", "smalltrashcan", "dumpster", "garbagethrone" }; public DeliveryShop CreateShop(DeliveryApp app) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Herbert's shop"); LandVehicle val = null; if (!InstanceFinder.IsServer) { Logger.Debug("Syncing vehicles"); VehicleSync.SyncVehicles(); Logger.Debug("Not on server, trying to find Herbert's land vehicle"); val = Utils.GetNotNullWithTimeout(() => VehicleSync.GetVehicleByName("LandVehicle_Herbert")); } else { Logger.Debug("On server, creating Herbert's land vehicle"); val = new LandVehicleBuilder().WithVehicleName("LandVehicle_Herbert").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)11) .Build(); } Logger.Debug($"Found land vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Herbert's Curiosities").WithShopDescription("Boutique's picks and exotic items").WithShopColor(new Color(0.2f, 0f, 1f)) .WithShopImage(Utils.FindSprite("Herbert_Mugshot")) .WithDeliveryFee(500f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(5); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((BaseItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding item " + ((Object)item).name + " to Herbert's shop"); deliveryShopBuilder.AddListing(item); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "Toileportation")) { ShopListing goldenToiletListing = ToileportationInterop.GoldenToiletListing; if (goldenToiletListing == null) { Logger.Warning("Golden toilet listing not found, waiting for it to be created"); MelonCoroutines.Start(Utils.WaitForNotNull(goldenToiletListing)); } goldenToiletListing.CanBeDelivered = true; Logger.Msg("Adding golden toilet to Herbert's shop"); deliveryShopBuilder.AddListing(goldenToiletListing); Logger.Debug($"{goldenToiletListing.Shop}, {goldenToiletListing.CurrentStock}, {goldenToiletListing.Item.BasePurchasePrice}, {((BaseItemDefinition)goldenToiletListing.Item).ID}"); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Herbert's Curiosities created"); return val2; } } public interface ICustomShop { List<string> ItemIDs { get; } string ShopName { get; } DeliveryShop CreateShop(DeliveryApp app); } public class OscarShop : ICustomShop { public static Instance Logger = new Instance("FurnitureDelivery-OscarShop"); public string ShopName => "DeliveryShop_Oscar"; public List<string> ItemIDs => new List<string> { "moisturepreservingpot", "airpot", "fullspectrumgrowlight", "suspensionrack", "packagingstation", "packagingstationmk2", "mixingstation", "mixingstationmk2", "mushroomspawnstation", "mushroombed", "dryingrack", "chemistrystation", "laboven", "cauldron", "brickpress", "locker" }; public DeliveryShop CreateShop(DeliveryApp app) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Oscar's Equipment shop"); LandVehicle val = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable<LandVehicle>().FirstOrDefault((Func<LandVehicle, bool>)((LandVehicle item) => (Object)(object)item != (Object)null && ((Object)item).name.Contains("Oscar"))); if ((Object)(object)val == (Object)null) { Logger.Warning("Oscar delivery vehicle not found, using default vehicle"); val = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable<LandVehicle>().FirstOrDefault(); } Logger.Debug($"Found delivery vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Oscar's Equipment").WithShopDescription("'Specialized' equipment").WithDeliveryFee(350f) .WithShopColor(new Color(0.87f, 0.44f, 0.05f)) .WithShopImage(Utils.FindSprite("Oscar_Mugshot")) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(7); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((BaseItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding " + ((BaseItemDefinition)item).ID + " to Oscar's shop"); deliveryShopBuilder.AddListing(item); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Oscar's Equipment created"); return val2; } } public class StanShop : ICustomShop { public static readonly Dictionary<string, float> ItemPrices = new Dictionary<string, float> { { "baseballbat", 50f }, { "fryingpan", 100f }, { "machete", 250f }, { "revolver", 1000f }, { "revolvercylinder", 10f }, { "m1911", 2500f }, { "goldenm1911", 25000f }, { "m1911mag", 20f }, { "pumpshotgun", 7500f }, { "shotgunshell", 5f }, { "ak47", 15000f }, { "ak47mag", 1000f }, { "minigun", 75000f }, { "minigunmag", 10000f } }; public static Instance Logger = new Instance("FurnitureDelivery-StanShop"); public string ShopName => "DeliveryShop_Armory"; public List<string> ItemIDs => ItemPrices.Keys.ToList(); public DeliveryShop CreateShop(DeliveryApp app) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Stan's shop"); LandVehicle val = null; if (!InstanceFinder.IsServer) { Logger.Debug("Syncing vehicles"); VehicleSync.SyncVehicles(); Logger.Debug("Not on server, trying to find Stan's land vehicle"); val = Utils.GetNotNullWithTimeout(() => VehicleSync.GetVehicleByName("LandVehicle_Stan")); } else { Logger.Debug("On server, creating Stan's land vehicle"); val = new LandVehicleBuilder().WithVehicleName("LandVehicle_Stan").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)0) .Build(); } Logger.Debug($"Found delivery vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Armory").WithShopDescription("Weapons and ammo").WithShopColor(new Color(0.8f, 0f, 0f)) .WithShopImage(FurnitureDelivery.StanMugshot) .WithDeliveryFee(800f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(8); List<StorableItemDefinition> allStorableItemDefinitions = Utils.GetAllStorableItemDefinitions(); Dictionary<string, StorableItemDefinition> itemMap = allStorableItemDefinitions.ToDictionary((StorableItemDefinition i) => ((BaseItemDefinition)i).ID); List<GunItem> list = (from kvp in ItemPrices where itemMap.ContainsKey(kvp.Key) select new GunItem { Item = (ItemDefinition)(object)itemMap[kvp.Key], BasePrice = kvp.Value }).ToList(); foreach (GunItem item in list) { Logger.Debug("Adding item " + ((BaseItemDefinition)item.Item).ID + " to Stan's shop"); float value = item.BasePrice; string iD = ((BaseItemDefinition)item.Item).ID; if (1 == 0) { } string text; switch (iD) { case "ak47": case "ak47mag": text = "ak47"; break; case "minigun": case "minigunmag": text = "minigun"; break; default: text = null; break; } if (1 == 0) { } string text2 = text; if (text2 != null && MoreGunsInterop.TryGetPrices(text2, out var gunPrice, out var magPrice)) { value = ((((BaseItemDefinition)item.Item).ID == text2) ? gunPrice : magPrice); Logger.Msg($"Using MoreGuns price for '{((BaseItemDefinition)item.Item).ID}': {value}"); } if (Utils.Is<StorableItemDefinition>((object)item.Item, out StorableItemDefinition result)) { deliveryShopBuilder.AddListing(result, value); } } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Stan's shop created"); return val2; } } public class GunItem { public ItemDefinition Item { get; set; } public float BasePrice { get; set; } } } namespace FurnitureDelivery.Shops.UI { public static class UIPathConstants { public const string Container = "Container"; public const string Header = "Container/Header"; public const string Listings = "Listings"; public const string ListingContainer = "ListingContainer"; public const string Entries = "Entries"; public const string BackButton = "Container/BackButton"; public const string Confirm = "Container/Confirm"; public const string DestinationDropdown = "Container/DestinationDropdown"; public const string LoadingDockDropdown = "Container/LoadingDockDropdown"; public const string ItemTotal = "Container/ItemTotal/Amount"; public const string OrderTotal = "Container/OrderTotal/Amount"; public const string DeliveryFee = "Container/DeliveryFee/Amount"; public const string DeliveryTime = "Container/DeliveryTime"; public const string Dropshadow = "Dropshadow"; public const string Order = "Container/Contents/Container/Shops/Order"; public const string ScrollViewContent = "Container/Scroll View/Viewport/Content"; public const string IconImage = "Container/Icon/Image"; public const string Title = "Container/Labels/Container/Title"; public const string Description = "Container/Labels/Container/Description"; public const string HeaderFallback = "Header"; public const string BackButtonFallback = "BackButton"; public const string OrderButtonFallback = "OrderButton"; public const string DestinationDropdownFallback = "DestinationDropdown"; public const string LoadingDockDropdownFallback = "LoadingDockDropdown"; public const string DeliveryTimeLabelFallback = "DeliveryTimeLabel"; public const string ItemTotalLabelFallback = "ItemTotalLabel"; public const string OrderTotalLabelFallback = "OrderTotalLabel"; public const string DeliveryFeeLabelFallback = "DeliveryFeeLabel"; } } namespace FurnitureDelivery.Patches { [HarmonyPatch] public static class DeliveryAppPatches { [HarmonyPatch(typeof(DeliveryApp), "SetIsAvailable")] public class SetIsAvailable { public static bool Prefix(DeliveryApp __instance, ShopInterface matchingShop) { Logger.Debug("SetIsAvailable: " + ((matchingShop != null) ? matchingShop.ShopName : null)); return true; } public static void Postfix(DeliveryApp __instance, ShopInterface matchingShop) { try { if (((matchingShop != null) ? matchingShop.ShopName : null) == null || (Object)(object)((Component)matchingShop).gameObject == (Object)null) { return; } DeliveryApp val = __instance ?? PlayerSingleton<DeliveryApp>.Instance; if (((val != null) ? val.deliveryShops : null) == null || !(matchingShop.ShopName == "Oscar's Store")) { return; } bool activeSelf = ((Component)matchingShop).gameObject.activeSelf; Enumerator<DeliveryShop> enumerator = val.deliveryShops.GetEnumerator(); while (enumerator.MoveNext()) { DeliveryShop current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !((Object)(object)((Component)current).gameObject == (Object)null) && !((Object)((Component)current).gameObject).name.StartsWith("DeliveryShop_") && (((Object)((Component)current).gameObject).name.Contains("Oscar") || ((Object)((Component)current).gameObject).name.Contains("Armory"))) { SyncButtonVisibility(val, current, activeSelf); } } } catch (Exception ex) { Logger.Error("SetIsAvailable postfix error: " + ex.Message); } } private static void SyncButtonVisibility(DeliveryApp app, DeliveryShop targetShop, bool visible) { if (((app != null) ? app._shopElements : null) == null || (Object)(object)targetShop == (Object)null) { return; } DeliveryShopElement val = app._shopElements?.AsEnumerable<DeliveryShopElement>().FirstOrDefault((Func<DeliveryShopElement, bool>)((DeliveryShopElement e) => (Object)(object)((e != null) ? e.Shop : null) == (Object)(object)targetShop)); if (val == null) { return; } Button button = val.Button; if (button != null) { GameObject gameObject = ((Component)button).gameObject; if (gameObject != null) { gameObject.SetActive(visible); } } } } [HarmonyPatch(typeof(DeliveryApp), "Awake")] public class Awake { public static bool AddedShops; public static void Prefix() { AddedShops = false; } } [HarmonyPatch(typeof(DeliveryApp), "Start")] public class Start { public static bool Initialized; public static void Postfix(DeliveryApp __instance) { if (Initialized) { return; } Initialized = true; Logger.Msg("DeliveryApp.Start running"); int value = (DeliveryShopBuilder.OriginalDeliveryShopsCount = __instance.deliveryShops.Count); Logger.Msg($"Set OriginalDeliveryShopsCount = {DeliveryShopBuilder.OriginalDeliveryShopsCount} (deliveryShops.Count = {value})"); foreach (ICustomShop shop in ShopRegistry.Shops) { try { Logger.Msg("Creating shop: " + shop.GetType().Name); shop.CreateShop(__instance); } catch (Exception ex) { Logger.Error("Failed to create shop: " + ex.Message); } } foreach (ICustomShop shop2 in ShopRegistry.Shops) { string shopName = shop2.GetShopName(); DeliveryShop customShop = __instance.deliveryShops.AsEnumerable<DeliveryShop>().FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)ds != (Object)null && ((Object)((Component)ds).gameObject).name.Contains(shopName))); if (!((Object)(object)customShop == (Object)null) && !((Object)(object)customShop.MatchingShop == (Object)null)) { if (__instance._shopElements.AsEnumerable<DeliveryShopElement>().Any((DeliveryShopElement e) => (Object)(object)((e != null) ? e.Shop : null) == (Object)(object)customShop)) { TryInitializeShop(customShop); continue; } CreateShopButton(__instance, customShop); TryInitializeShop(customShop); } } } private static void CreateShopButton(DeliveryApp app, DeliveryShop customShop) { //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Expected O, but got Unknown if (app._shopElements == null || app._shopElements.Count == 0) { return; } DeliveryShopElement val = app._shopElements[0]; object obj; if (val == null) { obj = null; } else { Button button = val.Button; obj = ((button != null) ? ((Component)button).gameObject : null); } if ((Object)obj == (Object)null) { return; } GameObject gameObject = ((Component)val.Button).gameObject; Transform parent = gameObject.transform.parent; GameObject val2 = Object.Instantiate<GameObject>(gameObject, parent); ((Object)val2).name = customShop.MatchingShop.ShopName + "Button"; val2.SetActive(true); int num = app.deliveryShops.IndexOf(customShop); if (num >= 0) { val2.transform.SetSiblingIndex(num); } foreach (Text componentsInChild in val2.GetComponentsInChildren<Text>()) { Text val3 = componentsInChild; string name = ((Object)((Component)componentsInChild).gameObject).name; if (1 == 0) { } string text = ((name == "Title") ? customShop.MatchingShop.ShopName : ((!(name == "Description")) ? componentsInChild.text : customShop.MatchingShop.ShopDescription)); if (1 == 0) { } val3.text = text; } foreach (Image componentsInChild2 in val2.GetComponentsInChildren<Image>()) { if (((Object)((Component)componentsInChild2).gameObject).name == "Image") { componentsInChild2.sprite = Registries.GetShopImage(customShop); } } if (Utils.Is<Image>((object)val2.GetComponent<Image>(), out Image result)) { ((Graphic)result).color = customShop.ShopColor; } Button component = val2.GetComponent<Button>(); if ((Object)(object)component != (Object)null) { ((UnityEventBase)component.onClick).RemoveAllListeners(); ((UnityEvent)component.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { app.OpenShop(customShop); })); DeliveryShop obj2 = customShop; obj2.OnSelect += Action<DeliveryShop>.op_Implicit((Action<DeliveryShop>)app.CloseShop); } int num2 = ((num >= 0 && num <= app._shopElements.Count) ? num : app._shopElements.Count); app._shopElements.Insert(num2, new DeliveryShopElement { Shop = customShop, Button = component }); } private static void TryInitializeShop(DeliveryShop shop) { if ((Object)(object)shop == (Object)null) { return; } if ((Object)(object)shop.MatchingShop != (Object)null && (Object)(object)shop.ListingContainer != (Object)null && shop.listingEntries.Count > 0) { Logger.Debug("Shop already initialized: " + ((Object)shop).name); return; } Instance logger = Logger; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(58, 3); defaultInterpolatedStringHandler.AppendLiteral("Setup shop - MatchingShop: "); ShopInterface matchingShop = shop.MatchingShop; defaultInterpolatedStringHandler.AppendFormatted((matchingShop != null) ? matchingShop.ShopName : null); defaultInterpolatedStringHandler.AppendLiteral(", ListingContainer: "); RectTransform listingContainer = shop.ListingContainer; defaultInterpolatedStringHandler.AppendFormatted((listingContainer != null) ? ((Object)listingContainer).name : null); defaultInterpolatedStringHandler.AppendLiteral(", Entries: "); defaultInterpolatedStringHandler.AppendFormatted(shop.listingEntries.Count); logger.Debug(defaultInterpolatedStringHandler.ToStringAndClear()); try { if ((Object)(object)shop.MatchingShop == (Object)null) { shop.MatchingShop = ShopInterface.AllShops.Find(Predicate<ShopInterface>.op_Implicit((Func<ShopInterface, bool>)((ShopInterface x) => x.ShopName == shop.MatchingShopInterfaceName))); } if ((Object)(object)shop.ListingContainer == (Object)null) { Logger.Error("ListingContainer is null for " + ((Object)shop).name + "!"); return; } if (shop.listingEntries.Count == 0) { Logger.Warning("No listing entries for " + ((Object)shop).name + ", creating them now..."); ShopInterface matchingShop2 = shop.MatchingShop; Enumerator<ShopListing> enumerator = (((matchingShop2 != null) ? matchingShop2.Listings : null) ?? new List<ShopListing>().ToIl2CppList()).GetEnumerator(); while (enumerator.MoveNext()) { ShopListing current = enumerator.Current; if (current.CanBeDelivered && (Object)(object)shop.ListingEntryPrefab != (Object)null) { ListingEntry val = Object.Instantiate<ListingEntry>(shop.ListingEntryPrefab, (Transform)(object)shop.ListingContainer); val.Initialize(current); val.onQuantityChanged.AddListener(UnityAction.op_Implicit((Action)shop.RefreshCart)); shop.listingEntries.Add(val); } } } Button backButton = shop.BackButton; if (backButton != null) { ((UnityEventBase)backButton.onClick).RemoveAllListeners(); } Button backButton2 = shop.BackButton; if (backButton2 != null) { ((UnityEvent)backButton2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { shop.OnSelect?.Invoke(shop); })); } Button orderButton = shop.OrderButton; if (orderButton != null) { ((UnityEventBase)orderButton.onClick).RemoveAllListeners(); } Button orderButton2 = shop.OrderButton; if (orderButton2 != null) { ((UnityEvent)orderButton2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { shop.SubmitOrder(string.Empty); })); } Dropdown destinationDropdown = shop.DestinationDropdown; if (destinationDropdown != null) { ((UnityEventBase)destinationDropdown.onValueChanged).RemoveAllListeners(); } Dropdown destinationDropdown2 = shop.DestinationDropdown; if (destinationDropdown2 != null) { ((UnityEvent<int>)(object)destinationDropdown2.onValueChanged).AddListener(UnityAction<int>.op_Implicit((Action<int>)shop.DestinationDropdownSelected)); } Dropdown loadingDockDropdown = shop.LoadingDockDropdown; if (loadingDockDropdown != null) { ((UnityEventBase)loadingDockDropdown.onValueChanged).RemoveAllListeners(); } Dropdown loadingDockDropdown2 = shop.LoadingDockDropdown; if (loadingDockDropdown2 != null) { ((UnityEvent<int>)(object)loadingDockDropdown2.onValueChanged).AddListener(UnityAction<int>.op_Implicit((Action<int>)shop.LoadingDockDropdownSelected)); } ((Component)shop).gameObject.SetActive(false); Logger.Debug("Setup succeeded for: " + ((Object)shop).name); } catch (Exception ex) { Logger.Error("Setup failed: " + ex.Message + "\n" + ex.StackTrace); } } } [HarmonyPatch(typeof(DeliveryApp), "SetOpen")] public class SetOpen { public static void Postfix(DeliveryApp __instance, bool open) { if ((Object)(object)__instance == (Object)null || !open) { return; } Enumerator<DeliveryShop> enumerator = __instance.deliveryShops.GetEnumerator(); while (enumerator.MoveNext()) { DeliveryShop current = enumerator.Current; if (!((Object)(object)((current != null) ? current.DeliveryFeeLabel : null) == (Object)null) && DeliveryShopBuilder.DeliveryFeeRegistry.TryGetValue(current, out var value)) { current.DeliveryFeeLabel.text = MoneyManager.FormatAmount(value, false, false); } } } } public static Instance Logger => new Instance("FurnitureDelivery-DeliveryApp"); } [HarmonyPatch] public static class DeliveryShopPatches { [HarmonyPatch(typeof(DeliveryShop), "RefreshCart")] public class RefreshCart { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.ItemTotalLabel == (Object)null || (Object)(object)__instance.OrderTotalLabel == (Object)null || (Object)(object)__instance.DeliveryTimeLabel == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "RefreshOrderButton")] public class RefreshOrderButton { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.OrderButton == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "RefreshDestinationUI")] public class RefreshDestinationUI { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.DestinationDropdown == (Object)null || (Object)(object)__instance.LoadingDockDropdown == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "RefreshLoadingDockUI")] public class RefreshLoadingDockUI { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.LoadingDockDropdown == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "GetDeliveryFee")] public class GetDeliveryFee { public static bool Prefix(DeliveryShop __instance, ref float __result) { if (DeliveryShopBuilder.DeliveryFeeRegistry.TryGetValue(__instance, out var value)) { __result = value; return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "CanOrder")] public class CanOrder { public static bool Prefix(DeliveryShop __instance, ref bool __result, ref string reason) { if ((Object)(object)__instance == (Object)null) { __result = false; reason = "Shop is null"; return false; } string name = ((Object)((Component)__instance).gameObject).name; if (name.Contains("Herbert")) { __result = ToileportationInterop.CanOrder((from e in PlayerSingleton<DeliveryApp>.Instance._shopElements.AsEnumerable<DeliveryShopElement>() select e.Shop).ToList(), out reason); if (!__result) { return false; } } if (!CheckShopConflict(name, "Dan", ref __result, out reason)) { return false; } if (!CheckShopConflict(name, "Oscar", ref __result, out reason)) { return false; } return true; } private static bool CheckShopConflict(string shopName, string name, ref bool __result, out string reason) { if (!shopName.Contains(name)) { reason = ""; return true; } Enumerator<DeliveryShop> enumerator = PlayerSingleton<DeliveryApp>.Instance.deliveryShops.GetEnumerator(); while (enumerator.MoveNext()) { DeliveryShop current = enumerator.Current; if ((Object)(object)current == (Object)null || !((Object)((Component)current).gameObject).name.Contains(name) || NetworkSingleton<DeliveryManager>.Instance.GetActiveShopDelivery(current) == null) { continue; } __result = false; reason = name + " is currently delivering an order"; return false; } reason = ""; return true; } } } [HarmonyPatch] public static class ListingUIPatches { [HarmonyPatch(typeof(ListingUI))] public static class ListingUIPatch { [HarmonyPatch("CanAddToCart")] public static bool CanAddToCart(ListingUI __instance, ref bool __result) { if (__instance.Listing == null) { __result = false; return false; } return true; } [HarmonyPatch("UpdateButtons")] public static bool UpdateButtons(ListingUI __instance) { if ((Object)(object)__instance == (Object)null) { return false; } if ((Object)(object)__instance.BuyButton == (Object)null || !((Behaviour)__instance.BuyButton).isActiveAndEnabled) { return false; } if ((Object)(object)__instance.DropdownButton == (Object)null || !((Behaviour)__instance.DropdownButton).isActiveAndEnabled) { return false; } if (__instance.Listing == null) { return false; } return true; } } } [HarmonyPatch] public static class ShopInterfacePatches { [HarmonyPatch(typeof(ShopInterface), "Awake")] public static class ShopInterfaceAwakePatch { public static void Prefix(ShopInterface __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { if (!ShopInterface.AllShops.Contains(__instance)) { ShopInterface.AllShops.Add(__instance); } } catch { } } } [HarmonyPatch(typeof(ShopInterface), "RefreshShownItems")] public static class RefreshShownItemsPatch { public static bool Prefix(ShopInterface __instance) { return ((__instance != null) ? __instance.listingUI : null) != null && (Object)(object)__instance.DetailPanel != (Object)null; } } [HarmonyPatch(typeof(ShopInterface), "Start")] public static class ShopInterfaceStartPatch { public static void Prefix(ShopInterface __instance) { if ((Object)(object)__instance.Canvas == (Object)null) { __instance.Canvas = ((Component)__instance).GetComponent<Canvas>() ?? ((Component)__instance).gameObject.AddComponent<Canvas>(); } if ((Object)(object)__instance.Container == (Object)null) { __instance.Container = ((Component)__instance).GetComponent<RectTransform>() ?? ((Component)__instance).gameObject.AddComponent<RectTransform>(); } } } } [HarmonyPatch] public static class VehiclePatches { [HarmonyPatch(typeof(VehicleCamera))] public static class VehicleCameraPatch { [HarmonyPatch("LateUpdate")] public static bool LateUpdate(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } [HarmonyPatch("Update")] public static bool Update(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } } [HarmonyPatch(typeof(DeliveryVehicle), "Deactivate")] public static class DeliveryVehicleDeactivatePatch { public static Instance Logger => new Instance("FurnitureDelivery-VehicleDeactivate"); public static bool Prefix(DeliveryVehicle __instance) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.Vehicle == (Object)null) { return true; } DeliveryInstance activeDelivery = __instance.ActiveDelivery; if (activeDelivery != null && (int)activeDelivery.Status == 3) { return true; } LandVehicle vehicle = __instance.Vehicle; string text = ((vehicle != null) ? ((Object)vehicle).name : null); if (string.IsNullOrEmpty(text)) { return true; } string text2 = (text.Contains("Dan") ? "Dan" : (text.Contains("Oscar") ? "Oscar" : null)); if (text2 == null) { return true; } DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; List<DeliveryShop> val = ((instance != null) ? instance.deliveryShops : null); DeliveryManager instance2 = NetworkSingleton<DeliveryManager>.Instance; if (val == null || (Object)(object)instance2 == (Object)null) { return true; } Enumerator<DeliveryShop> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { DeliveryShop current = enumerator.Current; if ((Object)(object)current != (Object)null && instance2.GetActiveShopDelivery(current) != null) { Logger.Warning(text2 + " has active delivery, not deactivating"); return false; } } return true; } } [HarmonyPatch(typeof(DeliveryVehicle), "Awake")] public static class DeliveryVehicleAwakePatch { [HarmonyPrefix] [HarmonyPriority(800)] public static bool Prefix(DeliveryVehicle __instance) { Guid val = default(Guid); if (Guid.TryParse(__instance.GUID, ref val)) { return true; } if ((Object)(object)((Component)__instance).GetComponent<LandVehicle>() == (Object)null) { return false; } __instance.Vehicle = ((Component)__instance).GetComponent<LandVehicle>(); __instance.Deactivate(); return false; } } } [HarmonyPatch] public static class WheelPatches { [HarmonyPatch(typeof(Wheel))] public static class WheelPatch { [HarmonyPatch("OnWeatherChange")] public static bool Prefix(Wheel __instance, WeatherConditions newConditions) { if ((Object)(object)((__instance != null) ? __instance.vehicle : null) == (Object)null) { return false; } if (newConditions != null) { _ = newConditions.Rainy; if (0 == 0) { return true; } } return false; } } } } namespace FurnitureDelivery.Interop { [HarmonyPatch(typeof(Cart))] internal static class CartPatches { [HarmonyPatch("UpdateTotal")] [HarmonyPrefix] private static bool UpdateTotal(Cart __instance) { return (Object)(object)__instance.TotalText != (Object)null; } [HarmonyPatch("UpdateProblem")] [HarmonyPrefix] private static bool UpdateProblem(Cart __instance) { return (Object)(object)__instance.ProblemText != (Object)null; } } public class DeliveryAppPlusPlusInterop { private static Instance _logger = new Instance("FurnitureDelivery-DeliveryAppPlusPlusInterop"); public static void ApplyPatches() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown Harmony harmonyInstance = ((MelonBase)Melon<FurnitureDelivery>.Instance).HarmonyInstance; Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "DeliveryAppPlusPlus"); if (assembly == null) { _logger.Error("Target assembly not found!"); return; } Type type = assembly.GetType("FavouriteDeliveriesPatch.DeliveryInfo"); if (type == null) { _logger.Error("DeliveryInfo type not found!"); return; } Type type2 = assembly.GetType("FavouriteDeliveriesPatch.DeliveryUtils"); if (type2 == null) { _logger.Error("Target class not found!"); return; } MethodInfo methodInfo = AccessTools.Method(type2, "OnReorder", new Type[1] { type }, (Type[])null); if (methodInfo == null) { _logger.Error("OnReorder method not found!"); } else { harmonyInstance.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(DeliveryAppPlusPlusInterop).GetMethod("OnReorder_Prefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool OnReorder_Prefix(Il2CppObjectBase __0) { try { Type type = ((object)__0).GetType(); FieldInfo field = type.GetField("instance", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { MelonLogger.Warning("[Added by FurnitureDelivery] Could not find 'instance' field on DeliveryInfo."); return false; } object value = field.GetValue(__0); if (value == null) { MelonLogger.Warning("[Added by FurnitureDelivery] 'instance' field was null."); return false; } if (!(value.GetType().GetProperty("StoreName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value) is string text)) { MelonLogger.Warning("[Added by FurnitureDelivery] 'StoreName' property was null."); return false; } DeliveryShop shop = PlayerSingleton<DeliveryApp>.Instance.GetShop(text); bool __result = true; string reason = ""; DeliveryShopPatches.CanOrder.Prefix(shop, ref __result, ref reason); if (!string.IsNullOrEmpty(reason)) { MelonLogger.Msg("[Added by FurnitureDelivery] Tried to order, but got " + reason); return false; } return true; } catch (Exception value2) { MelonLogger.Error($"[Added by FurnitureDelivery] Failed to reflect DeliveryInfo: {value2}"); } return false; } } public static class MoreGunsInterop { public static Instance Logger = new Instance("FurnitureDelivery-MoreGunsInterop"); public static bool TryGetPrices(string weaponID, out float gunPrice, out float magPrice) { gunPrice = 0f; magPrice = 0f; string text = "MoreGuns-" + weaponID + " Settings"; MelonPreferences_Category category = MelonPreferences.GetCategory(text); if (category == null) { Logger.Warning("Could not find category: " + text); return false; } MelonPreferences_Entry<float> entry = category.GetEntry<float>(weaponID + " Price"); MelonPreferences_Entry<float> entry2 = category.GetEntry<float>(weaponID + " Magazine Price"); if (entry == null || entry2 == null) { Logger.Warning("Missing price entries for '" + weaponID + "'"); return false; } gunPrice = entry.Value; magPrice = entry2.Value; return true; } } public static class ToileportationInterop { [HarmonyPatch(typeof(ShopListing), "Initialize")] public static class ToileportationShopListingPatch { public static void Postfix(ShopListing __instance) { if (!MelonTypeBase<MelonMod>.RegisteredMelons.All((MelonMod m) => ((MelonBase)m).Info.Name != "Toileportation") && __instance != null && !string.IsNullOrEmpty(__instance.name) && __instance.name.Contains("Golden Toilet")) { GoldenToiletListing = __instance; Logger.Msg("Captured Golden Toilet listing"); } } } public static Instance Logger = new Instance("FurnitureDelivery-ToileportationInterop"); public static ShopListing GoldenToiletListing; public static bool CanOrder(List<DeliveryShop> shops, out string reason) { reason = string.Empty; if (MelonTypeBase<MelonMod>.RegisteredMelons.All((MelonMod m) => ((MelonBase)m).Info.Name != "Toileportation")) { return true; } int currentStock = GoldenToiletListing.CurrentStock; foreach (DeliveryShop shop in shops) { List<ListingEntry> listingEntries = shop.listingEntries; Enumerator<ListingEntry> enumerator2 = listingEntries.GetEnumerator(); while (enumerator2.MoveNext()) { ListingEntry current2 = enumerator2.Current; if ((Object)(object)current2 == (Object)null || !((BaseItemDefinition)current2.MatchingListing.Item).Name.Contains("Golden Toilet") || current2.SelectedQuantity <= currentStock) { continue; } reason = "Not enough Golden Toilets in stock"; return false; } } return true; } public static void OnDeliveryCreated(DeliveryInstance delivery) { if (delivery == null) { return; } Il2CppReferenceArray<StringIntPair> items = delivery.Items; Logger.Debug($"Delivery created with {((Il2CppArrayBase<StringIntPair>)(object)items).Length} items"); foreach (StringIntPair item in (Il2CppArrayBase<StringIntPair>)(object)items) { Logger.Debug($"Checking item {item.String} in quantity {item.Int}"); if (item.String == "goldentoilet") { Logger.Debug("Found Golden Toilet in delivery"); if (GoldenToiletListing.CurrentStock < item.Int) { Logger.Error("Delivering more Golden Toilets than in stock"); } ShopListing goldenToiletListing = GoldenToiletListing; goldenToiletListing.CurrentStock -= item.Int; Logger.Debug($"New stock: {GoldenToiletListing.CurrentStock}"); } } } } } namespace FurnitureDelivery.Helpers { public static class Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } public static List<T> ToIl2CppList<T>(this IEnumerable<T> source) { List<T> val = new List<T>(); foreach (T item in source) { val.Add(item); } return val; } public static List<T> ConvertToList<T>(this List<T> il2CppList) { List<T> list = new List<T>(); T[] collection = Il2CppArrayBase<T>.op_Implicit(il2CppList.ToArray()); list.AddRange(collection); return list; } public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { IEnumerable<T> result; if (list != null) { result = ((IEnumerable<T>)list._items).Take(list._size); } else { IEnumerable<T> enumerable = Array.Empty<T>(); result = enumerable; } return result; } } public class LandVehicleBuilder { private string _vehicleName = "CustomVehicle"; private string _vehicleCode = "shitbox"; private float _vehiclePrice = 1000f; private float _topSpeed = 60f; private bool _isPlayerOwned = true; private EVehicleColor _color = (EVehicleColor)16; public static List<LandVehicle> VehiclePrefabs = NetworkSingleton<VehicleManager>.Instance.VehiclePrefabs.ConvertToList<LandVehicle>(); public LandVehicleBuilder WithVehicleName(string vehicleName) { _vehicleName = vehicleName; return this; } public LandVehicleBuilder WithVehicleCode(string vehicleCode) { _vehicleCode = vehicleCode; return this; } public LandVehicleBuilder WithVehiclePrice(float vehiclePrice) { _vehiclePrice = vehiclePrice; return this; } public LandVehicleBuilder WithTopSpeed(float topSpeed) { _topSpeed = topSpeed; return this; } public LandVehicleBuilder WithPlayerOwned(bool isPlayerOwned) { _isPlayerOwned = isPlayerOwned; return this; } public LandVehicleBuilder WithColor(EVehicleColor color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) _color = color; return this; } public LandVehicle Build() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(130f, 50f, -250f); Quaternion identity = Quaternion.identity; if (!InstanceFinder.IsServer) { MelonLogger.Error("LandVehicleBuilder can only be used on the server."); return null; } LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(_vehicleCode); if ((Object)(object)vehiclePrefab == (Object)null) { MelonLogger.Error("Vehicle prefab with code '" + _vehicleCode + "' not found."); return null; } GameObject val = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject); LandVehicle component = val.GetComponent<LandVehicle>(); ((Component)component).transform.position = position; ((Component)component).transform.rotation = identity; Guid gUID = GUIDManager.GenerateUniqueGUID(); component.SetGUID(gUID); ((Object)component).name = _vehicleName; ((Object)((Component)component).gameObject).name = _vehicleName; component.vehicleName = _vehicleName; component.vehiclePrice = _vehiclePrice; component.TopSpeed = _topSpeed; component.SetIsPlayerOwned((NetworkConnection)null, _isPlayerOwned); if (_isPlayerOwned) { NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(component); } component.ApplyColor(_color); component.SetOwnedColor((NetworkConnection)null, _color); NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component); ((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).NetworkObject.Spawn(((Component)component).gameObject, (NetworkConnection)null, default(Scene)); VehicleSync.AddedVehicles.Add(((NetworkBehaviour)component).ObjectId, (_vehicleName, ((object)(Guid)(ref gUID)).ToString())); VehicleSync.SyncVehicles(); return component; } } public static class MelonLoggerExtensions { public static void Debug(this Instance logger, string message, bool stacktrace = true) { MelonDebug.Msg(stacktrace ? ("[" + GetCallerInfo() + "] " + message) : message); } private static string GetCallerInfo() { StackTrace stackTrace = new StackTrace(); for (int i = 2; i < stackTrace.FrameCount; i++) { StackFrame frame = stackTrace.GetFrame(i); MethodBase method = frame.GetMethod(); if (!(method?.DeclaringType == null)) { return method.DeclaringType.FullName + "." + method.Name; } } return "unknown"; } } public static class Registries { private static GameObject _fdRoot; public static GameObject FDRoot { get { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown object obj = _fdRoot; if (obj == null) { GameObject val = new GameObject("FurnitureDeliveryRoot"); _fdRoot = val; obj = (object)val; } return (GameObject)obj; } } public static Dictionary<LandVehicle, DeliveryVehicle> DeliveryVehicleRegistry { get; } = new Dictionary<LandVehicle, DeliveryVehicle>(); public static Dictionary<DeliveryShop, float> DeliveryFeeRegistry { get; } = new Dictionary<DeliveryShop, float>(); public static Dictionary<DeliveryShop, Sprite> ShopImageRegistry { get; } = new Dictionary<DeliveryShop, Sprite>(); public static Dictionary<string, int> ShopPositionRegistry { get; } = new Dictionary<string, int>(); public static int OriginalDeliveryShopsCount { get; set; } = -1; public static Instance Logger => new Instance("FurnitureDelivery-Registries"); public static void RegisterAvailableVehicles() { VehicleManager instance = NetworkSingleton<VehicleManager>.Instance; if ((Object)(object)instance == (Object)null || instance.AllVehicles == null) { Logger.Error("VehicleManager or AllVehicles is null."); return; } foreach (LandVehicle item in instance.AllVehicles.AsEnumerable<LandVehicle>()) { if (!((Object)(object)item == (Object)null) && !DeliveryVehicleRegistry.ContainsKey(item)) { DeliveryVehicleRegistry[item] = null; } } Logger.Debug($"Registered {DeliveryVehicleRegistry.Count} vehicles for lazy wrapping."); } public static DeliveryVehicle GetOrCreateDeliveryVehicle(LandVehicle vehicle) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)vehicle == (Object)null) { return null; } object obj; if (vehicle == null) { obj = null; } else { GameObject gameObject = ((Component)vehicle).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent<DeliveryVehicle>() : null); } if ((Object)obj != (Object)null) { return ((Component)vehicle).gameObject.GetComponent<DeliveryVehicle>(); } if (DeliveryVehicleRegistry.TryGetValue(vehicle, out var value) && (Object)(object)value != (Object)null) { Logger.Debug("Using cached DeliveryVehicle for " + ((Object)vehicle).name); if ((Object)(object)value.Vehicle != (Object)(object)vehicle) { Logger.Warning("Cached DeliveryVehicle's Vehicle does not match for " + ((Object)vehicle).name + ". Updating reference."); value.Vehicle = vehicle; } return value; } GameObject gameObject2 = ((Component)vehicle).gameObject; gameObject2.transform.SetParent(FDRoot.transform); DeliveryVehicle val = gameObject2.AddComponent<DeliveryVehicle>(); val.Vehicle = vehicle; Guid gUID = vehicle.GUID; val.GUID = ((object)(Guid)(ref gUID)).ToString(); Logger.Debug("Created new DeliveryVehicle for " + ((Object)vehicle).name + " with GUID " + val.GUID); DeliveryVehicleRegistry[vehicle] = val; return val; } public static void RegisterShopPosition(string shopName, int position) { ShopPositionRegistry[shopName] = position; } public static int GetShopPosition(string shopName) { int value; return ShopPositionRegistry.TryGetValue(shopName, out value) ? value : (-1); } public static void RegisterShopImage(DeliveryShop shop, Sprite image) { ShopImageRegistry.TryAdd(shop, image); } public static Sprite GetShopImage(DeliveryShop shop) { Sprite value; return ShopImageRegistry.TryGetValue(shop, out value) ? value : null; } public static void RegisterDeliveryFee(DeliveryShop shop, float fee) { DeliveryFeeRegistry.TryAdd(shop, fee); } public static void Clear() { DeliveryVehicleRegistry.Clear(); DeliveryFeeRegistry.Clear(); ShopImageRegistry.Clear(); ShopPositionRegistry.Clear(); OriginalDeliveryShopsCount = -1; if ((Object)(object)_fdRoot != (Object)null) { Object.Destroy((Object)(object)_fdRoot); _fdRoot = null; } Logger.Debug("Registries cleared"); } } public static class Utils { [CompilerGenerated] private sealed class <WaitForNetworkSingleton>d__6<T> : IEnumerator<object>, IEnumerator, IDisposable where T : NetworkSingleton<T> { private int <>1__state; private object <>2__current; public IEnumerator coroutine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetworkSingleton>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0044; case 1: <>1__state = -1; goto IL_0044; case 2: { <>1__state = -1; return false; } IL_0044: if (!NetworkSingleton<T>.InstanceExists) { <>2__current = null; <>1__state = 1; return true; } <>2__current = coroutine; <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForNotNull>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object obj; public float timeout; public Action onTimeout; public Action onFinish; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNotNull>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (obj == null) { if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForPlayer>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayer>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static Instance Logger = new Instance("FurnitureDelivery-Utils"); public static Sprite FindSprite(string spriteName) { try { foreach (Sprite item in Resources.FindObjectsOfTypeAll<Sprite>()) { if (((Object)item).name == spriteName) { Logger.Debug("Found sprite '" + spriteName + "' directly in loaded objects"); return item; } } return null; } catch (Exception ex) { Logger.Error("Error finding sprite '" + spriteName + "': " + ex.Message); return null; } } public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component { List<T> list = new List<T>(); if ((Object)(object)obj == (Object)null) { return list; } T[] array = Il2CppArrayBase<T>.op_Implicit(obj.GetComponents<T>()); if (array.Length != 0) { list.AddRange(array); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject)); } return list; } public static bool Is<T>(object obj, out T result) where T : Object { Object val = (Object)((obj is Object) ? obj : null); if (val != null) { Type val2 = Il2CppType.Of<T>(); Type il2CppType = val.GetIl2CppType(); if (val2.IsAssignableFrom(il2CppType)) { result = ((Il2CppObjectBase)val).TryCast<T>(); return result != null; } } result = default(T); return false; } public static List<StorableItemDefinition> GetAllStorableItemDefinitions() { List<ItemRegister> list = Singleton<Registry>.Instance.ItemRegistry.ConvertToList<ItemRegister>(); List<StorableItemDefinition> list2 = new List<StorableItemDefinition>(); foreach (ItemRegister item in list) { if (Utils.Is<StorableItemDefinition>((object)item.Definition, out StorableItemDefinition result)) { list2.Add(result); } else { Logger.Warning("Definition " + ((object)item.Definition)?.GetType().FullName + " is not a StorableItemDefinition"); } } return list2.ToList(); } [IteratorStateMachine(typeof(<WaitForNotNull>d__5))] public static IEnumerator WaitForNotNull([MaybeNull] object obj, float timeout = float.NaN, Action onTimeout = null, Action onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNotNull>d__5(0) { obj = obj, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } [IteratorStateMachine(typeof(<WaitForNetworkSingleton>d__6<>))] public static IEnumerator WaitForNetworkSingleton<T>(IEnumerator coroutine) where T : NetworkSingleton<T> { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetworkSingleton>d__6<T>(0) { coroutine = coroutine }; } [IteratorStateMachine(typeof(<WaitForPlayer>d__7))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayer>d__7(0) { routine = routine }; } public static T GetNotNullWithTimeout<T>(Func<T> getter, float timeout = 5f) where T : class { Stopwatch stopwatch = Stopwatch.StartNew(); while (stopwatch.Elapsed.TotalSeconds < (double)timeout) { T val = getter(); if (val != null) { return val; } Thread.Sleep(100); } Logger.Error("Timed out waiting for " + typeof(T).Name + " to be not null"); return null; } } } namespace FurnitureDelivery.Builders { public class DeliveryShopBuilder { private class DeliveryShopUIElementsLinker : UIElementsLinker { private readonly float _deliveryFee; private readonly bool _availableByDefault; public DeliveryShopUIElementsLinker(DeliveryShop shopInstance, ShopInterface shopInterface, Color shopColor, string shopName, string shopDescription, Sprite shopImage, DeliveryShop deliveryShopTemplate, float deliveryFee, bool availableByDefault) : base(shopInstance, shopInterface, shopColor, shopName, shopDescription, shopImage, deliveryShopTemplate) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) _deliveryFee = deliveryFee; _availableByDefault = availableByDefault; } protected override float GetDeliveryFee() { return _deliveryFee; } protected override bool GetAvailableByDefault() { return _availableByDefault; } } private string _shopName = "CustomShop"; private string _shopDescription = "Custom shop description"; private Sprite _shopImage; private Color _shopColor = Color.red; private float _deliveryFee = 100f; private bool _availableByDefault = true; private int _insertPosition = -1; private DeliveryVehicle _deliveryVehicle; private readonly List<ShopListing> _listings = new List<ShopListing>(); private readonly DeliveryShop _deliveryShopTemplate; private readonly DeliveryApp _deliveryApp; public static Instance Logger => new Instance("FurnitureDelivery-DeliveryShopBuilder"); public static Dictionary<DeliveryShop, float> DeliveryFeeRegistry => Registries.DeliveryFeeRegistry; internal static int OriginalDeliveryShopsCount { get { return Registries.OriginalDeliveryShopsCount; } set { Registries.OriginalDeliveryShopsCount = value; } } public DeliveryShopBuilder(DeliveryApp appInstance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) _deliveryApp = appInstance; List<DeliveryShop> source = ((IEnumerable<DeliveryShop>)((Component)appInstance).GetComponentsInChildren<DeliveryShop>(true)).Where((DeliveryShop ds) => (Object)(object)ds != (Object)null && ((Component)ds).transform.childCount > 0).ToList(); _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)((Component)ds).transform.Find("Container") != (Object)null && (Object)(object)((Component)ds).transform.Find("Dropshadow") != (Object)null && (Object)(object)ds.ListingEntryPrefab != (Object)null)); if (_deliveryShopTemplate == null) { _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)ds.ListingEntryPrefab != (Object)null && (Object)(object)ds.ListingContainer != (Object)null && ((Object)ds.ListingContainer).name == "Listings" && (Object)(object)ds.BackButton != (Object)null)); } if (_deliveryShopTemplate == null) { _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)ds.ListingEntryPrefab != (Object)null)); } if (_deliveryShopTemplate == null) { _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => ((Component)ds).transform.childCount > 0)); } if (_deliveryShopTemplate == null) { _deliveryShopTemplate = source.FirstOrDefault(); } if ((Object)(object)_deliveryShopTemplate == (Object)null) { Logger.Error("No DeliveryShop template found in app."); } } public DeliveryShopBuilder WithShopName(string name) { _shopName = name; return this; } public DeliveryShopBuilder WithShopDescription(string description) { _shopDescription = description; return this; } public DeliveryShopBuilder WithShopImage(Sprite image) { _shopImage = image; return this; } public DeliveryShopBuilder WithShopColor(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) _shopColor = color; return this; } public DeliveryShopBuilder WithDeliveryFee(float fee) { _deliveryFee = fee; return this; } public DeliveryShopBuilder SetAvailableByDefault(bool available) { _availableByDefault = available; return this; } public DeliveryShopBuilder WithDeliveryVehicle(DeliveryVehicle vehicle) { _deliveryVehicle = vehicle; return this; } public DeliveryShopBuilder SetPosition(int position) { _insertPosition = position; return this; } public DeliveryShopBuilder AddListing(StorableItemDefinition item, float? overridePrice = null, int quantity = 999) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0057: Expected O, but got Unknown _listings.Add(new ShopListing { name = ((Object)item).name, Item = item, CanBeDelivered = true, OverridePrice = true, OverriddenPrice = (overridePrice ?? item.BasePurchasePrice) }); return this; } public DeliveryShopBuilder AddListing(ShopListing listing) { _listings.Add(listing); return this; } public DeliveryShop Build() { Logger.Debug("Build() START for " + _shopName); if ((Object)(object)_deliveryShopTemplate == (Object)null) { Logger.Error("Cannot build delivery shop without template."); return null; } try { ShopInterface shopInterface = CreateShopInterface(); DeliveryShop val = CloneDeliveryShop(); if ((Object)(object)val == (Object)null) { return null; } LinkUIElements(val, shopInterface); InitializeShop(val, shopInterface); Registries.RegisterShopPosition(((Object)((Component)val).gameObject).name, _insertPosition); if ((Object)(object)_shopImage != (Object)null) { Registries.RegisterShopImage(val, _shopImage); } Logger.Debug("Built delivery shop: " + ((Object)val).name); return val; } catch (Exception ex) { Logger.Error("Build() FAILED for " + _shopName + ": " + ex.Message); return null; } } private ShopInterface CreateShopInterface() { ShopInterfaceBuilder shopInterfaceBuilder = new ShopInterfaceBuilder(_shopName, _shopDescription, _shopImage, _listings, GetOrCreateDeliveryVehicle(), _deliveryApp); return shopInterfaceBuilder.Build().shopInterface; } private DeliveryShop CloneDeliveryShop() { Transform val = ((Component)_deliveryApp).transform.Find("Container/Contents/Container/Shops/Order"); if ((Object)(object)val == (Object)null) { Logger.Error("Cannot find Order canvas!"); return null; } try { DeliveryShop val2 = Object.Instantiate<DeliveryShop>(_deliveryShopTemplate, val); Logger.Debug($"Cloned shop has {((Component)val2).transform.childCount} children"); return val2; } catch (Exception ex) { Logger.Error("Object.Instantiate failed: " + ex.Message); return null; } } private void LinkUIElements(DeliveryShop shopInstance, ShopInterface shopInterface) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) DeliveryShopUIElementsLinker deliveryShopUIElementsLinker = new DeliveryShopUIElementsLinker(shopInstance, shopInterface, _shopColor, _shopName, _shopDescription, _shopImage, _deliveryShopTemplate, _deliveryFee, _availableByDefault); deliveryShopUIElementsLinker.LinkAll(); } private void InitializeShop(DeliveryShop shopInstance, ShopInterface shopInterface) { ShopInitializer shopInitializer = new ShopInitializer(shopInstance, shopInterface); shopInitializer.Initialize(); } private DeliveryVehicle GetOrCreateDeliveryVehicle() { if ((Object)(object)_deliveryVehicle != (Object)null) { return _deliveryVehicle; } if (Registries.DeliveryVehicleRegistry.Count == 0) { Registries.RegisterAvailableVehicles(); } LandVehicle val = Registries.DeliveryVehicleRegistry.Keys.FirstOrDefault(); if ((Object)(object)val == (Object)null) { Logger.Error("No available vehicles registered."); return null; } return Registries.GetOrCreateDeliveryVehicle(val); } public static List<DeliveryShop> GetInitializedShops(DeliveryApp app, out Transform contentT) { contentT = ((Component)app).transform.Find("Container/Scroll View/Viewport/Content"); if ((Object)(object)contentT == (Object)null) { Logger.Debug("Could not find 'Container/Scroll View/Viewport/Content' under DeliveryApp"); return null; } List<DeliveryShop> list = new List<DeliveryShop>(); for (int i = 0; i < contentT.childCount; i++) { DeliveryShop component = ((Component)contentT.GetChild(i)).GetComponent<DeliveryShop>(); if ((Object)(object)component != (Object)null) { list.Add(component); } } return list; } public static void Apply(DeliveryApp app, DeliveryShop shop) { int num = Registries.GetShopPosition(((Object)((Component)shop).gameObject).name); if (num < 0) { num = app.deliveryShops.Count + num + 1; if (num < 0) { num = 0; } } if (num > app.deliveryShops.Count) { num = app.deliveryShops.Count; } if (num < app.deliveryShops.Count) { app.deliveryShops.Insert(num, shop); } else { app.deliveryShops.Add(shop); } ReorderButtons(app); Logger.Debug("Added new delivery shop to app: " + ((Object)shop).name + ", " + ((Object)((Component)shop).gameObject).name); } private static void ReorderButtons(DeliveryApp app) { if (app._shopElements == null || app._shopElements.Count == 0) { return; } ((IEnumerable<DeliveryShopElement>)app._shopElements._items).ToList().Sort(delegate(DeliveryShopElement a, DeliveryShopElement b) { if ((Object)(object)((a != null) ? a.Shop : null) == (Object)null || (Object)(object)((b != null) ? b.Shop : null) == (Object)null) { return 0; } int num = app.deliveryShops.IndexOf(a.Shop); int value = app.deliveryShops.IndexOf(b.Shop); return num.CompareTo(value); }); for (int i = 0; i < app._shopElements.Count; i++) { DeliveryShopElement val = app._shopElements[i]; object obj; if (val == null) { obj = null; } else { Button button = val.Button; obj = ((button != null) ? ((Component)button).gameObject : null); } if ((Object)obj != (Object)null) { ((Component)val.Button).transform.SetSiblingIndex(i); } } } } public class ShopInitializer { private readonly DeliveryShop _shopInstance; private readonly ShopInterface _shopInterface; public static Instance Logger => new Instance("FurnitureDelivery-ShopInitializer"); public ShopInitializer(DeliveryShop shopInstance, ShopInterface shopInterface) { _shopInstance = shopInstance; _shopInterface = shopInterface; } public void Initialize() { ((Component)_shopInstance).gameObject.SetActive(true); try { CreateListingEntries(); SetupButtonListeners(); Logger.Debug("Initialize complete"); } catch (Exception ex) { Logger.Error("Initialize failed: " + ex.Message); } ((Component)_shopInstance).gameObject.SetActive(false); } private void CreateListingEntries() { Enumerator<ShopListing> enumerator = _shopInterface.Listings.GetEnumerator(); while (enumerator.MoveNext()) { ShopListing current = enumerator.Current; if (!current.CanBeDelivered) { continue; } try { ListingEntry entry = Object.Instantiate<ListingEntry>(_shopInstance.ListingEntryPrefab, (Transform)(object)_shopInstance.ListingContainer); entry.Initialize(current); entry.onQuantityChanged.AddListener(UnityAction.op_Implicit((Action)_shopInstance.RefreshCart)); DeliveryShop shopInstance = _shopInstance; shopInstance.OnSelect += Action<DeliveryShop>.op_Implicit((Action<DeliveryShop>)delegate { entry.RefreshLocked(); }); _shopInstance.listingEntries.Add(entry); } catch (Exception ex) { Logger.Warning("Failed to create entry for " + current.name + ": " + ex.Message); } } } private void SetupButtonListeners() { if ((Object)(object)_shopInstance.BackButton != (Object)null) { ((UnityEventBase)_shopInstance.BackButton.onClick).RemoveAllListeners(); ((UnityEvent)_shopInstance.BackButton.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { _shopInstance.OnSelect?.Invoke(_shopInstance); })); } if ((Object)(object)_shopInstance.OrderButton != (Object)null) { ((UnityEventBase)_shopInstance.OrderButton.onClick).RemoveAllListeners(); ((UnityEvent)_shopInstance.OrderButton.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { _shopInstance.SubmitOrder(string.Empty); })); } if ((Object)(object)_shopInstance.DestinationDropdown != (Object)null) { ((UnityEventBase)_shopInstance.DestinationDropdown.onValueChanged).RemoveAllListeners(); ((UnityEvent<int>)(object)_shopInstance.DestinationDropdown.onValueChanged).AddListener(UnityAction<int>.op_Implicit((Action<int>)_shopInstance.DestinationDropdownSelected)); } if ((Object)(object)_shopInstance.LoadingDockDropdown != (Object)null) { ((UnityEventBase)_shopInstance.LoadingDockDropdown.onValueChanged).RemoveAllListeners(); ((UnityEvent<int>)(object)_shopInstance.LoadingDockDropdown.onValueChanged).AddListener(UnityAction<int>.op_Implicit((Action<int>)_shopInstance.LoadingDockDropdownSelected)); } } } public class ShopInterfaceBuilder { private readonly string _shopName; private readonly string _shopDescription; private readonly Sprite _shopImage; private readonly List<ShopListing> _listings; private readonly DeliveryVehicle _deliveryVehicle; private readonly DeliveryApp _deliveryApp; public static Instance Logger => new Instance("FurnitureDelivery-ShopInterfaceBuilder"); public ShopInterfaceBuilder(string shopName, string shopDescription, Sprite shopImage, List<ShopListing> listings, DeliveryVehicle deliveryVehicle, DeliveryApp deliveryApp) { _shopName = shopName; _shopDescription = shopDescription; _shopImage = shopImage; _listings = listings; _deliveryVehicle = deliveryVehicle; _deliveryApp = deliveryApp; } public (ShopInterface shopInterface, Cart cart) Build() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown GameObject val = new GameObject("ShopInterface_" + _shopName); val.transform.SetParent(Registries.FDRoot.transform); val.SetActive(false); ShopInterface val2 = val.AddComponent<ShopInterface>(); val2.ShopName = _shopName; val2.ShopDescription = _shopDescription; val2.Listings = _listings.ToIl2CppList(); foreach (ShopListing listing in _listings) { listing.Shop = val2; } val2.DeliveryVehicle = _deliveryVehicle; val2.ShopCode = _shopName; Cart item = (val2.Cart = BuildCart(val2)); ShopInterface val4 = FindTemplateShop(); if ((Object)(object)val4 != (Object)null) { val2.ListingUIPrefab = val4.ListingUIPrefab; if ((Object)(object)val2.ListingUIPrefab != (Object)null) { ((Component)val2.ListingUIPrefab).gameObject.SetActive(false); } } RegisterShopInterface(val2); Logger.Debug("Built ShopInterface: " + val2.ShopName); return (val2, item); } private Cart BuildCart(ShopInterface shopInterface) { Cart val = ((Component)shopInterface).gameObject.AddComponent<Cart>(); ((Object)val).name = "Cart_" + _shopName; val.Shop = shopInterface; val.TotalText = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>(); val.WarningText = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>(); val.ProblemText = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>(); val.LoadVehicleToggle = ((Component)val).gameObject.AddComponent<Toggle>(); val.CartArea = ((Component)val).gameObject.AddComponent<Image>(); val.EntryPrefab = CreateCa
FurnitureDelivery-Mono.dll
Decompiled a month 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.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using FishNet; using FishNet.Connection; using FishNet.Object; using FurnitureDelivery; using FurnitureDelivery.Builders; using FurnitureDelivery.Helpers; using FurnitureDelivery.Interop; using FurnitureDelivery.Patches; using FurnitureDelivery.Shops; using HarmonyLib; using MelonLoader; using Microsoft.CodeAnalysis; using ScheduleOne; using ScheduleOne.Core.Items.Framework; using ScheduleOne.Delivery; using ScheduleOne.DevUtilities; using ScheduleOne.ItemFramework; using ScheduleOne.Money; using ScheduleOne.Networking; using ScheduleOne.PlayerScripts; using ScheduleOne.UI.Phone.Delivery; using ScheduleOne.UI.Shop; using ScheduleOne.Vehicles; using ScheduleOne.Vehicles.Modification; using ScheduleOne.Weather; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(global::FurnitureDelivery.FurnitureDelivery), "FurnitureDelivery", "2.0.0", "k073l", null)] [assembly: MelonColor(1, 255, 215, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonOptionalDependencies(new string[] { "MoreGuns", "Toileportation", "UpgradedTrashCans", "DeliveryApp++", "MetalStorage", "Absurdely Better Delivery" })] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ScheduleOne.Core")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FurnitureDelivery-Mono")] [assembly: AssemblyConfiguration("Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+41864b126039ed05f0f977b1aa19d64115393efb")] [assembly: AssemblyProduct("FurnitureDelivery-Mono")] [assembly: AssemblyTitle("FurnitureDelivery-Mono")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public class VehicleSync { [CompilerGenerated] private sealed class <WaitForPayload>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int <attempt>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPayload>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <attempt>5__1 = 0; break; case 1: <>1__state = -1; <attempt>5__1++; break; } if (<attempt>5__1 < 10) { if (GetPayload()) { Logger.Debug("Vehicle sync payload received successfully"); return false; } Logger.Debug($"Attempt {<attempt>5__1 + 1}/{10}: No payload received, waiting {1f} seconds..."); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } Logger.Error("Failed to receive vehicle sync payload after maximum attempts"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static Dictionary<int, (string, string)> AddedVehicles = new Dictionary<int, (string, string)>(); public static Instance Logger = new Instance("FurnitureDelivery-VehicleSync"); private const string VehiclesKey = "FurnitureDelivery_Vehicles"; private const string Version = "1.0.0"; public static bool isHost = Singleton<Lobby>.Instance.IsHost; public static bool isClient = !Singleton<Lobby>.Instance.IsHost && Singleton<Lobby>.Instance.IsInLobby; public static bool isSingleplayer = !Singleton<Lobby>.Instance.IsInLobby; public static void SyncVehicles() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (isSingleplayer) { Logger.Msg("Not in a lobby, skipping vehicle sync"); return; } Logger.Debug($"Syncing {AddedVehicles.Count} vehicles to clients"); if (isHost) { string text = SerializeVehicles(AddedVehicles); Logger.Debug("Syncing vehicles to clients: " + text); if (!SteamMatchmaking.SetLobbyData(Singleton<Lobby>.Instance.LobbySteamID, "FurnitureDelivery_Vehicles", text)) { Logger.Error("Failed to set lobby data for vehicle sync"); } } else if (isClient) { Logger.Debug("Client detected, waiting for vehicle sync payload"); if (GetPayload()) { Logger.Debug("Vehicle sync payload received successfully"); } else { MelonCoroutines.Start(WaitForPayload()); } } } [IteratorStateMachine(typeof(<WaitForPayload>d__8))] public static IEnumerator WaitForPayload() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPayload>d__8(0); } private static bool GetPayload() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) string lobbyData = SteamMatchmaking.GetLobbyData(Singleton<Lobby>.Instance.LobbySteamID, "FurnitureDelivery_Vehicles"); if (!string.IsNullOrEmpty(lobbyData)) { Logger.Debug("Received vehicle sync payload: " + lobbyData); AddedVehicles = DeserializeVehicles(lobbyData); Logger.Msg($"Synced {AddedVehicles.Count} vehicles from payload"); return true; } Logger.Debug("No vehicle sync payload found"); return false; } private static string SerializeVehicles(Dictionary<int, (string, string)> vehicles) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[email protected];"); foreach (KeyValuePair<int, (string, string)> vehicle in vehicles) { stringBuilder.Append($"{vehicle.Key}:{vehicle.Value.Item1},{vehicle.Value.Item2};"); } return stringBuilder.ToString(); } private static Dictionary<int, (string, string)> DeserializeVehicles(string data) { Dictionary<int, (string, string)> dictionary = new Dictionary<int, (string, string)>(); if (string.IsNullOrEmpty(data)) { return dictionary; } string[] array = data.Split(';'); if (array.Length == 0 || !array[0].StartsWith("[email protected]")) { Logger.Error("Invalid vehicle sync data format"); return dictionary; } string[] array2 = array; foreach (string text in array2) { if (string.IsNullOrEmpty(text)) { continue; } string[] array3 = text.Split(':'); if (array3.Length == 2) { int key = int.Parse(array3[0]); string[] array4 = array3[1].Split(','); if (array4.Length == 2) { dictionary[key] = (array4[0], array4[1]); } } } return dictionary; } public static LandVehicle GetVehicleById(int id) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (AddedVehicles.TryGetValue(id, out var value)) { var (text, text2) = value; Logger.Debug($"Searching for vehicle with ID {id}, Name: {text}, GUID: {text2}"); Scene sceneByName = SceneManager.GetSceneByName("Main"); if (!((Scene)(ref sceneByName)).isLoaded) { Logger.Error("Main scene is not loaded."); return null; } GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects(); LandVehicle val = null; GameObject[] array = rootGameObjects; foreach (GameObject val2 in array) { val = ((IEnumerable<LandVehicle>)val2.GetComponentsInChildren<LandVehicle>(true)).FirstOrDefault((Func<LandVehicle, bool>)((LandVehicle v) => ((NetworkBehaviour)v).ObjectId == id)); if ((Object)(object)val != (Object)null) { break; } } if ((Object)(object)val == (Object)null) { Logger.Error($"Vehicle with ObjectId {id} not found in Main scene"); return null; } Guid result; Guid guid = (Guid.TryParse(text2, out result) ? result : Guid.Empty); Logger.Debug($"Setting the vehicle GUID to {guid}"); val.SetGUID(guid); Logger.Debug("Setting the vehicle go name to " + text); ((Object)val).name = text; Logger.Debug("Setting the vehicle vehicleName to " + text); val.vehicleName = text; Logger.Debug($"Found vehicle: {((Object)val).name} with GUID {val.GUID} and ObjectId {((NetworkBehaviour)val).ObjectId}"); return val; } Logger.Error($"Vehicle with ID {id} not found in AddedVehicles dictionary"); return null; } public static LandVehicle GetVehicleByName(string name) { Logger.Debug("Searching for vehicle by name: " + name); int key = AddedVehicles.FirstOrDefault((KeyValuePair<int, (string, string)> kvp) => kvp.Value.Item1.Contains(name)).Key; return (key != 0) ? GetVehicleById(key) : null; } } namespace FurnitureDelivery { public static class BuildInfo { public const string Name = "FurnitureDelivery"; public const string Description = "Adds a custom delivery shops for furniture items"; public const string Author = "k073l"; public const string Version = "2.0.0"; } public class FurnitureDelivery : MelonMod { [CompilerGenerated] private sealed class <OnDeliveryManagerReady>d__10 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnDeliveryManagerReady>d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; MelonLogger.Debug("Delivery manager ready"); NetworkSingleton<DeliveryManager>.Instance.onDeliveryCreated += delegate(DeliveryInstance di) { ToileportationInterop.OnDeliveryCreated(di); }; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Sprite _stanMugshot; private static Instance MelonLogger { get; set; } internal static Sprite StanMugshot => GetIcon(ref _stanMugshot, "FurnitureDelivery.assets.stan_mugshot.png"); public override void OnInitializeMelon() { MelonLogger = ((MelonBase)this).LoggerInstance; MelonLogger.Msg("FurnitureDelivery initialized"); if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("MoreGuns"))) { MelonLogger.Msg("MoreGuns detected. Adding ak47 to Armory"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("Toileportation"))) { MelonLogger.Msg("Toileportation detected. Adding Golden Toilet to Herbert's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("UpgradedTrashCans"))) { MelonLogger.Msg("UpgradedTrashCans detected. Adding trash bins to Dan's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("MetalStorage"))) { MelonLogger.Msg("MetalStorage detected. Adding metal storage racks to Dan's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("BigSprinklerLogic"))) { MelonLogger.Msg("BigSprinklerLogic detected. Adding big sprinkler to Dan's shop"); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("Toileportation"))) { if (!(sceneName == "Main")) { if (sceneName == "Menu") { if ((Object)(object)NetworkSingleton<DeliveryManager>.Instance != (Object)null) { NetworkSingleton<DeliveryManager>.Instance.onDeliveryCreated += delegate(DeliveryInstance di) { ToileportationInterop.OnDeliveryCreated(di); }; } ToileportationInterop.GoldenToiletListing = null; } } else { MelonCoroutines.Start(Utils.WaitForNetworkSingleton<DeliveryManager>(OnDeliveryManagerReady())); } } if (!(sceneName == "Main")) { if (sceneName == "Menu") { } } else if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("DeliveryApp++"))) { MelonLogger.Msg("DeliveryAppPlusPlus detected. Applying patches"); DeliveryAppPlusPlusInterop.ApplyPatches(); } } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { if (sceneName == "Main") { DeliveryAppPatches.Start.Initialized = false; DeliveryAppPatches.Awake.AddedShops = false; Registries.Clear(); MelonLogger.Msg("Scene unloaded, reset initialization flags and registries"); } } [IteratorStateMachine(typeof(<OnDeliveryManagerReady>d__10))] private static IEnumerator OnDeliveryManagerReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnDeliveryManagerReady>d__10(0); } private static Sprite LoadEmbeddedPNG(string resourceName) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(resourceName); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2); if (!ImageConversion.LoadImage(val, array)) { return null; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); if ((Object)(object)val2 != (Object)null) { ((Object)val2).name = resourceName; } return val2; } private static Sprite GetIcon(ref Sprite spriteField, string resourceName) { if ((Object)(object)spriteField == (Object)null) { spriteField = LoadEmbeddedPNG(resourceName); } return spriteField; } } [HarmonyPatch(typeof(VehicleCamera))] public static class VehicleCameraPatch { [HarmonyPrefix] [HarmonyPatch("LateUpdate")] public static bool SafeLateUpdatePrefix(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } [HarmonyPrefix] [HarmonyPatch("Update")] public static bool SafeUpdatePrefix(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } } [HarmonyPatch(typeof(DeliveryVehicle), "Deactivate")] public static class DeliveryVehicleDeactivatePatch { public static Instance Logger = new Instance("FurnitureDelivery-VehicleDeactivate"); public static bool Prefix(DeliveryVehicle __instance) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)__instance.Vehicle == (Object)null) { return true; } DeliveryInstance activeDelivery = __instance.ActiveDelivery; if (activeDelivery != null && (int)activeDelivery.Status == 3) { return true; } LandVehicle vehicle = __instance.Vehicle; string text = ((vehicle != null) ? ((Object)vehicle).name : null); if (string.IsNullOrEmpty(text)) { return true; } string text2 = null; if (text.Contains("Dan")) { text2 = "Dan"; } else if (text.Contains("Oscar")) { text2 = "Oscar"; } if (!string.IsNullOrEmpty(text2)) { List<DeliveryShop> list = PlayerSingleton<DeliveryApp>.Instance?.deliveryShops; if (list == null) { return true; } DeliveryManager instance = NetworkSingleton<DeliveryManager>.Instance; if ((Object)(object)instance == (Object)null) { Logger.Debug("NetworkSingleton<DeliveryManager>.Instance is null"); return true; } foreach (DeliveryShop item in list) { if (instance.GetActiveShopDelivery(item) != null) { Logger.Warning(text2 + " is currently delivering an order, not deactivating the vehicle"); return false; } } } return true; } } [HarmonyPatch(typeof(ListingUI))] public static class ListingUICanAddToCartPatch { [HarmonyPatch("CanAddToCart")] [HarmonyPrefix] public static bool PrefixCanAddToCart(ListingUI __instance, ref bool __result) { if (__instance.Listing == null) { __result = false; return false; } return true; } [HarmonyPatch("UpdateButtons")] [HarmonyPrefix] public static bool PrefixUpdateButtons(ListingUI __instance) { if ((Object)(object)__instance == (Object)null) { return false; } if ((Object)(object)__instance.BuyButton == (Object)null) { return false; } if (!((Behaviour)__instance.BuyButton).isActiveAndEnabled) { return false; } if ((Object)(object)__instance.DropdownButton == (Object)null) { return false; } if (!((Behaviour)__instance.DropdownButton).isActiveAndEnabled) { return false; } if (__instance.Listing == null) { return false; } return true; } } [HarmonyPatch(typeof(Wheel))] internal class WheelPatch { [HarmonyPatch("OnWeatherChange")] [HarmonyPrefix] private static bool ExitIfNull(Wheel __instance, WeatherConditions newConditions) { if ((Object)(object)__instance?.vehicle == (Object)null) { return false; } if (newConditions != null) { _ = newConditions.Rainy; if (0 == 0) { return true; } } return false; } } [HarmonyPatch(typeof(DeliveryVehicle))] internal static class DeliveryVehicleAwakePatch { [HarmonyPatch("Awake")] [HarmonyPrefix] [HarmonyPriority(800)] private static bool ExitIfNull(DeliveryVehicle __instance) { if (Guid.TryParse(__instance.GUID, out var _)) { return true; } if ((Object)(object)((Component)__instance).GetComponent<LandVehicle>() == (Object)null) { return false; } __instance.Vehicle = ((Component)__instance).GetComponent<LandVehicle>(); __instance.Deactivate(); return false; } } [HarmonyPatch(typeof(ShopInterface))] internal static class ShopInterfacePatch { public static Instance Logger => new Instance("FurnitureDelivery-ShopInterfacePatch"); [HarmonyPatch("Awake")] [HarmonyPrefix] private static void EnsureInAllShops(ShopInterface __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { if (!ShopInterface.AllShops.Contains(__instance)) { ShopInterface.AllShops.Add(__instance); Logger.Debug("Added ShopInterface to AllShops: " + __instance.ShopName); } } catch (Exception ex) { Logger.Error("Failed to add ShopInterface to AllShops: " + ex.Message); } } [HarmonyPatch("RefreshShownItems")] [HarmonyPrefix] private static bool ExitIfUINull(ShopInterface __instance) { if (__instance?.listingUI == null || (Object)(object)__instance.DetailPanel == (Object)null) { return false; } return true; } [HarmonyPatch("Start")] [HarmonyPrefix] private static void AddMissingMembers(ShopInterface __instance) { if ((Object)(object)__instance.Canvas == (Object)null) { __instance.Canvas = ((Component)__instance).GetComponent<Canvas>() ?? ((Component)__instance).gameObject.AddComponent<Canvas>(); } if ((Object)(object)__instance.Container == (Object)null) { __instance.Container = ((Component)__instance).GetComponent<RectTransform>() ?? ((Component)__instance).gameObject.AddComponent<RectTransform>(); } } } public static class ShopRegistry { private static readonly List<ICustomShop> _shops = new List<ICustomShop>(4) { new DanShop(), new HerbertShop(), new OscarShop(), new StanShop() }; public static IReadOnlyList<ICustomShop> Shops => _shops.AsReadOnly(); public static string GetShopName(this ICustomShop shop) { return shop.ShopName; } } } namespace FurnitureDelivery.Shops { public class DanShop : ICustomShop { public static Instance Logger = new Instance("FurnitureDelivery-DanShop"); public string ShopName => "DeliveryShop_Dan's Furniture"; public List<string> ItemIDs => new List<string> { "coffeetable", "metalsquaretable", "woodsquaretable", "plastictable", "toilet", "trashcan", "trash_bin", "trash_compactor", "bed", "locker", "TV", "acunit", "floorlamp", "growtent", "plasticpot", "halogengrowlight", "ledgrowlight", "suspensionrack", "soilpourer", "potsprinkler", "bigsprinkler", "largestoragerack", "mediumstoragerack", "smallstoragerack", "metallargestoragerack", "metalmediumstoragerack", "metalsmallstoragerack", "smallstoragecloset", "mediumstoragecloset", "largestoragecloset", "hugestoragecloset" }; public DeliveryShop CreateShop(DeliveryApp app) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Dan's Furniture shop"); LandVehicle val = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable().FirstOrDefault((Func<LandVehicle, bool>)((LandVehicle item) => (Object)(object)item != (Object)null && ((Object)item).name.Contains("Dan"))); Logger.Debug($"Found delivery vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Dan's Furniture").WithShopDescription("General furniture").WithShopColor(new Color(0.06f, 0.56f, 0.87f)) .WithShopImage(Utils.FindSprite("Dan_Mugshot")) .WithDeliveryFee(300f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(4); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((BaseItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding item " + ((Object)item).name + " to Dan's shop"); deliveryShopBuilder.AddListing(item); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Dan's Furniture created"); return val2; } } public class HerbertShop : ICustomShop { public static Instance Logger = new Instance("FurnitureDelivery-HerbertShop"); public string ShopName => "DeliveryShop_Herbert"; public List<string> ItemIDs => new List<string> { "woodensign", "metalsign", "wallmountedshelf", "antiquewalllamp", "modernwalllamp", "wallclock", "grandfatherclock", "safe", "jukebox", "goldenskateboard", "filingcabinet", "smalltrashcan", "dumpster", "garbagethrone" }; public DeliveryShop CreateShop(DeliveryApp app) { //IL_0127: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Herbert's shop"); LandVehicle val = null; if (!InstanceFinder.IsServer) { Logger.Debug("Syncing vehicles"); VehicleSync.SyncVehicles(); Logger.Debug("Not on server, trying to find Herbert's land vehicle"); val = Utils.GetNotNullWithTimeout(() => VehicleSync.GetVehicleByName("LandVehicle_Herbert")); } else { Logger.Debug("On server, creating Herbert's land vehicle"); val = new LandVehicleBuilder().WithVehicleName("LandVehicle_Herbert").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)11) .Build(); } Logger.Debug($"Found land vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Herbert's Curiosities").WithShopDescription("Boutique's picks and exotic items").WithShopColor(new Color(0.2f, 0f, 1f)) .WithShopImage(Utils.FindSprite("Herbert_Mugshot")) .WithDeliveryFee(500f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(5); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((BaseItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding item " + ((Object)item).name + " to Herbert's shop"); deliveryShopBuilder.AddListing(item); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "Toileportation")) { ShopListing goldenToiletListing = ToileportationInterop.GoldenToiletListing; if (goldenToiletListing == null) { Logger.Warning("Golden toilet listing not found, waiting for it to be created"); MelonCoroutines.Start(Utils.WaitForNotNull(goldenToiletListing)); } goldenToiletListing.CanBeDelivered = true; Logger.Msg("Adding golden toilet to Herbert's shop"); deliveryShopBuilder.AddListing(goldenToiletListing); Logger.Debug($"{goldenToiletListing.Shop}, {goldenToiletListing.CurrentStock}, {goldenToiletListing.Item.BasePurchasePrice}, {((BaseItemDefinition)goldenToiletListing.Item).ID}"); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Herbert's Curiosities created"); return val2; } } public interface ICustomShop { List<string> ItemIDs { get; } string ShopName { get; } DeliveryShop CreateShop(DeliveryApp app); } public class OscarShop : ICustomShop { public static Instance Logger = new Instance("FurnitureDelivery-OscarShop"); public string ShopName => "DeliveryShop_Oscar"; public List<string> ItemIDs => new List<string> { "moisturepreservingpot", "airpot", "fullspectrumgrowlight", "suspensionrack", "packagingstation", "packagingstationmk2", "mixingstation", "mixingstationmk2", "mushroomspawnstation", "mushroombed", "dryingrack", "chemistrystation", "laboven", "cauldron", "brickpress", "locker" }; public DeliveryShop CreateShop(DeliveryApp app) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Oscar's Equipment shop"); LandVehicle val = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable().FirstOrDefault((Func<LandVehicle, bool>)((LandVehicle item) => (Object)(object)item != (Object)null && ((Object)item).name.Contains("Oscar"))); if ((Object)(object)val == (Object)null) { Logger.Warning("Oscar delivery vehicle not found, using default vehicle"); val = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable().FirstOrDefault(); } Logger.Debug($"Found delivery vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Oscar's Equipment").WithShopDescription("'Specialized' equipment").WithDeliveryFee(350f) .WithShopColor(new Color(0.87f, 0.44f, 0.05f)) .WithShopImage(Utils.FindSprite("Oscar_Mugshot")) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(7); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((BaseItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding " + ((BaseItemDefinition)item).ID + " to Oscar's shop"); deliveryShopBuilder.AddListing(item); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Oscar's Equipment created"); return val2; } } public class StanShop : ICustomShop { public static readonly Dictionary<string, float> ItemPrices = new Dictionary<string, float> { { "baseballbat", 50f }, { "fryingpan", 100f }, { "machete", 250f }, { "revolver", 1000f }, { "revolvercylinder", 10f }, { "m1911", 2500f }, { "goldenm1911", 25000f }, { "m1911mag", 20f }, { "pumpshotgun", 7500f }, { "shotgunshell", 5f }, { "ak47", 15000f }, { "ak47mag", 1000f }, { "minigun", 75000f }, { "minigunmag", 10000f } }; public static Instance Logger = new Instance("FurnitureDelivery-StanShop"); public string ShopName => "DeliveryShop_Armory"; public List<string> ItemIDs => ItemPrices.Keys.ToList(); public DeliveryShop CreateShop(DeliveryApp app) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Stan's shop"); LandVehicle val = null; if (!InstanceFinder.IsServer) { Logger.Debug("Syncing vehicles"); VehicleSync.SyncVehicles(); Logger.Debug("Not on server, trying to find Stan's land vehicle"); val = Utils.GetNotNullWithTimeout(() => VehicleSync.GetVehicleByName("LandVehicle_Stan")); } else { Logger.Debug("On server, creating Stan's land vehicle"); val = new LandVehicleBuilder().WithVehicleName("LandVehicle_Stan").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)0) .Build(); } Logger.Debug($"Found delivery vehicle: {((val != null) ? ((Object)val).name : null)} with guid {((val != null) ? new Guid?(val.GUID) : null)}"); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Armory").WithShopDescription("Weapons and ammo").WithShopColor(new Color(0.8f, 0f, 0f)) .WithShopImage(FurnitureDelivery.StanMugshot) .WithDeliveryFee(800f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(Registries.GetOrCreateDeliveryVehicle(val)) .SetPosition(8); List<StorableItemDefinition> allStorableItemDefinitions = Utils.GetAllStorableItemDefinitions(); Dictionary<string, StorableItemDefinition> itemMap = allStorableItemDefinitions.ToDictionary((StorableItemDefinition i) => ((BaseItemDefinition)i).ID); List<GunItem> list = (from kvp in ItemPrices where itemMap.ContainsKey(kvp.Key) select new GunItem { Item = (ItemDefinition)(object)itemMap[kvp.Key], BasePrice = kvp.Value }).ToList(); foreach (GunItem item in list) { Logger.Debug("Adding item " + ((BaseItemDefinition)item.Item).ID + " to Stan's shop"); float num = item.BasePrice; string iD = ((BaseItemDefinition)item.Item).ID; if (1 == 0) { } string text; switch (iD) { case "ak47": case "ak47mag": text = "ak47"; break; case "minigun": case "minigunmag": text = "minigun"; break; default: text = null; break; } if (1 == 0) { } string text2 = text; if (text2 != null && MoreGunsInterop.TryGetPrices(text2, out var gunPrice, out var magPrice)) { num = ((((BaseItemDefinition)item.Item).ID == text2) ? gunPrice : magPrice); Logger.Msg($"Using MoreGuns price for '{((BaseItemDefinition)item.Item).ID}': {num}"); } if (Utils.Is<StorableItemDefinition>(item.Item, out var result)) { deliveryShopBuilder.AddListing(result, num); } } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Stan's shop created"); return val2; } } public class GunItem { public ItemDefinition Item { get; set; } public float BasePrice { get; set; } } } namespace FurnitureDelivery.Shops.UI { public static class UIPathConstants { public const string Container = "Container"; public const string Header = "Container/Header"; public const string Listings = "Listings"; public const string ListingContainer = "ListingContainer"; public const string Entries = "Entries"; public const string BackButton = "Container/BackButton"; public const string Confirm = "Container/Confirm"; public const string DestinationDropdown = "Container/DestinationDropdown"; public const string LoadingDockDropdown = "Container/LoadingDockDropdown"; public const string ItemTotal = "Container/ItemTotal/Amount"; public const string OrderTotal = "Container/OrderTotal/Amount"; public const string DeliveryFee = "Container/DeliveryFee/Amount"; public const string DeliveryTime = "Container/DeliveryTime"; public const string Dropshadow = "Dropshadow"; public const string Order = "Container/Contents/Container/Shops/Order"; public const string ScrollViewContent = "Container/Scroll View/Viewport/Content"; public const string IconImage = "Container/Icon/Image"; public const string Title = "Container/Labels/Container/Title"; public const string Description = "Container/Labels/Container/Description"; public const string HeaderFallback = "Header"; public const string BackButtonFallback = "BackButton"; public const string OrderButtonFallback = "OrderButton"; public const string DestinationDropdownFallback = "DestinationDropdown"; public const string LoadingDockDropdownFallback = "LoadingDockDropdown"; public const string DeliveryTimeLabelFallback = "DeliveryTimeLabel"; public const string ItemTotalLabelFallback = "ItemTotalLabel"; public const string OrderTotalLabelFallback = "OrderTotalLabel"; public const string DeliveryFeeLabelFallback = "DeliveryFeeLabel"; } } namespace FurnitureDelivery.Patches { [HarmonyPatch] public static class DeliveryAppPatches { [HarmonyPatch(typeof(DeliveryApp), "SetIsAvailable")] public class SetIsAvailable { public static bool Prefix(DeliveryApp __instance, ShopInterface matchingShop) { Logger.Debug("SetIsAvailable: " + matchingShop?.ShopName); return true; } public static void Postfix(DeliveryApp __instance, ShopInterface matchingShop) { try { if (matchingShop?.ShopName == null || (Object)(object)((Component)matchingShop).gameObject == (Object)null) { return; } DeliveryApp val = __instance ?? PlayerSingleton<DeliveryApp>.Instance; if (val?.deliveryShops == null || !(matchingShop.ShopName == "Oscar's Store")) { return; } bool activeSelf = ((Component)matchingShop).gameObject.activeSelf; foreach (DeliveryShop deliveryShop in val.deliveryShops) { if (!((Object)(object)deliveryShop == (Object)null) && !((Object)(object)((Component)deliveryShop).gameObject == (Object)null) && !((Object)((Component)deliveryShop).gameObject).name.StartsWith("DeliveryShop_") && (((Object)((Component)deliveryShop).gameObject).name.Contains("Oscar") || ((Object)((Component)deliveryShop).gameObject).name.Contains("Armory"))) { SyncButtonVisibility(val, deliveryShop, activeSelf); } } } catch (Exception ex) { Logger.Error("SetIsAvailable postfix error: " + ex.Message); } } private static void SyncButtonVisibility(DeliveryApp app, DeliveryShop targetShop, bool visible) { if (app?._shopElements == null || (Object)(object)targetShop == (Object)null) { return; } DeliveryShopElement val = app._shopElements?.AsEnumerable().FirstOrDefault((Func<DeliveryShopElement, bool>)((DeliveryShopElement e) => (Object)(object)e?.Shop == (Object)(object)targetShop)); if (val == null) { return; } Button button = val.Button; if (button != null) { GameObject gameObject = ((Component)button).gameObject; if (gameObject != null) { gameObject.SetActive(visible); } } } } [HarmonyPatch(typeof(DeliveryApp), "Awake")] public class Awake { public static bool AddedShops; public static void Prefix() { AddedShops = false; } } [HarmonyPatch(typeof(DeliveryApp), "Start")] public class Start { public static bool Initialized; public static void Postfix(DeliveryApp __instance) { if (Initialized) { return; } Initialized = true; Logger.Msg("DeliveryApp.Start running"); int num = (DeliveryShopBuilder.OriginalDeliveryShopsCount = __instance.deliveryShops.Count); Logger.Msg($"Set OriginalDeliveryShopsCount = {DeliveryShopBuilder.OriginalDeliveryShopsCount} (deliveryShops.Count = {num})"); foreach (ICustomShop shop in ShopRegistry.Shops) { try { Logger.Msg("Creating shop: " + shop.GetType().Name); shop.CreateShop(__instance); } catch (Exception ex) { Logger.Error("Failed to create shop: " + ex.Message); } } foreach (ICustomShop shop2 in ShopRegistry.Shops) { string shopName = shop2.GetShopName(); DeliveryShop customShop = __instance.deliveryShops.AsEnumerable().FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)ds != (Object)null && ((Object)((Component)ds).gameObject).name.Contains(shopName))); if (!((Object)(object)customShop == (Object)null) && !((Object)(object)customShop.MatchingShop == (Object)null)) { if (__instance._shopElements.AsEnumerable().Any((DeliveryShopElement e) => (Object)(object)e?.Shop == (Object)(object)customShop)) { TryInitializeShop(customShop); continue; } CreateShopButton(__instance, customShop); TryInitializeShop(customShop); } } } private static void CreateShopButton(DeliveryApp app, DeliveryShop customShop) { //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Expected O, but got Unknown if (app._shopElements == null || app._shopElements.Count == 0) { return; } DeliveryShopElement val = app._shopElements[0]; object obj; if (val == null) { obj = null; } else { Button button = val.Button; obj = ((button != null) ? ((Component)button).gameObject : null); } if ((Object)obj == (Object)null) { return; } GameObject gameObject = ((Component)val.Button).gameObject; Transform parent = gameObject.transform.parent; GameObject val2 = Object.Instantiate<GameObject>(gameObject, parent); ((Object)val2).name = customShop.MatchingShop.ShopName + "Button"; val2.SetActive(true); int num = app.deliveryShops.IndexOf(customShop); if (num >= 0) { val2.transform.SetSiblingIndex(num); } Text[] componentsInChildren = val2.GetComponentsInChildren<Text>(); foreach (Text val3 in componentsInChildren) { Text val4 = val3; string name = ((Object)((Component)val3).gameObject).name; if (1 == 0) { } string text = ((name == "Title") ? customShop.MatchingShop.ShopName : ((!(name == "Description")) ? val3.text : customShop.MatchingShop.ShopDescription)); if (1 == 0) { } val4.text = text; } Image[] componentsInChildren2 = val2.GetComponentsInChildren<Image>(); foreach (Image val5 in componentsInChildren2) { if (((Object)((Component)val5).gameObject).name == "Image") { val5.sprite = Registries.GetShopImage(customShop); } } if (Utils.Is<Image>(val2.GetComponent<Image>(), out var result)) { ((Graphic)result).color = customShop.ShopColor; } Button component = val2.GetComponent<Button>(); if ((Object)(object)component != (Object)null) { ((UnityEventBase)component.onClick).RemoveAllListeners(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { app.OpenShop(customShop); }); DeliveryShop obj2 = customShop; obj2.OnSelect = (Action<DeliveryShop>)Delegate.Combine(obj2.OnSelect, new Action<DeliveryShop>(app.CloseShop)); } int index = ((num >= 0 && num <= app._shopElements.Count) ? num : app._shopElements.Count); app._shopElements.Insert(index, new DeliveryShopElement { Shop = customShop, Button = component }); } private static void TryInitializeShop(DeliveryShop shop) { //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Expected O, but got Unknown //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Expected O, but got Unknown if ((Object)(object)shop == (Object)null) { return; } if ((Object)(object)shop.MatchingShop != (Object)null && (Object)(object)shop.ListingContainer != (Object)null && shop.listingEntries.Count > 0) { Logger.Debug("Shop already initialized: " + ((Object)shop).name); return; } Instance logger = Logger; string arg = shop.MatchingShop?.ShopName; RectTransform listingContainer = shop.ListingContainer; logger.Debug($"Setup shop - MatchingShop: {arg}, ListingContainer: {((listingContainer != null) ? ((Object)listingContainer).name : null)}, Entries: {shop.listingEntries.Count}"); try { if ((Object)(object)shop.MatchingShop == (Object)null) { shop.MatchingShop = ShopInterface.AllShops.Find((ShopInterface x) => x.ShopName == shop.MatchingShopInterfaceName); } if ((Object)(object)shop.ListingContainer == (Object)null) { Logger.Error("ListingContainer is null for " + ((Object)shop).name + "!"); return; } if (shop.listingEntries.Count == 0) { Logger.Warning("No listing entries for " + ((Object)shop).name + ", creating them now..."); foreach (ShopListing item in shop.MatchingShop?.Listings ?? new List<ShopListing>()) { if (item.CanBeDelivered && (Object)(object)shop.ListingEntryPrefab != (Object)null) { ListingEntry val = Object.Instantiate<ListingEntry>(shop.ListingEntryPrefab, (Transform)(object)shop.ListingContainer); val.Initialize(item); val.onQuantityChanged.AddListener(new UnityAction(shop.RefreshCart)); shop.listingEntries.Add(val); } } } Button backButton = shop.BackButton; if (backButton != null) { ((UnityEventBase)backButton.onClick).RemoveAllListeners(); } Button backButton2 = shop.BackButton; if (backButton2 != null) { ((UnityEvent)backButton2.onClick).AddListener((UnityAction)delegate { shop.OnSelect?.Invoke(shop); }); } Button orderButton = shop.OrderButton; if (orderButton != null) { ((UnityEventBase)orderButton.onClick).RemoveAllListeners(); } Button orderButton2 = shop.OrderButton; if (orderButton2 != null) { ((UnityEvent)orderButton2.onClick).AddListener((UnityAction)delegate { shop.SubmitOrder(string.Empty); }); } Dropdown destinationDropdown = shop.DestinationDropdown; if (destinationDropdown != null) { ((UnityEventBase)destinationDropdown.onValueChanged).RemoveAllListeners(); } Dropdown destinationDropdown2 = shop.DestinationDropdown; if (destinationDropdown2 != null) { ((UnityEvent<int>)(object)destinationDropdown2.onValueChanged).AddListener((UnityAction<int>)shop.DestinationDropdownSelected); } Dropdown loadingDockDropdown = shop.LoadingDockDropdown; if (loadingDockDropdown != null) { ((UnityEventBase)loadingDockDropdown.onValueChanged).RemoveAllListeners(); } Dropdown loadingDockDropdown2 = shop.LoadingDockDropdown; if (loadingDockDropdown2 != null) { ((UnityEvent<int>)(object)loadingDockDropdown2.onValueChanged).AddListener((UnityAction<int>)shop.LoadingDockDropdownSelected); } ((Component)shop).gameObject.SetActive(false); Logger.Debug("Setup succeeded for: " + ((Object)shop).name); } catch (Exception ex) { Logger.Error("Setup failed: " + ex.Message + "\n" + ex.StackTrace); } } } [HarmonyPatch(typeof(DeliveryApp), "SetOpen")] public class SetOpen { public static void Postfix(DeliveryApp __instance, bool open) { if ((Object)(object)__instance == (Object)null || !open) { return; } foreach (DeliveryShop deliveryShop in __instance.deliveryShops) { if (!((Object)(object)deliveryShop?.DeliveryFeeLabel == (Object)null) && DeliveryShopBuilder.DeliveryFeeRegistry.TryGetValue(deliveryShop, out var value)) { deliveryShop.DeliveryFeeLabel.text = MoneyManager.FormatAmount(value, false, false); } } } } public static Instance Logger => new Instance("FurnitureDelivery-DeliveryApp"); } [HarmonyPatch] public static class DeliveryShopPatches { [HarmonyPatch(typeof(DeliveryShop), "RefreshCart")] public class RefreshCart { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.ItemTotalLabel == (Object)null || (Object)(object)__instance.OrderTotalLabel == (Object)null || (Object)(object)__instance.DeliveryTimeLabel == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "RefreshOrderButton")] public class RefreshOrderButton { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.OrderButton == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "RefreshDestinationUI")] public class RefreshDestinationUI { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.DestinationDropdown == (Object)null || (Object)(object)__instance.LoadingDockDropdown == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "RefreshLoadingDockUI")] public class RefreshLoadingDockUI { public static bool Prefix(DeliveryShop __instance) { if ((Object)(object)__instance.LoadingDockDropdown == (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "GetDeliveryFee")] public class GetDeliveryFee { public static bool Prefix(DeliveryShop __instance, ref float __result) { if (DeliveryShopBuilder.DeliveryFeeRegistry.TryGetValue(__instance, out var value)) { __result = value; return false; } return true; } } [HarmonyPatch(typeof(DeliveryShop), "CanOrder")] public class CanOrder { public static bool Prefix(DeliveryShop __instance, ref bool __result, ref string reason) { if ((Object)(object)__instance == (Object)null) { __result = false; reason = "Shop is null"; return false; } string name = ((Object)((Component)__instance).gameObject).name; if (name.Contains("Herbert")) { __result = ToileportationInterop.CanOrder((from e in PlayerSingleton<DeliveryApp>.Instance._shopElements.AsEnumerable() select e.Shop).ToList(), out reason); if (!__result) { return false; } } if (!CheckShopConflict(name, "Dan", ref __result, out reason)) { return false; } if (!CheckShopConflict(name, "Oscar", ref __result, out reason)) { return false; } return true; } private static bool CheckShopConflict(string shopName, string name, ref bool __result, out string reason) { if (!shopName.Contains(name)) { reason = ""; return true; } foreach (DeliveryShop deliveryShop in PlayerSingleton<DeliveryApp>.Instance.deliveryShops) { if ((Object)(object)deliveryShop == (Object)null || !((Object)((Component)deliveryShop).gameObject).name.Contains(name) || NetworkSingleton<DeliveryManager>.Instance.GetActiveShopDelivery(deliveryShop) == null) { continue; } __result = false; reason = name + " is currently delivering an order"; return false; } reason = ""; return true; } } } [HarmonyPatch] public static class ListingUIPatches { [HarmonyPatch(typeof(ListingUI))] public static class ListingUIPatch { [HarmonyPatch("CanAddToCart")] public static bool CanAddToCart(ListingUI __instance, ref bool __result) { if (__instance.Listing == null) { __result = false; return false; } return true; } [HarmonyPatch("UpdateButtons")] public static bool UpdateButtons(ListingUI __instance) { if ((Object)(object)__instance == (Object)null) { return false; } if ((Object)(object)__instance.BuyButton == (Object)null || !((Behaviour)__instance.BuyButton).isActiveAndEnabled) { return false; } if ((Object)(object)__instance.DropdownButton == (Object)null || !((Behaviour)__instance.DropdownButton).isActiveAndEnabled) { return false; } if (__instance.Listing == null) { return false; } return true; } } } [HarmonyPatch] public static class ShopInterfacePatches { [HarmonyPatch(typeof(ShopInterface), "Awake")] public static class ShopInterfaceAwakePatch { public static void Prefix(ShopInterface __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { if (!ShopInterface.AllShops.Contains(__instance)) { ShopInterface.AllShops.Add(__instance); } } catch { } } } [HarmonyPatch(typeof(ShopInterface), "RefreshShownItems")] public static class RefreshShownItemsPatch { public static bool Prefix(ShopInterface __instance) { return __instance?.listingUI != null && (Object)(object)__instance.DetailPanel != (Object)null; } } [HarmonyPatch(typeof(ShopInterface), "Start")] public static class ShopInterfaceStartPatch { public static void Prefix(ShopInterface __instance) { if ((Object)(object)__instance.Canvas == (Object)null) { __instance.Canvas = ((Component)__instance).GetComponent<Canvas>() ?? ((Component)__instance).gameObject.AddComponent<Canvas>(); } if ((Object)(object)__instance.Container == (Object)null) { __instance.Container = ((Component)__instance).GetComponent<RectTransform>() ?? ((Component)__instance).gameObject.AddComponent<RectTransform>(); } } } } [HarmonyPatch] public static class VehiclePatches { [HarmonyPatch(typeof(VehicleCamera))] public static class VehicleCameraPatch { [HarmonyPatch("LateUpdate")] public static bool LateUpdate(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } [HarmonyPatch("Update")] public static bool Update(VehicleCamera __instance) { return (Object)(object)__instance.vehicle != (Object)null && (Object)(object)__instance.cameraOrigin != (Object)null && (Object)(object)PlayerSingleton<PlayerCamera>.Instance != (Object)null; } } [HarmonyPatch(typeof(DeliveryVehicle), "Deactivate")] public static class DeliveryVehicleDeactivatePatch { public static Instance Logger => new Instance("FurnitureDelivery-VehicleDeactivate"); public static bool Prefix(DeliveryVehicle __instance) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.Vehicle == (Object)null) { return true; } DeliveryInstance activeDelivery = __instance.ActiveDelivery; if (activeDelivery != null && (int)activeDelivery.Status == 3) { return true; } LandVehicle vehicle = __instance.Vehicle; string text = ((vehicle != null) ? ((Object)vehicle).name : null); if (string.IsNullOrEmpty(text)) { return true; } string text2 = (text.Contains("Dan") ? "Dan" : (text.Contains("Oscar") ? "Oscar" : null)); if (text2 == null) { return true; } List<DeliveryShop> list = PlayerSingleton<DeliveryApp>.Instance?.deliveryShops; DeliveryManager instance = NetworkSingleton<DeliveryManager>.Instance; if (list == null || (Object)(object)instance == (Object)null) { return true; } foreach (DeliveryShop item in list) { if ((Object)(object)item != (Object)null && instance.GetActiveShopDelivery(item) != null) { Logger.Warning(text2 + " has active delivery, not deactivating"); return false; } } return true; } } [HarmonyPatch(typeof(DeliveryVehicle), "Awake")] public static class DeliveryVehicleAwakePatch { [HarmonyPrefix] [HarmonyPriority(800)] public static bool Prefix(DeliveryVehicle __instance) { if (Guid.TryParse(__instance.GUID, out var _)) { return true; } if ((Object)(object)((Component)__instance).GetComponent<LandVehicle>() == (Object)null) { return false; } __instance.Vehicle = ((Component)__instance).GetComponent<LandVehicle>(); __instance.Deactivate(); return false; } } } [HarmonyPatch] public static class WheelPatches { [HarmonyPatch(typeof(Wheel))] public static class WheelPatch { [HarmonyPatch("OnWeatherChange")] public static bool Prefix(Wheel __instance, WeatherConditions newConditions) { if ((Object)(object)__instance?.vehicle == (Object)null) { return false; } if (newConditions != null) { _ = newConditions.Rainy; if (0 == 0) { return true; } } return false; } } } } namespace FurnitureDelivery.Interop { [HarmonyPatch(typeof(Cart))] internal static class CartPatches { [HarmonyPatch("UpdateTotal")] [HarmonyPrefix] private static bool UpdateTotal(Cart __instance) { return (Object)(object)__instance.TotalText != (Object)null; } [HarmonyPatch("UpdateProblem")] [HarmonyPrefix] private static bool UpdateProblem(Cart __instance) { return (Object)(object)__instance.ProblemText != (Object)null; } } public class DeliveryAppPlusPlusInterop { private static Instance _logger = new Instance("FurnitureDelivery-DeliveryAppPlusPlusInterop"); public static void ApplyPatches() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown Harmony harmonyInstance = ((MelonBase)Melon<FurnitureDelivery>.Instance).HarmonyInstance; Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "DeliveryAppPlusPlus"); if (assembly == null) { _logger.Error("Target assembly not found!"); return; } Type type = assembly.GetType("FavouriteDeliveriesPatch.DeliveryInfo"); if (type == null) { _logger.Error("DeliveryInfo type not found!"); return; } Type type2 = assembly.GetType("FavouriteDeliveriesPatch.DeliveryUtils"); if (type2 == null) { _logger.Error("Target class not found!"); return; } MethodInfo methodInfo = AccessTools.Method(type2, "OnReorder", new Type[1] { type }, (Type[])null); if (methodInfo == null) { _logger.Error("OnReorder method not found!"); } else { harmonyInstance.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(DeliveryAppPlusPlusInterop).GetMethod("OnReorder_Prefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool OnReorder_Prefix(object __0) { try { Type type = __0.GetType(); FieldInfo field = type.GetField("instance", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { MelonLogger.Warning("[Added by FurnitureDelivery] Could not find 'instance' field on DeliveryInfo."); return false; } object value = field.GetValue(__0); if (value == null) { MelonLogger.Warning("[Added by FurnitureDelivery] 'instance' field was null."); return false; } if (!(value.GetType().GetProperty("StoreName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value) is string text)) { MelonLogger.Warning("[Added by FurnitureDelivery] 'StoreName' property was null."); return false; } DeliveryShop shop = PlayerSingleton<DeliveryApp>.Instance.GetShop(text); bool __result = true; string reason = ""; DeliveryShopPatches.CanOrder.Prefix(shop, ref __result, ref reason); if (!string.IsNullOrEmpty(reason)) { MelonLogger.Msg("[Added by FurnitureDelivery] Tried to order, but got " + reason); return false; } return true; } catch (Exception arg) { MelonLogger.Error($"[Added by FurnitureDelivery] Failed to reflect DeliveryInfo: {arg}"); } return false; } } public static class MoreGunsInterop { public static Instance Logger = new Instance("FurnitureDelivery-MoreGunsInterop"); public static bool TryGetPrices(string weaponID, out float gunPrice, out float magPrice) { gunPrice = 0f; magPrice = 0f; string text = "MoreGuns-" + weaponID + " Settings"; MelonPreferences_Category category = MelonPreferences.GetCategory(text); if (category == null) { Logger.Warning("Could not find category: " + text); return false; } MelonPreferences_Entry<float> entry = category.GetEntry<float>(weaponID + " Price"); MelonPreferences_Entry<float> entry2 = category.GetEntry<float>(weaponID + " Magazine Price"); if (entry == null || entry2 == null) { Logger.Warning("Missing price entries for '" + weaponID + "'"); return false; } gunPrice = entry.Value; magPrice = entry2.Value; return true; } } public static class ToileportationInterop { [HarmonyPatch(typeof(ShopListing), "Initialize")] public static class ToileportationShopListingPatch { public static void Postfix(ShopListing __instance) { if (!MelonTypeBase<MelonMod>.RegisteredMelons.All((MelonMod m) => ((MelonBase)m).Info.Name != "Toileportation") && __instance != null && !string.IsNullOrEmpty(__instance.name) && __instance.name.Contains("Golden Toilet")) { GoldenToiletListing = __instance; Logger.Msg("Captured Golden Toilet listing"); } } } public static Instance Logger = new Instance("FurnitureDelivery-ToileportationInterop"); public static ShopListing GoldenToiletListing; public static bool CanOrder(List<DeliveryShop> shops, out string reason) { reason = string.Empty; if (MelonTypeBase<MelonMod>.RegisteredMelons.All((MelonMod m) => ((MelonBase)m).Info.Name != "Toileportation")) { return true; } int currentStock = GoldenToiletListing.CurrentStock; foreach (DeliveryShop shop in shops) { List<ListingEntry> listingEntries = shop.listingEntries; foreach (ListingEntry item in listingEntries) { if ((Object)(object)item == (Object)null || !((BaseItemDefinition)item.MatchingListing.Item).Name.Contains("Golden Toilet") || item.SelectedQuantity <= currentStock) { continue; } reason = "Not enough Golden Toilets in stock"; return false; } } return true; } public static void OnDeliveryCreated(DeliveryInstance delivery) { if (delivery == null) { return; } StringIntPair[] items = delivery.Items; Logger.Debug($"Delivery created with {items.Length} items"); StringIntPair[] array = items; foreach (StringIntPair val in array) { Logger.Debug($"Checking item {val.String} in quantity {val.Int}"); if (val.String == "goldentoilet") { Logger.Debug("Found Golden Toilet in delivery"); if (GoldenToiletListing.CurrentStock < val.Int) { Logger.Error("Delivering more Golden Toilets than in stock"); } ShopListing goldenToiletListing = GoldenToiletListing; goldenToiletListing.CurrentStock -= val.Int; Logger.Debug($"New stock: {GoldenToiletListing.CurrentStock}"); } } } } } namespace FurnitureDelivery.Helpers { public static class Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } } public class LandVehicleBuilder { private string _vehicleName = "CustomVehicle"; private string _vehicleCode = "shitbox"; private float _vehiclePrice = 1000f; private float _topSpeed = 60f; private bool _isPlayerOwned = true; private EVehicleColor _color = (EVehicleColor)16; public static List<LandVehicle> VehiclePrefabs = NetworkSingleton<VehicleManager>.Instance.VehiclePrefabs; public LandVehicleBuilder WithVehicleName(string vehicleName) { _vehicleName = vehicleName; return this; } public LandVehicleBuilder WithVehicleCode(string vehicleCode) { _vehicleCode = vehicleCode; return this; } public LandVehicleBuilder WithVehiclePrice(float vehiclePrice) { _vehiclePrice = vehiclePrice; return this; } public LandVehicleBuilder WithTopSpeed(float topSpeed) { _topSpeed = topSpeed; return this; } public LandVehicleBuilder WithPlayerOwned(bool isPlayerOwned) { _isPlayerOwned = isPlayerOwned; return this; } public LandVehicleBuilder WithColor(EVehicleColor color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) _color = color; return this; } public LandVehicle Build() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_00aa: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(130f, 50f, -250f); Quaternion identity = Quaternion.identity; if (!InstanceFinder.IsServer) { MelonLogger.Error("LandVehicleBuilder can only be used on the server."); return null; } LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(_vehicleCode); if ((Object)(object)vehiclePrefab == (Object)null) { MelonLogger.Error("Vehicle prefab with code '" + _vehicleCode + "' not found."); return null; } GameObject val = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject); LandVehicle component = val.GetComponent<LandVehicle>(); ((Component)component).transform.position = position; ((Component)component).transform.rotation = identity; Guid gUID = GUIDManager.GenerateUniqueGUID(); component.SetGUID(gUID); ((Object)component).name = _vehicleName; ((Object)((Component)component).gameObject).name = _vehicleName; component.vehicleName = _vehicleName; component.vehiclePrice = _vehiclePrice; component.TopSpeed = _topSpeed; component.SetIsPlayerOwned((NetworkConnection)null, _isPlayerOwned); if (_isPlayerOwned) { NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(component); } component.ApplyColor(_color); component.SetOwnedColor((NetworkConnection)null, _color); NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component); ((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).NetworkObject.Spawn(((Component)component).gameObject, (NetworkConnection)null, default(Scene)); VehicleSync.AddedVehicles.Add(((NetworkBehaviour)component).ObjectId, (_vehicleName, gUID.ToString())); VehicleSync.SyncVehicles(); return component; } } public static class MelonLoggerExtensions { public static void Debug(this Instance logger, string message, bool stacktrace = true) { MelonDebug.Msg(stacktrace ? ("[" + GetCallerInfo() + "] " + message) : message); } private static string GetCallerInfo() { StackTrace stackTrace = new StackTrace(); for (int i = 2; i < stackTrace.FrameCount; i++) { StackFrame frame = stackTrace.GetFrame(i); MethodBase method = frame.GetMethod(); if (!(method?.DeclaringType == null)) { return method.DeclaringType.FullName + "." + method.Name; } } return "unknown"; } } public static class Registries { private static GameObject _fdRoot; public static GameObject FDRoot { get { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown object obj = _fdRoot; if (obj == null) { GameObject val = new GameObject("FurnitureDeliveryRoot"); _fdRoot = val; obj = (object)val; } return (GameObject)obj; } } public static Dictionary<LandVehicle, DeliveryVehicle> DeliveryVehicleRegistry { get; } = new Dictionary<LandVehicle, DeliveryVehicle>(); public static Dictionary<DeliveryShop, float> DeliveryFeeRegistry { get; } = new Dictionary<DeliveryShop, float>(); public static Dictionary<DeliveryShop, Sprite> ShopImageRegistry { get; } = new Dictionary<DeliveryShop, Sprite>(); public static Dictionary<string, int> ShopPositionRegistry { get; } = new Dictionary<string, int>(); public static int OriginalDeliveryShopsCount { get; set; } = -1; public static Instance Logger => new Instance("FurnitureDelivery-Registries"); public static void RegisterAvailableVehicles() { VehicleManager instance = NetworkSingleton<VehicleManager>.Instance; if ((Object)(object)instance == (Object)null || instance.AllVehicles == null) { Logger.Error("VehicleManager or AllVehicles is null."); return; } foreach (LandVehicle item in instance.AllVehicles.AsEnumerable()) { if (!((Object)(object)item == (Object)null) && !DeliveryVehicleRegistry.ContainsKey(item)) { DeliveryVehicleRegistry[item] = null; } } Logger.Debug($"Registered {DeliveryVehicleRegistry.Count} vehicles for lazy wrapping."); } public static DeliveryVehicle GetOrCreateDeliveryVehicle(LandVehicle vehicle) { if ((Object)(object)vehicle == (Object)null) { return null; } object obj; if (vehicle == null) { obj = null; } else { GameObject gameObject = ((Component)vehicle).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent<DeliveryVehicle>() : null); } if ((Object)obj != (Object)null) { return ((Component)vehicle).gameObject.GetComponent<DeliveryVehicle>(); } if (DeliveryVehicleRegistry.TryGetValue(vehicle, out var value) && (Object)(object)value != (Object)null) { Logger.Debug("Using cached DeliveryVehicle for " + ((Object)vehicle).name); if ((Object)(object)value.Vehicle != (Object)(object)vehicle) { Logger.Warning("Cached DeliveryVehicle's Vehicle does not match for " + ((Object)vehicle).name + ". Updating reference."); value.Vehicle = vehicle; } return value; } GameObject gameObject2 = ((Component)vehicle).gameObject; gameObject2.transform.SetParent(FDRoot.transform); DeliveryVehicle val = gameObject2.AddComponent<DeliveryVehicle>(); val.Vehicle = vehicle; val.GUID = vehicle.GUID.ToString(); Logger.Debug("Created new DeliveryVehicle for " + ((Object)vehicle).name + " with GUID " + val.GUID); DeliveryVehicleRegistry[vehicle] = val; return val; } public static void RegisterShopPosition(string shopName, int position) { ShopPositionRegistry[shopName] = position; } public static int GetShopPosition(string shopName) { int value; return ShopPositionRegistry.TryGetValue(shopName, out value) ? value : (-1); } public static void RegisterShopImage(DeliveryShop shop, Sprite image) { ShopImageRegistry.TryAdd(shop, image); } public static Sprite GetShopImage(DeliveryShop shop) { Sprite value; return ShopImageRegistry.TryGetValue(shop, out value) ? value : null; } public static void RegisterDeliveryFee(DeliveryShop shop, float fee) { DeliveryFeeRegistry.TryAdd(shop, fee); } public static void Clear() { DeliveryVehicleRegistry.Clear(); DeliveryFeeRegistry.Clear(); ShopImageRegistry.Clear(); ShopPositionRegistry.Clear(); OriginalDeliveryShopsCount = -1; if ((Object)(object)_fdRoot != (Object)null) { Object.Destroy((Object)(object)_fdRoot); _fdRoot = null; } Logger.Debug("Registries cleared"); } } public static class Utils { [CompilerGenerated] private sealed class <WaitForNetworkSingleton>d__6<T> : IEnumerator<object>, IEnumerator, IDisposable where T : NetworkSingleton<T> { private int <>1__state; private object <>2__current; public IEnumerator coroutine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetworkSingleton>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0044; case 1: <>1__state = -1; goto IL_0044; case 2: { <>1__state = -1; return false; } IL_0044: if (!NetworkSingleton<T>.InstanceExists) { <>2__current = null; <>1__state = 1; return true; } <>2__current = coroutine; <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForNotNull>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object obj; public float timeout; public Action onTimeout; public Action onFinish; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNotNull>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (obj == null) { if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForPlayer>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayer>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static Instance Logger = new Instance("FurnitureDelivery-Utils"); public static Sprite FindSprite(string spriteName) { try { Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val in array) { if (((Object)val).name == spriteName) { Logger.Debug("Found sprite '" + spriteName + "' directly in loaded objects"); return val; } } return null; } catch (Exception ex) { Logger.Error("Error finding sprite '" + spriteName + "': " + ex.Message); return null; } } public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component { List<T> list = new List<T>(); if ((Object)(object)obj == (Object)null) { return list; } T[] components = obj.GetComponents<T>(); if (components.Length != 0) { list.AddRange(components); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject)); } return list; } public static bool Is<T>(object obj, out T result) where T : class { if (obj is T val) { result = val; return true; } result = null; return false; } public static List<StorableItemDefinition> GetAllStorableItemDefinitions() { List<ItemRegister> list = Singleton<Registry>.Instance.ItemRegistry.ToList(); List<StorableItemDefinition> list2 = new List<StorableItemDefinition>(); foreach (ItemRegister item in list) { if (Is<StorableItemDefinition>(item.Definition, out var result)) { list2.Add(result); } else { Logger.Warning("Definition " + ((object)item.Definition)?.GetType().FullName + " is not a StorableItemDefinition"); } } return list2.ToList(); } [IteratorStateMachine(typeof(<WaitForNotNull>d__5))] public static IEnumerator WaitForNotNull([MaybeNull] object obj, float timeout = float.NaN, Action onTimeout = null, Action onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNotNull>d__5(0) { obj = obj, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } [IteratorStateMachine(typeof(<WaitForNetworkSingleton>d__6<>))] public static IEnumerator WaitForNetworkSingleton<T>(IEnumerator coroutine) where T : NetworkSingleton<T> { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetworkSingleton>d__6<T>(0) { coroutine = coroutine }; } [IteratorStateMachine(typeof(<WaitForPlayer>d__7))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayer>d__7(0) { routine = routine }; } public static T GetNotNullWithTimeout<T>(Func<T> getter, float timeout = 5f) where T : class { Stopwatch stopwatch = Stopwatch.StartNew(); while (stopwatch.Elapsed.TotalSeconds < (double)timeout) { T val = getter(); if (val != null) { return val; } Thread.Sleep(100); } Logger.Error("Timed out waiting for " + typeof(T).Name + " to be not null"); return null; } } } namespace FurnitureDelivery.Builders { public class DeliveryShopBuilder { private class DeliveryShopUIElementsLinker : UIElementsLinker { private readonly float _deliveryFee; private readonly bool _availableByDefault; public DeliveryShopUIElementsLinker(DeliveryShop shopInstance, ShopInterface shopInterface, Color shopColor, string shopName, string shopDescription, Sprite shopImage, DeliveryShop deliveryShopTemplate, float deliveryFee, bool availableByDefault) : base(shopInstance, shopInterface, shopColor, shopName, shopDescription, shopImage, deliveryShopTemplate) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) _deliveryFee = deliveryFee; _availableByDefault = availableByDefault; } protected override float GetDeliveryFee() { return _deliveryFee; } protected override bool GetAvailableByDefault() { return _availableByDefault; } } private string _shopName = "CustomShop"; private string _shopDescription = "Custom shop description"; private Sprite _shopImage; private Color _shopColor = Color.red; private float _deliveryFee = 100f; private bool _availableByDefault = true; private int _insertPosition = -1; private DeliveryVehicle _deliveryVehicle; private readonly List<ShopListing> _listings = new List<ShopListing>(); private readonly DeliveryShop _deliveryShopTemplate; private readonly DeliveryApp _deliveryApp; public static Instance Logger => new Instance("FurnitureDelivery-DeliveryShopBuilder"); public static Dictionary<DeliveryShop, float> DeliveryFeeRegistry => Registries.DeliveryFeeRegistry; internal static int OriginalDeliveryShopsCount { get { return Registries.OriginalDeliveryShopsCount; } set { Registries.OriginalDeliveryShopsCount = value; } } public DeliveryShopBuilder(DeliveryApp appInstance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) _deliveryApp = appInstance; List<DeliveryShop> source = (from ds in ((Component)appInstance).GetComponentsInChildren<DeliveryShop>(true) where (Object)(object)ds != (Object)null && ((Component)ds).transform.childCount > 0 select ds).ToList(); _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)((Component)ds).transform.Find("Container") != (Object)null && (Object)(object)((Component)ds).transform.Find("Dropshadow") != (Object)null && (Object)(object)ds.ListingEntryPrefab != (Object)null)); if (_deliveryShopTemplate == null) { _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)ds.ListingEntryPrefab != (Object)null && (Object)(object)ds.ListingContainer != (Object)null && ((Object)ds.ListingContainer).name == "Listings" && (Object)(object)ds.BackButton != (Object)null)); } if (_deliveryShopTemplate == null) { _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => (Object)(object)ds.ListingEntryPrefab != (Object)null)); } if (_deliveryShopTemplate == null) { _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)source).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop ds) => ((Component)ds).transform.childCount > 0)); } if (_deliveryShopTemplate == null) { _deliveryShopTemplate = source.FirstOrDefault(); } if ((Object)(object)_deliveryShopTemplate == (Object)null) { Logger.Error("No DeliveryShop template found in app."); } } public DeliveryShopBuilder WithShopName(string name) { _shopName = name; return this; } public DeliveryShopBuilder WithShopDescription(string description) { _shopDescription = description; return this; } public DeliveryShopBuilder WithShopImage(Sprite image) { _shopImage = image; return this; } public DeliveryShopBuilder WithShopColor(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) _shopColor = color; return this; } public DeliveryShopBuilder WithDeliveryFee(float fee) { _deliveryFee = fee; return this; } public DeliveryShopBuilder SetAvailableByDefault(bool available) { _availableByDefault = available; return this; } public DeliveryShopBuilder WithDeliveryVehicle(DeliveryVehicle vehicle) { _deliveryVehicle = vehicle; return this; } public DeliveryShopBuilder SetPosition(int position) { _insertPosition = position; return this; } public DeliveryShopBuilder AddListing(StorableItemDefinition item, float? overridePrice = null, int quantity = 999) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown _listings.Add(new ShopListing { name = ((Object)item).name, Item = item, CanBeDelivered = true, OverridePrice = true, OverriddenPrice = (overridePrice ?? item.BasePurchasePrice) }); return this; } public DeliveryShopBuilder AddListing(ShopListing listing) { _listings.Add(listing); return this; } public DeliveryShop Build() { Logger.Debug("Build() START for " + _shopName); if ((Object)(object)_deliveryShopTemplate == (Object)null) { Logger.Error("Cannot build delivery shop without template."); return null; } try { ShopInterface shopInterface = CreateShopInterface(); DeliveryShop val = CloneDeliveryShop(); if ((Object)(object)val == (Object)null) { return null; } LinkUIElements(val, shopInterface); InitializeShop(val, shopInterface); Registries.RegisterShopPosition(((Object)((Component)val).gameObject).name, _insertPosition); if ((Object)(object)_shopImage != (Object)null) { Registries.RegisterShopImage(val, _shopImage); } Logger.Debug("Built delivery shop: " + ((Object)val).name); return val; } catch (Exception ex) { Logger.Error("Build() FAILED for " + _shopName + ": " + ex.Message); return null; } } private ShopInterface CreateShopInterface() { ShopInterfaceBuilder shopInterfaceBuilder = new ShopInterfaceBuilder(_shopName, _shopDescription, _shopImage, _listings, GetOrCreateDeliveryVehicle(), _deliveryApp); return shopInterfaceBuilder.Build().shopInterface; } private DeliveryShop CloneDeliveryShop() { Transform val = ((Component)_deliveryApp).transform.Find("Container/Contents/Container/Shops/Order"); if ((Object)(object)val == (Object)null) { Logger.Error("Cannot find Order canvas!"); return null; } try { DeliveryShop val2 = Object.Instantiate<DeliveryShop>(_deliveryShopTemplate, val); Logger.Debug($"Cloned shop has {((Component)val2).transform.childCount} children"); return val2; } catch (Exception ex) { Logger.Error("Object.Instantiate failed: " + ex.Message); return null; } } private void LinkUIElements(DeliveryShop shopInstance, ShopInterface shopInterface) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) DeliveryShopUIElementsLinker deliveryShopUIElementsLinker = new DeliveryShopUIElementsLinker(shopInstance, shopInterface, _shopColor, _shopName, _shopDescription, _shopImage, _deliveryShopTemplate, _deliveryFee, _availableByDefault); deliveryShopUIElementsLinker.LinkAll(); } private void InitializeShop(DeliveryShop shopInstance, ShopInterface shopInterface) { ShopInitializer shopInitializer = new ShopInitializer(shopInstance, shopInterface); shopInitializer.Initialize(); } private DeliveryVehicle GetOrCreateDeliveryVehicle() { if ((Object)(object)_deliveryVehicle != (Object)null) { return _deliveryVehicle; } if (Registries.DeliveryVehicleRegistry.Count == 0) { Registries.RegisterAvailableVehicles(); } LandVehicle val = Registries.DeliveryVehicleRegistry.Keys.FirstOrDefault(); if ((Object)(object)val == (Object)null) { Logger.Error("No available vehicles registered."); return null; } return Registries.GetOrCreateDeliveryVehicle(val); } public static List<DeliveryShop> GetInitializedShops(DeliveryApp app, out Transform contentT) { contentT = ((Component)app).transform.Find("Container/Scroll View/Viewport/Content"); if ((Object)(object)contentT == (Object)null) { Logger.Debug("Could not find 'Container/Scroll View/Viewport/Content' under DeliveryApp"); return null; } List<DeliveryShop> list = new List<DeliveryShop>(); for (int i = 0; i < contentT.childCount; i++) { DeliveryShop component = ((Component)contentT.GetChild(i)).GetComponent<DeliveryShop>(); if ((Object)(object)component != (Object)null) { list.Add(component); } } return list; } public static void Apply(DeliveryApp app, DeliveryShop shop) { int num = Registries.GetShopPosition(((Object)((Component)shop).gameObject).name); if (num < 0) { num = app.deliveryShops.Count + num + 1; if (num < 0) { num = 0; } } if (num > app.deliveryShops.Count) { num = app.deliveryShops.Count; } if (num < app.deliveryShops.Count) { app.deliveryShops.Insert(num, shop); } else { app.deliveryShops.Add(shop); } ReorderButtons(app); Logger.Debug("Added new delivery shop to app: " + ((Object)shop).name + ", " + ((Object)((Component)shop).gameObject).name); } private static void ReorderButtons(DeliveryApp app) { if (app._shopElements == null || app._shopElements.Count == 0) { return; } app._shopElements.Sort(delegate(DeliveryShopElement a, DeliveryShopElement b) { if ((Object)(object)a?.Shop == (Object)null || (Object)(object)b?.Shop == (Object)null) { return 0; } int num = app.deliveryShops.IndexOf(a.Shop); int value = app.deliveryShops.IndexOf(b.Shop); return num.CompareTo(value); }); for (int i = 0; i < app._shopElements.Count; i++) { DeliveryShopElement val = app._shopElements[i]; object obj; if (val == null) { obj = null; } else { Button button = val.Button; obj = ((button != null) ? ((Component)button).gameObject : null); } if ((Object)obj != (Object)null) { ((Component)val.Button).transform.SetSiblingIndex(i); } } } } public class ShopInitializer { private readonly DeliveryShop _shopInstance; private readonly ShopInterface _shopInterface; public static Instance Logger => new Instance("FurnitureDelivery-ShopInitializer"); public ShopInitializer(DeliveryShop shopInstance, ShopInterface shopInterface) { _shopInstance = shopInstance; _shopInterface = shopInterface; } public void Initialize() { ((Component)_shopInstance).gameObject.SetActive(true); try { CreateListingEntries(); SetupButtonListeners(); Logger.Debug("Initialize complete"); } catch (Exception ex) { Logger.Error("Initialize failed: " + ex.Message); } ((Component)_shopInstance).gameObject.SetActive(false); } private void CreateListingEntries() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown foreach (ShopListing listing in _shopInterface.Listings) { if (!listing.CanBeDelivered) { continue; } try { ListingEntry entry = Object.Instantiate<ListingEntry>(_shopInstance.ListingEntryPrefab, (Transform)(object)_shopInstance.ListingContainer); entry.Initialize(listing); entry.onQuantityChanged.AddListener(new UnityAction(_shopInstance.RefreshCart)); DeliveryShop shopInstance = _shopInstance; shopInstance.OnSelect = (Action<DeliveryShop>)Delegate.Combine(shopInstance.OnSelect, (Action<DeliveryShop>)delegate { entry.RefreshLocked(); }); _shopInstance.listingEntries.Add(entry); } catch (Exception ex) { Logger.Warning("Failed to create entry for " + listing.name + ": " + ex.Message); } } } private void SetupButtonListeners() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown if ((Object)(object)_shopInstance.BackButton != (Object)null) { ((UnityEventBase)_shopInstance.BackButton.onClick).RemoveAllListeners(); ((UnityEvent)_shopInstance.BackButton.onClick).AddListener((UnityAction)delegate { _shopInstance.OnSelect?.Invoke(_shopInstance); }); } if ((Object)(object)_shopInstance.OrderButton != (Object)null) { ((UnityEventBase)_shopInstance.OrderButton.onClick).RemoveAllListeners(); ((UnityEvent)_shopInstance.OrderButton.onClick).AddListener((UnityAction)delegate { _shopInstance.SubmitOrder(string.Empty); }); } if ((Object)(object)_shopInstance.DestinationDropdown != (Object)null) { ((UnityEventBase)_shopInstance.DestinationDropdown.onValueChanged).RemoveAllListeners(); ((UnityEvent<int>)(object)_shopInstance.DestinationDropdown.onValueChanged).AddListener((UnityAction<int>)_shopInstance.DestinationDropdownSelected); } if ((Object)(object)_shopInstance.LoadingDockDropdown != (Object)null) { ((UnityEventBase)_shopInstance.LoadingDockDropdown.onValueChanged).RemoveAllListeners(); ((UnityEvent<int>)(object)_shopInstance.LoadingDockDropdown.onValueChanged).AddListener((UnityAction<int>)_shopInstance.LoadingDockDropdownSelected); } } } public class ShopInterfaceBuilder { private readonly string _shopName; private readonly string _shopDescription; private readonly Sprite _shopImage; private readonly List<ShopListing> _listings; private readonly DeliveryVehicle _deliveryVehicle; private readonly DeliveryApp _deliveryApp; public static Instance Logger => new Instance("FurnitureDelivery-ShopInterfaceBuilder"); public ShopInterfaceBuilder(string shopName, string shopDescription, Sprite shopImage, List<ShopListing> listings, DeliveryVehicle deliveryVehicle, DeliveryApp deliveryApp) { _shopName = shopName; _shopDescription = shopDescription; _shopImage = shopImage; _listings = listings; _deliveryVehicle = deliveryVehicle; _deliveryApp = deliveryApp; } public (ShopInterface shopInterface, Cart cart) Build() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown GameObject val = new GameObject("ShopInterface_" + _shopName); val.transform.SetParent(Registries.FDRoot.transform); val.SetActive(false); ShopInterface val2 = val.AddComponent<ShopInterface>(); val2.ShopName = _shopName; val2.ShopDescription = _shopDescription; val2.Listings = _listings; foreach (ShopListing listing in _listings) { listing.Shop = val2; } val2.DeliveryVehicle = _deliveryVehicle; val2.ShopCode = _shopName; Cart item = (val2.Cart = BuildCart(val2)); ShopInterface val3 = FindTemplateShop(); if ((Object)(object)val3 != (Object)null) { val2.ListingUIPrefab = val3.ListingUIPrefab; if ((Object)(object)val2.ListingUIPrefab != (Object)null) { ((Component)val2.ListingUIPrefab).gameObject.SetActive(false); } } RegisterShopInterface(val2); Logger.Debug("Built ShopInterface: " + val2.ShopName); return (val2, item); } private Cart BuildCart(ShopInterface shopInterface) { Cart val = ((Component)shopInterface).gameObject.AddComponent<Cart>(); ((Object)val).name = "Cart_" + _shopName; val.Shop = shopInterface; val.TotalText = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>(); val.WarningText = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>(); val.ProblemText = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>(); val.LoadVehicleToggle = ((Component)val).gameObject.AddComponent<Toggle>(); val.CartArea = ((Component)val).gameObject.AddComponent<Image>(); val.EntryPrefab = CreateCartEntryPrefab(); val.CartEntryContainer = CreateCartEntryContainer(((Component)val).transform); Logger.Debug("Built Cart: " + ((Object)val).name); return val; } private CartEntry CreateCartEntryPrefab() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("CartEntry"); val.transform.SetParent(Registries.FDRoot.transform); CartEntry val2 = val.AddComponent<CartEntry>(); val2.NameLabel = CreateChild<TextMeshProUGUI>(val.transform, "NameLabel"); val2.PriceLabel = CreateChild<TextMeshProUGUI>(val.transform, "PriceLabel"); val2.IncrementButton = CreateChild<Button>(val.transform, "IncrementButton"); val2.DecrementButton = CreateChild<Button>(val.transform, "DecrementButton"); val2.RemoveButton = CreateChild<Button>(val.transform, "RemoveButton"); return val2; } private T CreateChild<T>(Transform parent, string name) where T : Component { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); return val.AddComponent<T>(); } private RectTransform CreateCartEntryContainer(Transform parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("CartEntryContainer"); val.transform.SetParent(parent); return val.AddComponent<RectTransform>(); } private ShopInterface FindTemplateShop() { if (_deliveryApp?.deliveryShops != null && DeliveryShopBuilder.OriginalDeliveryShopsCount >= 0) { int originalDeliveryShopsCount = DeliveryShopBuilder.OriginalDeliveryShopsCount; foreach (DeliveryShop deliveryShop in _deliveryApp.deliveryShops) { int num = _deliveryApp.deliveryShops.IndexOf(deliveryShop); if (num >= originalDeliveryShopsCount || !((Object)(object)((deliveryShop == null) ? null : deliveryShop.MatchingShop?.ListingUIPrefab) != (Object)null)) { continue; } return deliveryShop.MatchingShop; } } return ShopInterface.AllShops.AsEnumerable().FirstOrDefault((Func<ShopInterface, bool>)((ShopInterface shop) => (Object)(object)shop != (Object)null && (Object)(object)shop.ListingUIPrefab != (Object)null)) ?? ShopInterface.AllShops.AsEnumerable().FirstOrDefault((Func<ShopInterface, bool>)((ShopInterface shop) => (Object)(object)shop != (Object)null)); } private void RegisterShopInterface(ShopInterface shopInterface) { ShopInterface.AllShops.RemoveAll((ShopInterface si) => (Object)(object)si == (Object)null); ShopInterface.AllShops.Add(shopInterface); Logger.Debug("Registered ShopInterface: " + shopInterface.ShopName); } } public class UIElementsLinker { private readonly DeliveryShop _shopInstance; private readonly ShopInterface _shopInterface; private readonly Color _shopColor; private readonly string _shopName; private readonly string _shopDescription; private readonly Sprite _shopImage; private readonly DeliveryShop _deliveryShopTemplate; public static Instance Logger => new Instance("FurnitureDelivery-UIElementsLinker"); public UIElementsLinker(DeliveryShop shopInstance, ShopInterface shopInterface, Color shopColor, string shopName, string shopDescription, Sprite shopImage, DeliveryShop deliveryShopTemplate) { //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) _shopInstance = shopInstance; _shopInterface = shopInterface; _shopColor = shopColor; _shopName = shopName; _shopDescription = shopDescription; _shopImage = shopImage; _deliveryShopTemplate = deliveryShopTemplate; } public void LinkAll() { //IL_0008: 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) _shopInstance.ShopColor = _shopColor; ((Object)((Component)_shopInstance).gameObject).name = "DeliveryShop_" + _shopName; LinkHeader(); LinkLabels(); LinkButtons(); LinkDropdowns(); LinkListingContainer(); _shopInstance.ListingEntryPrefab = _deliveryShopTemplate.ListingEntryPrefab; Logger.Debug("Set ListingEntryPrefab: " + (((Object)(object)_shopInstance.ListingEntryPrefab != (Object)null) ? ((Object)_shopInstance.ListingEntryPrefab).name : "NULL")); _shopInstance.MatchingShopInterfaceName = _shopName; _shopInstance.MatchingShop = _shopInterface; Registries.RegisterDeliveryFee(_shopInstance, GetDeliveryFee()); _shopInstance.AvailableByDefault = GetAvailableByDefault(); } protected virtual float GetDeliveryFee() { return 100f; } protected virtual bool GetAvailableByDefault() { return true; } private void LinkHeader() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)_shopInstance).transform.Find("Container/Header") ?? ((Component)_shopInstance).transform.Find("Header"); if ((Object)(object)val == (Object)null) { return; } Image component = ((Component)val).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = _shopColor; }