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.3", "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(".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+725133d526a54349a4c573a1a5f6b5b39dd357af")] [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 d__8 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__1 = 0; break; case 1: <>1__state = -1; 5__1++; break; } if (5__1 < 10) { if (GetPayload()) { Logger.Debug("Vehicle sync payload received successfully"); return false; } Logger.Debug($"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 AddedVehicles = new Dictionary(); 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.Instance.IsHost; public static bool isClient = !Singleton.Instance.IsHost && Singleton.Instance.IsInLobby; public static bool isSingleplayer = !Singleton.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.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(d__8))] public static IEnumerator WaitForPayload() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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.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 vehicles) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("FurnitureDelivery_Vehicles@1.0.0;"); foreach (KeyValuePair vehicle in vehicles) { stringBuilder.Append($"{vehicle.Key}:{vehicle.Value.Item1},{vehicle.Value.Item2};"); } return stringBuilder.ToString(); } private static Dictionary DeserializeVehicles(string data) { Dictionary dictionary = new Dictionary(); if (string.IsNullOrEmpty(data)) { return dictionary; } string[] array = data.Split(';'); if (array.Length == 0 || !array[0].StartsWith("FurnitureDelivery_Vehicles@1.0.0")) { 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)val2.GetComponentsInChildren(true)).FirstOrDefault((Func)((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 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.3"; } public class FurnitureDelivery : MelonMod { [CompilerGenerated] private sealed class d__10 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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.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.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("MoreGuns"))) { MelonLogger.Msg("MoreGuns detected. Adding ak47 to Armory"); } if (MelonTypeBase.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("Toileportation"))) { MelonLogger.Msg("Toileportation detected. Adding Golden Toilet to Herbert's shop"); } if (MelonTypeBase.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("UpgradedTrashCans"))) { MelonLogger.Msg("UpgradedTrashCans detected. Adding trash bins to Dan's shop"); } if (MelonTypeBase.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("MetalStorage"))) { MelonLogger.Msg("MetalStorage detected. Adding metal storage racks to Dan's shop"); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (MelonTypeBase.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name.Contains("Toileportation"))) { if (!(sceneName == "Main")) { if (sceneName == "Menu") { if ((Object)(object)NetworkSingleton.Instance != (Object)null) { NetworkSingleton.Instance.onDeliveryCreated += delegate(DeliveryInstance di) { ToileportationInterop.OnDeliveryCreated(di); }; } ToileportationInterop.GoldenToiletListing = null; } } else { MelonCoroutines.Start(Utils.WaitForNetworkSingleton(OnDeliveryManagerReady())); } } if (!(sceneName == "Main")) { if (sceneName == "Menu") { } } else if (MelonTypeBase.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(d__10))] private static IEnumerator OnDeliveryManagerReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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.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.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 list = PlayerSingleton.Instance?.deliveryShops; if (list == null) { return true; } DeliveryManager instance = NetworkSingleton.Instance; if ((Object)(object)instance == (Object)null) { Logger.Debug("NetworkSingleton.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() == (Object)null) { return false; } __instance.Vehicle = ((Component)__instance).GetComponent(); __instance.Deactivate(); return false; } } [HarmonyPatch(typeof(ShopInterface))] internal static class ShopInterfacePatch { public static Instance Logger => new Instance("FurnitureDelivery-ShopInterfacePatch"); [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() ?? ((Component)__instance).gameObject.AddComponent(); } if ((Object)(object)__instance.Container == (Object)null) { __instance.Container = ((Component)__instance).GetComponent() ?? ((Component)__instance).gameObject.AddComponent(); } } } public static class ShopRegistry { private static readonly List _shops = new List(4) { new DanShop(), new HerbertShop(), new OscarShop(), new StanShop() }; public static IReadOnlyList 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 ItemIDs => new List { "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.Instance.AllVehicles.AsEnumerable().FirstOrDefault((Func)((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 itemDefinitions = Utils.GetAllStorableItemDefinitions(); List list = (from id in ItemIDs select ((IEnumerable)itemDefinitions).FirstOrDefault((Func)((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 ItemIDs => new List { "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 itemDefinitions = Utils.GetAllStorableItemDefinitions(); List list = (from id in ItemIDs select ((IEnumerable)itemDefinitions).FirstOrDefault((Func)((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.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 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 ItemIDs => new List { "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.Instance.AllVehicles.AsEnumerable().FirstOrDefault((Func)((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.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 itemDefinitions = Utils.GetAllStorableItemDefinitions(); List list = (from id in ItemIDs select ((IEnumerable)itemDefinitions).FirstOrDefault((Func)((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 ItemPrices = new Dictionary { { "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 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 allStorableItemDefinitions = Utils.GetAllStorableItemDefinitions(); Dictionary itemMap = (from x in allStorableItemDefinitions group x by ((BaseItemDefinition)x).ID).ToDictionary((IGrouping g) => g.Key, (IGrouping g) => g.Last()); List 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(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 { [HarmonyWrapSafe] public static bool Prefix(DeliveryApp __instance, ShopInterface matchingShop, bool available) { DeliveryShopElement val = __instance._shopElements.AsEnumerable().FirstOrDefault((Func)((DeliveryShopElement x) => (Object)(object)x.Shop.MatchingShop == (Object)(object)matchingShop)); Debug.Log((object)("Setting delivery shop " + matchingShop.ShopName + " availability to " + available)); if (val != null) { ((Component)val.Button).gameObject.SetActive(available); } Logger.Debug("SetIsAvailable: " + matchingShop?.ShopName); return false; } 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.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 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; [HarmonyWrapSafe] public static void Prefix(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 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, 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(); 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(); foreach (Image val5 in componentsInChildren2) { if (((Object)((Component)val5).gameObject).name == "Image") { val5.sprite = Registries.GetShopImage(customShop); } } if (Utils.Is(val2.GetComponent(), out var result)) { ((Graphic)result).color = customShop.ShopColor; } Button component = val2.GetComponent