Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of RecommendedPriceIl2Cpp v1.1.2
Mods/RecommendedPrice.Il2Cpp.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Fxcpds; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppScheduleOne.Core.Items.Framework; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Product; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using RecommendedPrice; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Mod), "Recommended Price", "1.1.2", "Foxcapades", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("RecommendedPrice")] [assembly: AssemblyConfiguration("Il2Cpp")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9f29c78855c6d2f08159db0ee3cacc20b8bac4da")] [assembly: AssemblyProduct("RecommendedPrice")] [assembly: AssemblyTitle("RecommendedPrice")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Fxcpds { public abstract class FxMod : MelonMod { private static FxMod? instance; protected const string SCENE_NAME_MAIN = "Main"; public static FxMod Instance => instance; public static Instance Logger => ((MelonBase)instance).LoggerInstance; protected string Scene { get; private set; } = ""; public bool InMainScene { get; private set; } public override void OnEarlyInitializeMelon() { instance = this; } public override void OnSceneWasLoaded(int _, string sceneName) { Scene = sceneName; if (sceneName == "Main") { InMainScene = true; } } public override void OnSceneWasUnloaded(int _, string sceneName) { if (Scene == sceneName) { Scene = ""; } if (sceneName == "Main") { InMainScene = false; } } } } namespace RecommendedPrice { [HarmonyPatch] public class Mod : FxMod { public const string MOD_NAME = "Recommended Price"; private static MelonPreferences_Category? preferences; private static MelonPreferences_Entry<float>? weedModifier; private static MelonPreferences_Entry<float>? cokeModifier; private static MelonPreferences_Entry<float>? methModifier; private static MelonPreferences_Entry<float>? shrmModifier; private static Action<ProductDefinition>? onProductAction; private static readonly Dictionary<string, float> originalProductPrices = new Dictionary<string, float>(12); public override void OnInitializeMelon() { preferences = MelonPreferences.CreateCategory("Recommended Price", "Recommended Price"); weedModifier = preferences.CreateEntry<float>("weedModifier", 1f, "Weed Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)weedModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); cokeModifier = preferences.CreateEntry<float>("cocaineModifier", 1f, "Cocaine Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)cokeModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); methModifier = preferences.CreateEntry<float>("methModifier", 1f, "Meth Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)methModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); shrmModifier = preferences.CreateEntry<float>("shoomModifier", 1f, "Shroom Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)shrmModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); } private void onPrefChange(float o, float n) { if (!Mathf.Approximately(o, n)) { applyInMainOnly(); } } [HarmonyPrefix] [HarmonyPatch(typeof(ProductManager), "OnStartServer")] private static void PreStartServer(ProductManager __instance) { onProductAction = DelegateSupport.ConvertDelegate<Action<ProductDefinition>>((Delegate)new Action<ProductDefinition>(onProduct)); __instance.onProductDiscovered += onProductAction; __instance.onNewProductCreated += onProductAction; } [HarmonyPostfix] [HarmonyPatch(typeof(ProductManager), "Clean")] private static void PostClean(ProductManager __instance) { unapplyModifiers(__instance); if (!((Delegate)(object)onProductAction == (Delegate)null)) { __instance.onProductDiscovered -= onProductAction; __instance.onNewProductCreated -= onProductAction; onProductAction = null; } } private static void applyInMainOnly() { if (!FxMod.Instance.InMainScene) { return; } Instance loggerInstance = ((MelonBase)Melon<Mod>.Instance).LoggerInstance; ProductManager val = NetworkSingleton<ProductManager>.Instance; loggerInstance.Msg("attempting to apply recommended price modifiers"); Dictionary<ProductDefinition, float> productPrices = getProductPrices(); if (productPrices == null) { loggerInstance.Error("failed to get product prices, cannot modify price values"); return; } Enumerator<ProductDefinition> enumerator = val.AllProducts.GetEnumerator(); while (enumerator.MoveNext()) { ProductDefinition current = enumerator.Current; apply(productPrices, current); } } private static void onProduct(ProductDefinition product) { apply(getProductPrices(), product); } private static void apply(Dictionary<ProductDefinition, float>? prices, ProductDefinition product) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) float marketValue = product.MarketValue; originalProductPrices.TryAdd(((BaseItemDefinition)product).ID, product.MarketValue); product.MarketValue = safeMultiply(originalProductPrices[((BaseItemDefinition)product).ID], product.DrugType); float num = default(float); if (prices != null && prices.TryGetValue(product, ref num) && (num == 0f || Mathf.Approximately(num, product.BasePrice) || Mathf.Approximately(num, marketValue))) { prices[product] = product.MarketValue; } } private static void unapplyModifiers(ProductManager manager) { Dictionary<ProductDefinition, float> productPrices = getProductPrices(); Instance loggerInstance = ((MelonBase)Melon<Mod>.Instance).LoggerInstance; loggerInstance.Msg("attempting to revert recommended price modifiers"); if (productPrices == null) { loggerInstance.Error("failed to get product prices, cannot revert price values"); return; } Enumerator<ProductDefinition> enumerator = manager.AllProducts.GetEnumerator(); while (enumerator.MoveNext()) { ProductDefinition current = enumerator.Current; if (!originalProductPrices.ContainsKey(((BaseItemDefinition)current).ID)) { loggerInstance.Warning("unrecognized product id {0}", new object[1] { ((BaseItemDefinition)current).ID }); } else if (!productPrices.ContainsKey(current)) { loggerInstance.Warning("product id {0} not found in product price index", new object[1] { ((BaseItemDefinition)current).ID }); } else { productPrices[current] = originalProductPrices[((BaseItemDefinition)current).ID]; } } } private static float safeMultiply(float price, EDrugType type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown if (1 == 0) { } float num = (int)type switch { 0 => weedModifier.Value, 1 => methModifier.Value, 2 => cokeModifier.Value, 4 => shrmModifier.Value, _ => 1f, }; if (1 == 0) { } float num2 = num; num2 = ((num2 < 0.01f) ? 0.01f : num2); return (float)Math.Round((double)(price * num2), (MidpointRounding)1); } private static Dictionary<ProductDefinition, float>? getProductPrices() { PropertyInfo propertyInfo = AccessTools.DeclaredProperty(typeof(ProductManager), "ProductPrices"); if (propertyInfo == null) { return null; } return (Dictionary<ProductDefinition, float>)propertyInfo.GetValue(NetworkSingleton<ProductManager>.Instance); } } }