Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of FurnitureDelivery v1.5.0
FurnitureDelivery-IL2CPP.dll
Decompiled 2 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FurnitureDelivery; using FurnitureDelivery.Helpers; using FurnitureDelivery.Interop; using FurnitureDelivery.Shops; using HarmonyLib; using Il2Cpp; using Il2CppFishNet.Connection; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.Delivery; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.UI.Phone.Delivery; using Il2CppScheduleOne.UI.Shop; using Il2CppScheduleOne.Vehicles; using Il2CppScheduleOne.Vehicles.Modification; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; 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", "1.5.0", "k073l", null)] [assembly: MelonColor(1, 255, 215, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonOptionalDependencies(new string[] { "MoreGuns", "Toileportation", "UpgradedTrashCans" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("FurnitureDelivery-IL2CPP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+93abdb3bd6210c85db993ac0134ce56c30aaf6ec")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } 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 = "1.5.0"; } public class FurnitureDelivery : MelonMod { [CompilerGenerated] private sealed class <OnDeliveryManagerReady>d__6 : 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__6(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.AddListener(UnityAction<DeliveryInstance>.op_Implicit((Action<DeliveryInstance>)ToileportationInterop.OnDeliveryCreated)); 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 Instance MelonLogger { get; set; } public override void OnInitializeMelon() { MelonLogger = ((MelonBase)this).LoggerInstance; MelonLogger.Msg("FurnitureDelivery initialized"); if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "MoreGuns")) { MelonLogger.Msg("MoreGuns detected. Adding ak47 to Armory"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "Toileportation")) { MelonLogger.Msg("Toileportation detected. Adding Golden Toilet to Herbert's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "UpgradedTrashCans")) { MelonLogger.Msg("UpgradedTrashCans detected. Adding trash bins to Dan's shop"); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (!MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "Toileportation")) { return; } if (sceneName == "Main") { MelonCoroutines.Start(Utils.WaitForNetworkSingleton<DeliveryManager>(OnDeliveryManagerReady())); MelonLogger.Debug("Repatching CanOrder"); DeliveryShopCanOrderPatch.ApplyManualPatch(); } if (sceneName == "Menu") { if ((Object)(object)NetworkSingleton<DeliveryManager>.Instance != (Object)null) { NetworkSingleton<DeliveryManager>.Instance.onDeliveryCreated.RemoveListener(UnityAction<DeliveryInstance>.op_Implicit((Action<DeliveryInstance>)ToileportationInterop.OnDeliveryCreated)); } ToileportationInterop.GoldenToiletListing = null; } } [IteratorStateMachine(typeof(<OnDeliveryManagerReady>d__6))] private static IEnumerator OnDeliveryManagerReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnDeliveryManagerReady>d__6(0); } } [HarmonyPatch(typeof(DeliveryShop), "SetIsAvailable")] public class DeliveryShopSetIsAvailablePatch { public static Instance Logger = new Instance("FurnitureDelivery-SetIsAvailable"); public static void Postfix(DeliveryShop __instance) { DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; Transform contentT; List<DeliveryShop> initializedShops = DeliveryShopBuilder.GetInitializedShops(instance, out contentT); DeliveryShop val = initializedShops?.FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop item) => ((Object)((Component)item).gameObject).name.StartsWith("Oscar"))); if ((Object)(object)val == (Object)null || ((Object)((Component)__instance).gameObject).name != ((Object)((Component)val).gameObject).name) { return; } Logger.Msg("First Oscar's shop: " + ((Object)((Component)val).gameObject).name + " set to active, setting other one to active"); DeliveryShop val2 = ((IEnumerable<DeliveryShop>)initializedShops).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop item) => ((Object)((Component)item).gameObject).name.StartsWith("DeliveryShop_Oscar"))); if ((Object)(object)val2 == (Object)null) { Logger.Warning("Oscar's equipment shop not found"); return; } ((Component)val2).gameObject.SetActive(true); DeliveryShop val3 = ((IEnumerable<DeliveryShop>)initializedShops).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop item) => ((Object)((Component)item).gameObject).name.StartsWith("DeliveryShop_Armory"))); if ((Object)(object)val3 == (Object)null) { Logger.Warning("Stan's shop not found"); } else { ((Component)val3).gameObject.SetActive(true); } } } internal class InitializedShopsCache { public static Dictionary<string, DeliveryShop> shops = new Dictionary<string, DeliveryShop>(); public static DeliveryShop GetShop(string name) { if (!shops.ContainsKey(name)) { DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; Transform contentT; List<DeliveryShop> initializedShops = DeliveryShopBuilder.GetInitializedShops(instance, out contentT); foreach (DeliveryShop item in initializedShops) { shops.TryAdd(((Object)((Component)item).gameObject).name, item); } } DeliveryShop value; return shops.TryGetValue(name, out value) ? value : null; } public static List<DeliveryShop> GetShops(string name) { if (!shops.Any()) { GetShop(name); } return (from kvp in shops where kvp.Key.Contains(name) select kvp.Value).ToList(); } } [HarmonyPatch(typeof(DeliveryShop), "CanOrder")] public class DeliveryShopCanOrderPatch { public static bool Prefix(DeliveryShop __instance, out string reason, ref bool __result) { string name = ((Object)((Component)__instance).gameObject).name; if (name.Contains("Herbert")) { __result = ToileportationInterop.CanOrder(InitializedShopsCache.GetShops("Herbert"), out reason); if (!__result) { __result = false; return false; } } if (!name.Contains("Dan") && !name.Contains("Oscar")) { reason = string.Empty; return true; } if (name.Contains("Dan")) { List<DeliveryShop> shops = InitializedShopsCache.GetShops("Dan"); foreach (DeliveryShop item in shops) { if (NetworkSingleton<DeliveryManager>.Instance.GetActiveShopDelivery(item) != null) { __result = false; reason = "Dan is currently delivering an order"; return false; } } } if (name.Contains("Oscar")) { List<DeliveryShop> shops2 = InitializedShopsCache.GetShops("Oscar"); foreach (DeliveryShop item2 in shops2) { if (NetworkSingleton<DeliveryManager>.Instance.GetActiveShopDelivery(item2) != null) { __result = false; reason = "Oscar is currently delivering an order"; return false; } } } reason = string.Empty; return true; } public static void ApplyManualPatch() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown Harmony val = new Harmony("com.k0.furnituredelivery"); if (!val.GetPatchedMethods().Contains(AccessTools.Method(typeof(DeliveryShop), "CanOrder", (Type[])null, (Type[])null))) { val.Patch((MethodBase)AccessTools.Method(typeof(DeliveryShop), "CanOrder", (Type[])null, (Type[])null), new HarmonyMethod(typeof(DeliveryShopCanOrderPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } [HarmonyPatch(typeof(DeliveryApp), "Awake")] public class DeliveryAppAwakePatch { public static Instance Logger = new Instance("FurnitureDelivery-AppAwake"); public static void Postfix(DeliveryApp __instance) { Logger.Debug("DeliveryApp Awake called"); DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; DanShop.CreateDanShop(instance); HerbertShop.CreateHerbertShop(instance); OscarShop.CreateOscarShop(instance); StanShop.CreateStanShop(instance); } } } namespace FurnitureDelivery.Shops { public static class DanShop { public static readonly List<string> ItemIDs = new List<string> { "coffeetable", "metalsquaretable", "woodsquaretable", "toilet", "trashcan", "trash_bin", "trash_compactor", "bed", "locker", "TV", "floorlamp", "growtent", "plasticpot", "halogengrowlight", "ledgrowlight", "suspensionrack", "soilpourer", "potsprinkler", "largestoragerack", "mediumstoragerack", "smallstoragerack" }; public static Instance Logger = new Instance("FurnitureDelivery-DanShop"); public static void CreateDanShop(DeliveryApp app) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Dan's Furniture shop"); LandVehicle vehicle = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable<LandVehicle>().FirstOrDefault(); 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(DeliveryShopBuilder.GetOrCreateDeliveryVehicle(vehicle)) .SetPosition(2); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((ItemDefinition)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 shop = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, shop); Logger.Msg("Dan's Furniture created"); } } public class HerbertShop { public static readonly List<string> ItemIDs = new List<string> { "woodensign", "metalsign", "wallmountedshelf", "antiquewalllamp", "modernwalllamp", "wallclock", "grandfatherclock", "safe", "jukebox", "goldenskateboard", "filingcabinet", "smalltrashcan", "dumpster" }; public static Instance Logger = new Instance("FurnitureDelivery-HerbertShop"); public static void CreateHerbertShop(DeliveryApp app) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Herbert's shop"); LandVehicle vehicle = new LandVehicleBuilder().WithVehicleName("LandVehicle_Herbert").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)11) .Build(); 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(DeliveryShopBuilder.GetOrCreateDeliveryVehicle(vehicle)) .SetPosition(5); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((ItemDefinition)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}, {((ItemDefinition)goldenToiletListing.Item).ID}"); } DeliveryShop shop = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, shop); Logger.Msg("Herbert's Curiosities created"); } } public static class OscarShop { public static readonly List<string> ItemIDs = new List<string> { "moisturepreservingpot", "airpot", "fullspectrumgrowlight", "suspensionrack", "packagingstation", "packagingstationmk2", "mixingstation", "mixingstationmk2", "dryingrack", "chemistrystation", "laboven", "cauldron", "brickpress", "locker" }; public static Instance Logger = new Instance("FurnitureDelivery-OscarShop"); public static void CreateOscarShop(DeliveryApp app) { //IL_00b3: 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(); } 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(DeliveryShopBuilder.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) => ((ItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding " + ((ItemDefinition)item).ID + " to Oscar's shop"); deliveryShopBuilder.AddListing(item); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Oscar's Equipment created"); ((Component)val2).gameObject.active = false; } } public class StanShop { public static readonly Dictionary<string, float> ItemPrices = new Dictionary<string, float> { { "baseballbat", 50f }, { "fryingpan", 100f }, { "machete", 250f }, { "revolver", 1000f }, { "revolvercylinder", 10f }, { "m1911", 2500f }, { "m1911mag", 20f }, { "ak47", 15000f }, { "ak47mag", 1000f } }; public static Instance Logger = new Instance("FurnitureDelivery-StanShop"); public static void CreateStanShop(DeliveryApp app) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Stan's shop"); LandVehicle vehicle = new LandVehicleBuilder().WithVehicleName("LandVehicle_Stan").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)0) .Build(); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Armory").WithShopDescription("Weapons and ammo").WithShopColor(new Color(0.8f, 0f, 0f)) .WithShopImage(Utils.FindSprite("Fixer_Mugshot")) .WithDeliveryFee(800f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(DeliveryShopBuilder.GetOrCreateDeliveryVehicle(vehicle)) .SetPosition(8); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<(StorableItemDefinition, float)> list = (from pair in ItemPrices.Select(delegate(KeyValuePair<string, float> kvp) { StorableItemDefinition val2 = ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition i) => ((ItemDefinition)i).ID == kvp.Key)); return ((Object)(object)val2 != (Object)null) ? (val2, kvp.Value) : (null, 0f); }) where (Object)(object)pair.item != (Object)null select pair).ToList(); foreach (var item in list) { Logger.Debug("Adding item " + ((ItemDefinition)item.Item1).ID + " to Stan's shop"); float value = item.Item2; if ((((ItemDefinition)item.Item1).ID == "ak47" || ((ItemDefinition)item.Item1).ID == "ak47mag") && MoreGunsInterop.TryGetPrices("ak47", out var gunPrice, out var magPrice)) { value = ((((ItemDefinition)item.Item1).ID == "ak47") ? gunPrice : magPrice); Logger.Msg($"Using MoreGuns price for '{((ItemDefinition)item.Item1).ID}': {value}"); } deliveryShopBuilder.AddListing(item.Item1, value); } DeliveryShop val = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val); Logger.Msg("Stan's shop created"); ((Component)val).gameObject.active = false; } } } namespace FurnitureDelivery.Interop { 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 || !((ItemDefinition)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 class DeliveryShopBuilder { private string _shopName = "CustomShop"; private string _shopDescription = "Custom shop description"; private Sprite _shopImage = Utils.FindSprite("Salvador_Mugshot"); private Color _shopColor = Color.red; private float _deliveryFee = 100f; private bool _availableByDefault = true; private int _insertPosition = -1; private DeliveryVehicle _deliveryVehicle = null; private readonly List<ShopListing> _listings = new List<ShopListing>(); private readonly DeliveryShop _deliveryShopTemplate; public static readonly Dictionary<LandVehicle, DeliveryVehicle> DeliveryVehicleRegistry = new Dictionary<LandVehicle, DeliveryVehicle>(); public static Instance Logger = new Instance("FurnitureDelivery-DeliveryShopBuilder"); public DeliveryShopBuilder(DeliveryApp appInstance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) _deliveryShopTemplate = ((IEnumerable<DeliveryShop>)((Component)appInstance).GetComponentsInChildren<DeliveryShop>(true)).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 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 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 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)vehicle == (Object)null) { return null; } if (DeliveryVehicleRegistry.TryGetValue(vehicle, out var value) && (Object)(object)value != (Object)null) { return value; } GameObject val = new GameObject("DeliveryVehicle_" + ((Object)vehicle).name); DeliveryVehicle val2 = val.AddComponent<DeliveryVehicle>(); val2.Vehicle = vehicle; Guid gUID = vehicle.GUID; val2.GUID = ((object)(Guid)(ref gUID)).ToString(); DeliveryVehicleRegistry[vehicle] = val2; return val2; } private DeliveryVehicle CreateDeliveryVehicle() { if ((Object)(object)_deliveryVehicle != (Object)null) { return _deliveryVehicle; } if (DeliveryVehicleRegistry.Count == 0) { RegisterAvailableVehicles(); } LandVehicle val = DeliveryVehicleRegistry.Keys.FirstOrDefault(); if ((Object)(object)val == (Object)null) { Logger.Error("No available vehicles registered."); return null; } return GetOrCreateDeliveryVehicle(val); } public DeliveryShopBuilder AddListing(StorableItemDefinition item, float? overridePrice = null, int quantity = 999) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown ShopListing item2 = new ShopListing { name = ((Object)item).name, Item = item, CanBeDelivered = true, OverridePrice = true, OverriddenPrice = (overridePrice ?? item.BasePurchasePrice) }; _listings.Add(item2); return this; } public DeliveryShopBuilder AddListing(ShopListing listing) { _listings.Add(listing); return this; } public DeliveryShopBuilder SetPosition(int position) { _insertPosition = position; return this; } public DeliveryShop Build() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_deliveryShopTemplate == (Object)null) { Logger.Error("Cannot build delivery shop without template."); return null; } GameObject val = new GameObject("ShopInterface_" + _shopName); ShopInterface val2 = val.AddComponent<ShopInterface>(); val2.ShopName = _shopName; val2.Listings = _listings.ToIl2CppList(); val2.DeliveryVehicle = CreateDeliveryVehicle(); ShopInterface.AllShops.Add(val2); DeliveryShop val3 = Object.Instantiate<DeliveryShop>(_deliveryShopTemplate, ((Component)_deliveryShopTemplate).transform.parent); val3.MatchingShopInterfaceName = _shopName; val3.DeliveryFee = _deliveryFee; val3.AvailableByDefault = _availableByDefault; ((Object)((Component)val3).gameObject).name = "DeliveryShop_" + _shopName; Transform val4 = ((Component)val3).transform.Find("Header"); if ((Object)(object)val4 != (Object)null) { Image component = ((Component)val4).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = _shopColor; } Transform val5 = val4.Find("Icon"); if ((Object)(object)val5 != (Object)null) { Transform val6 = val5.Find("Image"); if ((Object)(object)val6 != (Object)null) { Image component2 = ((Component)val6).GetComponent<Image>(); if ((Object)(object)component2 != (Object)null && (Object)(object)_shopImage != (Object)null) { component2.sprite = _shopImage; } } } Transform val7 = val4.Find("Title"); if ((Object)(object)val7 != (Object)null) { Text component3 = ((Component)val7).GetComponent<Text>(); if ((Object)(object)component3 != (Object)null) { component3.text = _shopName; } } Transform val8 = val4.Find("Description"); if ((Object)(object)val8 != (Object)null) { Text component4 = ((Component)val8).GetComponent<Text>(); if ((Object)(object)component4 != (Object)null) { component4.text = _shopDescription; } } } ShopPositionRegistry.ShopPositions[((Object)((Component)val3).gameObject).name] = _insertPosition; ((Component)val3).gameObject.SetActive(true); return val3; } 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.Error("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 = -1; if (ShopPositionRegistry.ShopPositions.TryGetValue(((Object)((Component)shop).gameObject).name, out var value)) { num = value; Logger.Debug($"Found position {num} for shop {((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) { Logger.Debug($"Inserting shop at position {num}"); app.deliveryShops.Insert(num, shop); } else { Logger.Debug($"Adding shop to end at position {num}"); app.deliveryShops.Add(shop); } Logger.Msg("Added new delivery shop to app: " + ((Object)shop).name + ", " + ((Object)((Component)shop).gameObject).name); FixShopHierarchy(app); } private static void FixShopHierarchy(DeliveryApp app) { Transform contentT; List<DeliveryShop> initializedShops = GetInitializedShops(app, out contentT); Logger.Debug($"Found {initializedShops.Count} shop components in UI hierarchy"); for (int i = 0; i < app.deliveryShops.Count; i++) { DeliveryShop val = app.deliveryShops.AsEnumerable<DeliveryShop>().ElementAt(i); if (!(((Object)((Component)val).gameObject).name == "Space") && !((Object)((Component)val).gameObject).name.Contains("Spacer")) { ((Component)val).transform.SetParent(contentT, false); ((Component)val).transform.SetSiblingIndex(i); Logger.Debug($"Set {((Object)((Component)val).gameObject).name} to sibling index {i}"); } } } } public static class ShopPositionRegistry { public static Dictionary<string, int> ShopPositions = new Dictionary<string, int>(); } 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_0028: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(130f, 50f, -250f); Quaternion identity = Quaternion.identity; LandVehicle val2 = NetworkSingleton<VehicleManager>.Instance.SpawnAndReturnVehicle(_vehicleCode, val, identity, false); val2.SetGUID(GUIDManager.GenerateUniqueGUID()); ((Object)val2).name = _vehicleName; ((Object)((Component)val2).gameObject).name = _vehicleName; val2.vehicleName = _vehicleName; val2.vehiclePrice = _vehiclePrice; val2.TopSpeed = _topSpeed; val2.ApplyColor(_color); val2.SetOwnedColor((NetworkConnection)null, _color); val2.SetIsPlayerOwned((NetworkConnection)null, _isPlayerOwned); if (_isPlayerOwned) { NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(val2); } NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(val2); return val2; } } public static class MelonLoggerExtensions { public static void Debug(this Instance logger, string message, bool stacktrace = true) { } private static string GetLoggerName(Instance logger) { return typeof(Instance).GetField("Name", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(logger) as string; } private static void InvokeNativeMsg(Color namesectionColor, Color textColor, string nameSection, string message) { typeof(MelonLogger).GetMethod("NativeMsg", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, new object[5] { namesectionColor, textColor, nameSection, message ?? "null", false }); } 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 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 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(); } } 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; } private 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 (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 }; } } }
FurnitureDelivery-Mono.dll
Decompiled 2 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FishNet.Connection; using FurnitureDelivery; using FurnitureDelivery.Helpers; using FurnitureDelivery.Interop; using FurnitureDelivery.Shops; using HarmonyLib; using MelonLoader; using Microsoft.CodeAnalysis; using ScheduleOne; using ScheduleOne.Delivery; using ScheduleOne.DevUtilities; using ScheduleOne.ItemFramework; using ScheduleOne.UI.Phone.Delivery; using ScheduleOne.UI.Shop; using ScheduleOne.Vehicles; using ScheduleOne.Vehicles.Modification; using UnityEngine; using UnityEngine.Events; 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", "1.5.0", "k073l", null)] [assembly: MelonColor(1, 255, 215, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonOptionalDependencies(new string[] { "MoreGuns", "Toileportation", "UpgradedTrashCans" })] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FurnitureDelivery-Mono")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+93abdb3bd6210c85db993ac0134ce56c30aaf6ec")] [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; } } } 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 = "1.5.0"; } public class FurnitureDelivery : MelonMod { [CompilerGenerated] private sealed class <OnDeliveryManagerReady>d__6 : 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__6(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.AddListener((UnityAction<DeliveryInstance>)ToileportationInterop.OnDeliveryCreated); 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 Instance MelonLogger { get; set; } public override void OnInitializeMelon() { MelonLogger = ((MelonBase)this).LoggerInstance; MelonLogger.Msg("FurnitureDelivery initialized"); if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "MoreGuns")) { MelonLogger.Msg("MoreGuns detected. Adding ak47 to Armory"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "Toileportation")) { MelonLogger.Msg("Toileportation detected. Adding Golden Toilet to Herbert's shop"); } if (MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "UpgradedTrashCans")) { MelonLogger.Msg("UpgradedTrashCans detected. Adding trash bins to Dan's shop"); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (!MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod m) => ((MelonBase)m).Info.Name == "Toileportation")) { return; } if (sceneName == "Main") { MelonCoroutines.Start(Utils.WaitForNetworkSingleton<DeliveryManager>(OnDeliveryManagerReady())); MelonLogger.Debug("Repatching CanOrder"); DeliveryShopCanOrderPatch.ApplyManualPatch(); } if (sceneName == "Menu") { if ((Object)(object)NetworkSingleton<DeliveryManager>.Instance != (Object)null) { NetworkSingleton<DeliveryManager>.Instance.onDeliveryCreated.RemoveListener((UnityAction<DeliveryInstance>)ToileportationInterop.OnDeliveryCreated); } ToileportationInterop.GoldenToiletListing = null; } } [IteratorStateMachine(typeof(<OnDeliveryManagerReady>d__6))] private static IEnumerator OnDeliveryManagerReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnDeliveryManagerReady>d__6(0); } } [HarmonyPatch(typeof(DeliveryShop), "SetIsAvailable")] public class DeliveryShopSetIsAvailablePatch { public static Instance Logger = new Instance("FurnitureDelivery-SetIsAvailable"); public static void Postfix(DeliveryShop __instance) { DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; Transform contentT; List<DeliveryShop> initializedShops = DeliveryShopBuilder.GetInitializedShops(instance, out contentT); DeliveryShop val = initializedShops?.FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop item) => ((Object)((Component)item).gameObject).name.StartsWith("Oscar"))); if ((Object)(object)val == (Object)null || ((Object)((Component)__instance).gameObject).name != ((Object)((Component)val).gameObject).name) { return; } Logger.Msg("First Oscar's shop: " + ((Object)((Component)val).gameObject).name + " set to active, setting other one to active"); DeliveryShop val2 = ((IEnumerable<DeliveryShop>)initializedShops).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop item) => ((Object)((Component)item).gameObject).name.StartsWith("DeliveryShop_Oscar"))); if ((Object)(object)val2 == (Object)null) { Logger.Warning("Oscar's equipment shop not found"); return; } ((Component)val2).gameObject.SetActive(true); DeliveryShop val3 = ((IEnumerable<DeliveryShop>)initializedShops).FirstOrDefault((Func<DeliveryShop, bool>)((DeliveryShop item) => ((Object)((Component)item).gameObject).name.StartsWith("DeliveryShop_Armory"))); if ((Object)(object)val3 == (Object)null) { Logger.Warning("Stan's shop not found"); } else { ((Component)val3).gameObject.SetActive(true); } } } internal class InitializedShopsCache { public static Dictionary<string, DeliveryShop> shops = new Dictionary<string, DeliveryShop>(); public static DeliveryShop GetShop(string name) { if (!shops.ContainsKey(name)) { DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; Transform contentT; List<DeliveryShop> initializedShops = DeliveryShopBuilder.GetInitializedShops(instance, out contentT); foreach (DeliveryShop item in initializedShops) { shops.TryAdd(((Object)((Component)item).gameObject).name, item); } } DeliveryShop value; return shops.TryGetValue(name, out value) ? value : null; } public static List<DeliveryShop> GetShops(string name) { if (!shops.Any()) { GetShop(name); } return (from kvp in shops where kvp.Key.Contains(name) select kvp.Value).ToList(); } } [HarmonyPatch(typeof(DeliveryShop), "CanOrder")] public class DeliveryShopCanOrderPatch { public static bool Prefix(DeliveryShop __instance, out string reason, ref bool __result) { string name = ((Object)((Component)__instance).gameObject).name; if (name.Contains("Herbert")) { __result = ToileportationInterop.CanOrder(InitializedShopsCache.GetShops("Herbert"), out reason); if (!__result) { __result = false; return false; } } if (!name.Contains("Dan") && !name.Contains("Oscar")) { reason = string.Empty; return true; } if (name.Contains("Dan")) { List<DeliveryShop> shops = InitializedShopsCache.GetShops("Dan"); foreach (DeliveryShop item in shops) { if (NetworkSingleton<DeliveryManager>.Instance.GetActiveShopDelivery(item) != null) { __result = false; reason = "Dan is currently delivering an order"; return false; } } } if (name.Contains("Oscar")) { List<DeliveryShop> shops2 = InitializedShopsCache.GetShops("Oscar"); foreach (DeliveryShop item2 in shops2) { if (NetworkSingleton<DeliveryManager>.Instance.GetActiveShopDelivery(item2) != null) { __result = false; reason = "Oscar is currently delivering an order"; return false; } } } reason = string.Empty; return true; } public static void ApplyManualPatch() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown Harmony val = new Harmony("com.k0.furnituredelivery"); if (!val.GetPatchedMethods().Contains(AccessTools.Method(typeof(DeliveryShop), "CanOrder", (Type[])null, (Type[])null))) { val.Patch((MethodBase)AccessTools.Method(typeof(DeliveryShop), "CanOrder", (Type[])null, (Type[])null), new HarmonyMethod(typeof(DeliveryShopCanOrderPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } [HarmonyPatch(typeof(DeliveryApp), "Awake")] public class DeliveryAppAwakePatch { public static Instance Logger = new Instance("FurnitureDelivery-AppAwake"); public static void Postfix(DeliveryApp __instance) { Logger.Debug("DeliveryApp Awake called"); DeliveryApp instance = PlayerSingleton<DeliveryApp>.Instance; DanShop.CreateDanShop(instance); HerbertShop.CreateHerbertShop(instance); OscarShop.CreateOscarShop(instance); StanShop.CreateStanShop(instance); } } } namespace FurnitureDelivery.Shops { public static class DanShop { public static readonly List<string> ItemIDs = new List<string> { "coffeetable", "metalsquaretable", "woodsquaretable", "toilet", "trashcan", "trash_bin", "trash_compactor", "bed", "locker", "TV", "floorlamp", "growtent", "plasticpot", "halogengrowlight", "ledgrowlight", "suspensionrack", "soilpourer", "potsprinkler", "largestoragerack", "mediumstoragerack", "smallstoragerack" }; public static Instance Logger = new Instance("FurnitureDelivery-DanShop"); public static void CreateDanShop(DeliveryApp app) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Dan's Furniture shop"); LandVehicle vehicle = NetworkSingleton<VehicleManager>.Instance.AllVehicles.AsEnumerable().FirstOrDefault(); 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(DeliveryShopBuilder.GetOrCreateDeliveryVehicle(vehicle)) .SetPosition(2); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((ItemDefinition)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 shop = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, shop); Logger.Msg("Dan's Furniture created"); } } public class HerbertShop { public static readonly List<string> ItemIDs = new List<string> { "woodensign", "metalsign", "wallmountedshelf", "antiquewalllamp", "modernwalllamp", "wallclock", "grandfatherclock", "safe", "jukebox", "goldenskateboard", "filingcabinet", "smalltrashcan", "dumpster" }; public static Instance Logger = new Instance("FurnitureDelivery-HerbertShop"); public static void CreateHerbertShop(DeliveryApp app) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Herbert's shop"); LandVehicle vehicle = new LandVehicleBuilder().WithVehicleName("LandVehicle_Herbert").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)11) .Build(); 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(DeliveryShopBuilder.GetOrCreateDeliveryVehicle(vehicle)) .SetPosition(5); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<StorableItemDefinition> list = (from id in ItemIDs select ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition item) => ((ItemDefinition)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}, {((ItemDefinition)goldenToiletListing.Item).ID}"); } DeliveryShop shop = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, shop); Logger.Msg("Herbert's Curiosities created"); } } public static class OscarShop { public static readonly List<string> ItemIDs = new List<string> { "moisturepreservingpot", "airpot", "fullspectrumgrowlight", "suspensionrack", "packagingstation", "packagingstationmk2", "mixingstation", "mixingstationmk2", "dryingrack", "chemistrystation", "laboven", "cauldron", "brickpress", "locker" }; public static Instance Logger = new Instance("FurnitureDelivery-OscarShop"); public static void CreateOscarShop(DeliveryApp app) { //IL_00b3: 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(); } 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(DeliveryShopBuilder.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) => ((ItemDefinition)item).ID == id)) into item where (Object)(object)item != (Object)null select item).ToList(); foreach (StorableItemDefinition item in list) { Logger.Debug("Adding " + ((ItemDefinition)item).ID + " to Oscar's shop"); deliveryShopBuilder.AddListing(item); } DeliveryShop val2 = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val2); Logger.Msg("Oscar's Equipment created"); ((Component)val2).gameObject.active = false; } } public class StanShop { public static readonly Dictionary<string, float> ItemPrices = new Dictionary<string, float> { { "baseballbat", 50f }, { "fryingpan", 100f }, { "machete", 250f }, { "revolver", 1000f }, { "revolvercylinder", 10f }, { "m1911", 2500f }, { "m1911mag", 20f }, { "ak47", 15000f }, { "ak47mag", 1000f } }; public static Instance Logger = new Instance("FurnitureDelivery-StanShop"); public static void CreateStanShop(DeliveryApp app) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) Logger.Debug("Creating Stan's shop"); LandVehicle vehicle = new LandVehicleBuilder().WithVehicleName("LandVehicle_Stan").WithVehicleCode("veeper").WithPlayerOwned(isPlayerOwned: false) .WithColor((EVehicleColor)0) .Build(); DeliveryShopBuilder deliveryShopBuilder = new DeliveryShopBuilder(app).WithShopName("Armory").WithShopDescription("Weapons and ammo").WithShopColor(new Color(0.8f, 0f, 0f)) .WithShopImage(Utils.FindSprite("Fixer_Mugshot")) .WithDeliveryFee(800f) .SetAvailableByDefault(available: true) .WithDeliveryVehicle(DeliveryShopBuilder.GetOrCreateDeliveryVehicle(vehicle)) .SetPosition(8); List<StorableItemDefinition> itemDefinitions = Utils.GetAllStorableItemDefinitions(); List<(StorableItemDefinition, float)> list = (from pair in ItemPrices.Select(delegate(KeyValuePair<string, float> kvp) { StorableItemDefinition val2 = ((IEnumerable<StorableItemDefinition>)itemDefinitions).FirstOrDefault((Func<StorableItemDefinition, bool>)((StorableItemDefinition i) => ((ItemDefinition)i).ID == kvp.Key)); return ((Object)(object)val2 != (Object)null) ? (val2, kvp.Value) : (null, 0f); }) where (Object)(object)pair.item != (Object)null select pair).ToList(); foreach (var item in list) { Logger.Debug("Adding item " + ((ItemDefinition)item.Item1).ID + " to Stan's shop"); float num = item.Item2; if ((((ItemDefinition)item.Item1).ID == "ak47" || ((ItemDefinition)item.Item1).ID == "ak47mag") && MoreGunsInterop.TryGetPrices("ak47", out var gunPrice, out var magPrice)) { num = ((((ItemDefinition)item.Item1).ID == "ak47") ? gunPrice : magPrice); Logger.Msg($"Using MoreGuns price for '{((ItemDefinition)item.Item1).ID}': {num}"); } deliveryShopBuilder.AddListing(item.Item1, num); } DeliveryShop val = deliveryShopBuilder.Build(); DeliveryShopBuilder.Apply(app, val); Logger.Msg("Stan's shop created"); ((Component)val).gameObject.active = false; } } } namespace FurnitureDelivery.Interop { 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 || !((ItemDefinition)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 class DeliveryShopBuilder { private string _shopName = "CustomShop"; private string _shopDescription = "Custom shop description"; private Sprite _shopImage = Utils.FindSprite("Salvador_Mugshot"); private Color _shopColor = Color.red; private float _deliveryFee = 100f; private bool _availableByDefault = true; private int _insertPosition = -1; private DeliveryVehicle _deliveryVehicle = null; private readonly List<ShopListing> _listings = new List<ShopListing>(); private readonly DeliveryShop _deliveryShopTemplate; public static readonly Dictionary<LandVehicle, DeliveryVehicle> DeliveryVehicleRegistry = new Dictionary<LandVehicle, DeliveryVehicle>(); public static Instance Logger = new Instance("FurnitureDelivery-DeliveryShopBuilder"); public DeliveryShopBuilder(DeliveryApp appInstance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) _deliveryShopTemplate = ((Component)appInstance).GetComponentsInChildren<DeliveryShop>(true).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 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 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 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) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if ((Object)(object)vehicle == (Object)null) { return null; } if (DeliveryVehicleRegistry.TryGetValue(vehicle, out var value) && (Object)(object)value != (Object)null) { return value; } GameObject val = new GameObject("DeliveryVehicle_" + ((Object)vehicle).name); DeliveryVehicle val2 = val.AddComponent<DeliveryVehicle>(); val2.Vehicle = vehicle; val2.GUID = vehicle.GUID.ToString(); DeliveryVehicleRegistry[vehicle] = val2; return val2; } private DeliveryVehicle CreateDeliveryVehicle() { if ((Object)(object)_deliveryVehicle != (Object)null) { return _deliveryVehicle; } if (DeliveryVehicleRegistry.Count == 0) { RegisterAvailableVehicles(); } LandVehicle val = DeliveryVehicleRegistry.Keys.FirstOrDefault(); if ((Object)(object)val == (Object)null) { Logger.Error("No available vehicles registered."); return null; } return GetOrCreateDeliveryVehicle(val); } public DeliveryShopBuilder AddListing(StorableItemDefinition item, float? overridePrice = null, int quantity = 999) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown ShopListing item2 = new ShopListing { name = ((Object)item).name, Item = item, CanBeDelivered = true, OverridePrice = true, OverriddenPrice = (overridePrice ?? item.BasePurchasePrice) }; _listings.Add(item2); return this; } public DeliveryShopBuilder AddListing(ShopListing listing) { _listings.Add(listing); return this; } public DeliveryShopBuilder SetPosition(int position) { _insertPosition = position; return this; } public DeliveryShop Build() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_deliveryShopTemplate == (Object)null) { Logger.Error("Cannot build delivery shop without template."); return null; } GameObject val = new GameObject("ShopInterface_" + _shopName); ShopInterface val2 = val.AddComponent<ShopInterface>(); val2.ShopName = _shopName; val2.Listings = _listings; val2.DeliveryVehicle = CreateDeliveryVehicle(); ShopInterface.AllShops.Add(val2); DeliveryShop val3 = Object.Instantiate<DeliveryShop>(_deliveryShopTemplate, ((Component)_deliveryShopTemplate).transform.parent); val3.MatchingShopInterfaceName = _shopName; val3.DeliveryFee = _deliveryFee; val3.AvailableByDefault = _availableByDefault; ((Object)((Component)val3).gameObject).name = "DeliveryShop_" + _shopName; Transform val4 = ((Component)val3).transform.Find("Header"); if ((Object)(object)val4 != (Object)null) { Image component = ((Component)val4).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = _shopColor; } Transform val5 = val4.Find("Icon"); if ((Object)(object)val5 != (Object)null) { Transform val6 = val5.Find("Image"); if ((Object)(object)val6 != (Object)null) { Image component2 = ((Component)val6).GetComponent<Image>(); if ((Object)(object)component2 != (Object)null && (Object)(object)_shopImage != (Object)null) { component2.sprite = _shopImage; } } } Transform val7 = val4.Find("Title"); if ((Object)(object)val7 != (Object)null) { Text component3 = ((Component)val7).GetComponent<Text>(); if ((Object)(object)component3 != (Object)null) { component3.text = _shopName; } } Transform val8 = val4.Find("Description"); if ((Object)(object)val8 != (Object)null) { Text component4 = ((Component)val8).GetComponent<Text>(); if ((Object)(object)component4 != (Object)null) { component4.text = _shopDescription; } } } ShopPositionRegistry.ShopPositions[((Object)((Component)val3).gameObject).name] = _insertPosition; ((Component)val3).gameObject.SetActive(true); return val3; } 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.Error("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 = -1; if (ShopPositionRegistry.ShopPositions.TryGetValue(((Object)((Component)shop).gameObject).name, out var value)) { num = value; Logger.Debug($"Found position {num} for shop {((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) { Logger.Debug($"Inserting shop at position {num}"); app.deliveryShops.Insert(num, shop); } else { Logger.Debug($"Adding shop to end at position {num}"); app.deliveryShops.Add(shop); } Logger.Msg("Added new delivery shop to app: " + ((Object)shop).name + ", " + ((Object)((Component)shop).gameObject).name); FixShopHierarchy(app); } private static void FixShopHierarchy(DeliveryApp app) { Transform contentT; List<DeliveryShop> initializedShops = GetInitializedShops(app, out contentT); Logger.Debug($"Found {initializedShops.Count} shop components in UI hierarchy"); for (int i = 0; i < app.deliveryShops.Count; i++) { DeliveryShop val = app.deliveryShops.AsEnumerable().ElementAt(i); if (!(((Object)((Component)val).gameObject).name == "Space") && !((Object)((Component)val).gameObject).name.Contains("Spacer")) { ((Component)val).transform.SetParent(contentT, false); ((Component)val).transform.SetSiblingIndex(i); Logger.Debug($"Set {((Object)((Component)val).gameObject).name} to sibling index {i}"); } } } } public static class ShopPositionRegistry { public static Dictionary<string, int> ShopPositions = new Dictionary<string, int>(); } 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_0028: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(130f, 50f, -250f); Quaternion identity = Quaternion.identity; LandVehicle val2 = NetworkSingleton<VehicleManager>.Instance.SpawnAndReturnVehicle(_vehicleCode, val, identity, false); val2.SetGUID(GUIDManager.GenerateUniqueGUID()); ((Object)val2).name = _vehicleName; ((Object)((Component)val2).gameObject).name = _vehicleName; val2.vehicleName = _vehicleName; val2.vehiclePrice = _vehiclePrice; val2.TopSpeed = _topSpeed; val2.ApplyColor(_color); val2.SetOwnedColor((NetworkConnection)null, _color); val2.SetIsPlayerOwned((NetworkConnection)null, _isPlayerOwned); if (_isPlayerOwned) { NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(val2); } NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(val2); return val2; } } public static class MelonLoggerExtensions { public static void Debug(this Instance logger, string message, bool stacktrace = true) { } private static string GetLoggerName(Instance logger) { return typeof(Instance).GetField("Name", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(logger) as string; } private static void InvokeNativeMsg(Color namesectionColor, Color textColor, string nameSection, string message) { typeof(MelonLogger).GetMethod("NativeMsg", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, new object[5] { namesectionColor, textColor, nameSection, message ?? "null", false }); } 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 Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } } 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(); } } 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; } private 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 }; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }