Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BuyRateSettings v1.3.2
BuyRateSettings.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BuyRateSettings.Configuration; using BuyRateSettings.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BuyRateSettings")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("In-game alerts, jackpots, min/max, randomizer, last day rates")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1+f3718c5309867a03dc2352d0bf90c0a659ea20d8")] [assembly: AssemblyProduct("BuyRateSettings")] [assembly: AssemblyTitle("BuyRateSettings")] [assembly: AssemblyVersion("1.3.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace BuyRateSettings { public static class BuyRateRefresher { public static void Refresh() { float companyBuyingRate = StartOfRound.Instance.companyBuyingRate; double num = StartOfRound.Instance.randomMapSeed * 3 + 99; double num2 = num % 100.0 / 100.0; bool minMaxToggle = SyncedInstance<Config>.Instance.minMaxToggle; float minRate = SyncedInstance<Config>.Instance.minRate; float maxRate = SyncedInstance<Config>.Instance.maxRate; bool randomRateToggle = SyncedInstance<Config>.Instance.randomRateToggle; bool lastDayToggle = SyncedInstance<Config>.Instance.lastDayToggle; float lastDayRangeChance = SyncedInstance<Config>.Instance.lastDayRangeChance; float lastDayMinRate = SyncedInstance<Config>.Instance.lastDayMinRate; float lastDayMaxRate = SyncedInstance<Config>.Instance.lastDayMaxRate; float num3 = TimeOfDay.Instance.daysUntilDeadline; bool jackpotToggle = SyncedInstance<Config>.Instance.jackpotToggle; bool jackpotToggleLD = SyncedInstance<Config>.Instance.jackpotToggleLD; double jackpotChance = SyncedInstance<Config>.Instance.jackpotChance; float jackpotMinRate = SyncedInstance<Config>.Instance.jackpotMinRate; float jackpotMaxRate = SyncedInstance<Config>.Instance.jackpotMaxRate; bool flag = false; bool jackpotAlertToggle = SyncedInstance<Config>.Default.jackpotAlertToggle; bool buyRateAlertToggle = SyncedInstance<Config>.Default.buyRateAlertToggle; float alertDelaySeconds = SyncedInstance<Config>.Instance.alertDelaySeconds; float rateDelayTimeSeconds = 3f; BuyRateModifier.mls.LogInfo((object)$"Days left: {TimeOfDay.Instance.daysUntilDeadline}"); BuyRateModifier.mls.LogInfo((object)$"Initial buying rate (pre-calculation): {StartOfRound.Instance.companyBuyingRate}"); BuyRateModifier.mls.LogInfo((object)$"Jackpot chance: {jackpotChance}"); BuyRateModifier.mls.LogInfo((object)$"Map seed: {StartOfRound.Instance.randomMapSeed}"); BuyRateModifier.mls.LogInfo((object)$"Rate seed: {num}"); BuyRateModifier.mls.LogInfo((object)$"Rate seed remainder: {num2}"); if (jackpotToggle && num2 <= jackpotChance && jackpotToggleLD && num3 == 0f) { if (jackpotMinRate != jackpotMaxRate) { companyBuyingRate = Next() * (jackpotMaxRate - jackpotMinRate) + jackpotMinRate; flag = true; BuyRateModifier.mls.LogInfo((object)$"HIT THE JACKPOT - LAST DAY ONLY (RANGED) (unrounded rate: {companyBuyingRate})"); } else { companyBuyingRate = jackpotMinRate; flag = true; BuyRateModifier.mls.LogInfo((object)$"HIT THE JACKPOT - LAST DAY ONLY (NOT RANGED) (unrounded rate: {companyBuyingRate})"); } } else if (jackpotToggle && num2 <= jackpotChance && !jackpotToggleLD) { if (jackpotMinRate != jackpotMaxRate) { companyBuyingRate = Next() * (jackpotMaxRate - jackpotMinRate) + jackpotMinRate; flag = true; BuyRateModifier.mls.LogInfo((object)$"HIT THE JACKPOT - ANY DAY (RANGED) (unrounded rate: {companyBuyingRate})"); } else { companyBuyingRate = jackpotMinRate; flag = true; BuyRateModifier.mls.LogInfo((object)$"HIT THE JACKPOT - ANY DAY (NOT RANGED) (unrounded rate: {companyBuyingRate})"); } } else if (lastDayToggle && num3 == 0f) { if (lastDayMinRate != lastDayMaxRate && num2 <= (double)lastDayRangeChance) { companyBuyingRate = Next() * (lastDayMaxRate - lastDayMinRate) + lastDayMinRate; BuyRateModifier.mls.LogInfo((object)$"Last day rate (ranged-hit) picked (unrounded rate: {companyBuyingRate})"); } else if (lastDayMinRate != lastDayMaxRate && num2 > (double)lastDayRangeChance) { companyBuyingRate = 1f; BuyRateModifier.mls.LogInfo((object)$"Last day rate (ranged-nohit) picked (unrounded rate: {companyBuyingRate})"); } else { companyBuyingRate = lastDayMinRate; BuyRateModifier.mls.LogInfo((object)$"Last day rate (not ranged) picked (unrounded rate: {companyBuyingRate})"); } } else if (randomRateToggle && minMaxToggle) { companyBuyingRate = Next() * (maxRate - minRate) + minRate; BuyRateModifier.mls.LogInfo((object)$"Random Rate picked (unrounded rate: {companyBuyingRate})"); } else if (minMaxToggle && StartOfRound.Instance.companyBuyingRate <= minRate) { companyBuyingRate = minRate; BuyRateModifier.mls.LogInfo((object)$"Min rate picked (unrounded rate: {companyBuyingRate})"); } else if (minMaxToggle && StartOfRound.Instance.companyBuyingRate >= maxRate) { companyBuyingRate = maxRate; BuyRateModifier.mls.LogInfo((object)$"Max rate picked (unrounded rate: {companyBuyingRate})"); } else { companyBuyingRate = StartOfRound.Instance.companyBuyingRate; BuyRateModifier.mls.LogInfo((object)$"Vanilla rate picked (unrounded rate: {companyBuyingRate})"); } int buyRateRounded = (int)Math.Round(companyBuyingRate * 100f); StartOfRound.Instance.companyBuyingRate = companyBuyingRate; BuyRateModifier.mls.LogInfo((object)("Set Company buy rate to: " + buyRateRounded + "%")); ((MonoBehaviour)TimeOfDay.Instance).StartCoroutine(BuyRateSetter(rateDelayTimeSeconds, companyBuyingRate, buyRateRounded)); if (jackpotAlertToggle && flag) { ((MonoBehaviour)TimeOfDay.Instance).StartCoroutine(BuyRateAlertJackpot(alertDelaySeconds, buyRateRounded)); } else if (buyRateAlertToggle) { ((MonoBehaviour)TimeOfDay.Instance).StartCoroutine(BuyRateAlertNormal(alertDelaySeconds, buyRateRounded)); } static float Next() { Random random = new Random(StartOfRound.Instance.randomMapSeed); return (float)random.NextDouble(); } } private static IEnumerator BuyRateSetter(float rateDelayTimeSeconds, float buyRate, int buyRateRounded) { yield return (object)new WaitForSeconds(rateDelayTimeSeconds); StartOfRound.Instance.companyBuyingRate = buyRate; BuyRateModifier.mls.LogInfo((object)("Set Company buy rate to " + buyRateRounded + "% (delayed)")); } private static IEnumerator BuyRateAlertNormal(float alertDelayTimeSeconds, int buyRateRounded) { yield return (object)new WaitForSecondsRealtime(alertDelayTimeSeconds); HUDManager.Instance.DisplayTip("New Scrap Rate", "\n* Buying rates have changed to " + buyRateRounded + "%", false, false, "LC_JackpotTip2"); BuyRateModifier.mls.LogInfo((object)$"Sent normal alert. Rate: {buyRateRounded}"); } private static IEnumerator BuyRateAlertJackpot(float alertDelayTimeSeconds, int buyRateRounded) { yield return (object)new WaitForSecondsRealtime(alertDelayTimeSeconds); HUDManager.Instance.DisplayTip("<color=#ffc526>SCRAP EMERGENCY</color>", "<color=#fcbf17>\n* Buying rates have soared to " + buyRateRounded + "%</color>", true, false, "LC_JackpotTip1"); HUDManager.Instance.UIAudio.PlayOneShot(HUDManager.Instance.globalNotificationSFX); BuyRateModifier.mls.LogInfo((object)$"Sent jackpot alert. Rate: {buyRateRounded}"); } } [BepInPlugin("MoonJuice.BuyRateSettings", "BuyRateSettings", "1.3.1")] public sealed class BuyRateModifier : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("MoonJuice.BuyRateSettings"); private static BuyRateModifier Instance; public static ManualLogSource mls; public static Config BRconfig { get; private set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } BRconfig = new Config(((BaseUnityPlugin)this).Config); mls = Logger.CreateLogSource("MoonJuice.BuyRateSettings"); mls.LogInfo((object)"Loading buy rate patches..."); harmony.PatchAll(typeof(BuyRateModifier)); harmony.PatchAll(typeof(Config)); harmony.PatchAll(typeof(TimeOfDayPatch)); harmony.PatchAll(typeof(GameNetworkManagerPatch)); mls.LogInfo((object)"The Company's buy rates have been patched."); } } internal static class GeneratedPluginInfo { public const string Identifier = "MoonJuice.BuyRateSettings"; public const string Name = "BuyRateSettings"; public const string Version = "1.3.1"; } } namespace BuyRateSettings.Patches { [HarmonyPatch(typeof(GameNetworkManager))] public class GameNetworkManagerPatch { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } [HarmonyPostfix] [HarmonyPatch("Singleton_OnClientConnectedCallback")] public static void InitializeLocalPlayer() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0026: 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_0031: Expected O, but got Unknown if (SyncedInstance<Config>.IsHost) { try { CustomMessagingManager messageManager = SyncedInstance<Config>.MessageManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = Config.OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } messageManager.RegisterNamedMessageHandler("BuyRateSettings_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); SyncedInstance<Config>.Synced = true; return; } catch (Exception ex) { BuyRateModifier.mls.LogError((object)ex); return; } } SyncedInstance<Config>.Synced = false; CustomMessagingManager messageManager2 = SyncedInstance<Config>.MessageManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = Config.OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } messageManager2.RegisterNamedMessageHandler("BuyRateSettings_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); Config.RequestSync(); } [HarmonyPostfix] [HarmonyPatch("StartDisconnect")] public static void PlayerLeave() { SyncedInstance<Config>.RevertSync(); } } [HarmonyPatch(typeof(StartOfRound))] public class StartOfRoundPatch { public static int randomMapSeed = StartOfRound.Instance.randomMapSeed; public static SelectableLevel[] levels = StartOfRound.Instance.levels; public static int daysPlayersSurvivedInARow = StartOfRound.Instance.daysPlayersSurvivedInARow; public static AnimationCurve planetsWeatherRandomCurve = StartOfRound.Instance.planetsWeatherRandomCurve; [HarmonyPrefix] [HarmonyPatch("SetPlanetsWeather")] public static void SetPlanetsWeather(int connectedPlayersOnServer = 0) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < levels.Length; i++) { levels[i].currentWeather = (LevelWeatherType)(-1); if (levels[i].overrideWeather) { levels[i].currentWeather = levels[i].overrideWeatherType; } } Random random = new Random(randomMapSeed + 31); List<SelectableLevel> list = levels.ToList(); float num = 1f; if (connectedPlayersOnServer + 1 > 1 && daysPlayersSurvivedInARow > 2 && daysPlayersSurvivedInARow % 3 == 0) { num = (float)random.Next(15, 25) / 10f; } int num2 = Mathf.Clamp((int)(Mathf.Clamp(planetsWeatherRandomCurve.Evaluate((float)random.NextDouble()) * num, 0f, 1f) * (float)levels.Length), 0, levels.Length); for (int j = 0; j < num2; j++) { SelectableLevel val = list[random.Next(0, list.Count)]; if (val.randomWeathers != null && val.randomWeathers.Length != 0) { val.currentWeather = val.randomWeathers[random.Next(0, val.randomWeathers.Length)].weatherType; } list.Remove(val); } } } [HarmonyPatch(typeof(TimeOfDay))] internal static class TimeOfDayPatch { [HarmonyPostfix] [HarmonyPatch("SetBuyingRateForDay")] public static void SetBuyRate() { if ((SyncedInstance<Config>.Synced && !NetworkManager.Singleton.IsHost) || NetworkManager.Singleton.IsHost) { BuyRateRefresher.Refresh(); } } } } namespace BuyRateSettings.Configuration { [Serializable] public class Config : SyncedInstance<Config> { private static ConfigFile cfg; public static ConfigEntry<bool>? minMaxToggleEntry { get; private set; } public static ConfigEntry<float>? minRateEntry { get; private set; } public static ConfigEntry<float>? maxRateEntry { get; private set; } public static ConfigEntry<bool>? randomRateToggleEntry { get; private set; } public static ConfigEntry<bool>? lastDayToggleEntry { get; private set; } public static ConfigEntry<float>? lastDayRangeChanceEntry { get; private set; } public static ConfigEntry<float>? lastDayMinRateEntry { get; private set; } public static ConfigEntry<float>? lastDayMaxRateEntry { get; private set; } public static ConfigEntry<bool>? jackpotToggleEntry { get; private set; } public static ConfigEntry<bool>? jackpotToggleLDEntry { get; private set; } public static ConfigEntry<double>? jackpotChanceEntry { get; private set; } public static ConfigEntry<float>? jackpotMinRateEntry { get; private set; } public static ConfigEntry<float>? jackpotMaxRateEntry { get; private set; } public static ConfigEntry<bool>? jackpotAlertToggleEntry { get; private set; } public static ConfigEntry<bool>? buyRateAlertToggleEntry { get; private set; } public static ConfigEntry<float>? alertDelaySecondsEntry { get; private set; } public bool minMaxToggle { get; private set; } public float minRate { get; private set; } public float maxRate { get; private set; } public bool randomRateToggle { get; private set; } public bool lastDayToggle { get; private set; } public float lastDayRangeChance { get; private set; } public float lastDayMinRate { get; private set; } public float lastDayMaxRate { get; private set; } public float daysUntilDeadline { get; private set; } public bool jackpotToggle { get; private set; } public bool jackpotToggleLD { get; private set; } public double jackpotChance { get; private set; } public float jackpotMinRate { get; private set; } public float jackpotMaxRate { get; private set; } public bool jackpotAlertToggle { get; private set; } public bool buyRateAlertToggle { get; private set; } public float alertDelaySeconds { get; private set; } public Config(ConfigFile config) { cfg = config; InitInstance(this); Reload(); } public void Reload(bool setValues = true) { minMaxToggleEntry = cfg.Bind<bool>("Min/Max Rate", "Min/Max Enabled", true, "Guarantees Company buy rates within the set minimum/maximum buy rate values."); minRateEntry = cfg.Bind<float>("Min/Max Rate", "Minimum Rate", 0.2f, "The minimum rate the Company will buy your scrap for (0.2 = 20%)."); maxRateEntry = cfg.Bind<float>("Min/Max Rate", "Maximum Rate", 1.2f, "The maximum rate the Company will buy your scrap for (1.2 = 120%)."); randomRateToggleEntry = cfg.Bind<bool>("Random Rate", "Random Rate Enabled", true, "Randomize the daily buy rate within the minimum/maximum that is set."); lastDayToggleEntry = cfg.Bind<bool>("Last Day Rate", "Last Day Rate Enabled", true, "Guarantees a specified buy rate range on the last day of the deadline.\nIf you want a specific rate, set both the Last Day Min/Max to the same values.\nI recommended having this on while using random rate, so you aren't screwed from a bad roll on the last day."); lastDayRangeChanceEntry = cfg.Bind<float>("Last Day Rate", "Last Day Random Chance", 0.3f, "The chance for the last day rate to be randomized within the 'Last Day Min/Max' range instead of being the default 100% (0.3 = 30%)\n1.0 = Always randomized, 0.0 = Never randomized (always the default 100% rate)"); lastDayMinRateEntry = cfg.Bind<float>("Last Day Rate", "Last Day Minimum Rate", 1f, "The minimum rate to occur on the last day of the deadline (1.0 = 100%)."); lastDayMaxRateEntry = cfg.Bind<float>("Last Day Rate", "Last Day Maximum Rate", 1.2f, "The maximum rate to occur on the last day of the deadline (1.2 = 120%)."); jackpotToggleEntry = cfg.Bind<bool>("Jackpot Rate", "Jackpot Rate Enabled", true, "Enables a chance of rolling the jackpot rate within the minimum/maximum that is set."); jackpotToggleLDEntry = cfg.Bind<bool>("Jackpot Rate", "Jackpot Rate ONLY On Last Day", true, "Only allow jackpot rates on the last day of the deadline."); jackpotChanceEntry = cfg.Bind<double>("Jackpot Rate", "Jackpot Chance", 0.01, "The chance of rolling a jackpot rate (0.01 = 1%)."); jackpotMinRateEntry = cfg.Bind<float>("Jackpot Rate", "Jackpot Minimum Rate", 1.5f, "The minimum jackpot rate (1.5 = 150%)."); jackpotMaxRateEntry = cfg.Bind<float>("Jackpot Rate", "Jackpot Maximum Rate", 3f, "The maximum jackpot rate (3.0 = 300%)."); buyRateAlertToggleEntry = cfg.Bind<bool>("Alerts", "Buy Rate Alerts Enabled", true, "Shows a yellow message on screen with the new daily buy rate.\nCLIENT SIDED, DOES NOT SYNC WITH HOST"); jackpotAlertToggleEntry = cfg.Bind<bool>("Alerts", "Jackpot Alerts Enabled", true, "Shows a red message on screen with the jackpot buy rate (will show as SCRAP EMERGENCY).\nCLIENT SIDED, DOES NOT SYNC WITH HOST"); alertDelaySecondsEntry = cfg.Bind<float>("Alerts", "Alert Delay", 3f, "Number of seconds to wait to display the alert.\nTo prevent overlapping with other mods like BetterEXP and DiscountAlerts, I recommend 8+ seconds."); if (setValues) { minMaxToggle = minMaxToggleEntry.Value; minRate = minRateEntry.Value; maxRate = maxRateEntry.Value; randomRateToggle = randomRateToggleEntry.Value; lastDayToggle = lastDayToggleEntry.Value; lastDayRangeChance = lastDayRangeChanceEntry.Value; lastDayMinRate = lastDayMinRateEntry.Value; lastDayMaxRate = lastDayMaxRateEntry.Value; jackpotToggle = jackpotToggleEntry.Value; jackpotToggleLD = jackpotToggleLDEntry.Value; jackpotChance = jackpotChanceEntry.Value; jackpotMinRate = jackpotMinRateEntry.Value; jackpotMaxRate = jackpotMaxRateEntry.Value; buyRateAlertToggle = buyRateAlertToggleEntry.Value; jackpotAlertToggle = jackpotAlertToggleEntry.Value; alertDelaySeconds = alertDelaySecondsEntry.Value; } } public static void RequestSync() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<Config>.IsClient) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(SyncedInstance<Config>.IntSize, (Allocator)2, -1); try { SyncedInstance<Config>.MessageManager.SendNamedMessage("BuyRateSettings_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<Config>.IsHost) { return; } BuyRateModifier.mls.LogInfo((object)$"Config sync request received from client: {clientId}"); byte[] array = SyncedInstance<Config>.SerializeToBytes(SyncedInstance<Config>.Instance); int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<Config>.IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); SyncedInstance<Config>.MessageManager.SendNamedMessage("BuyRateSettings_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3); } catch (Exception arg) { BuyRateModifier.mls.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}"); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<Config>.IntSize)) { BuyRateModifier.mls.LogError((object)"Config sync error: Could not begin reading buffer."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (!((FastBufferReader)(ref reader)).TryBeginRead(num)) { BuyRateModifier.mls.LogError((object)"Config sync error: Host could not sync."); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); SyncedInstance<Config>.SyncInstance(data); BuyRateModifier.mls.LogInfo((object)"Successfully synced config with host."); BuyRateRefresher.Refresh(); BuyRateModifier.mls.LogInfo((object)"Successfully refreshed post-sync."); } } [Serializable] public class SyncedInstance<T> { [NonSerialized] protected static int IntSize = 4; internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager; internal static bool IsClient => NetworkManager.Singleton.IsClient; internal static bool IsHost => NetworkManager.Singleton.IsHost; public static T Default { get; private set; } public static T Instance { get; private set; } public static bool Synced { get; internal set; } protected void InitInstance(T instance) { Default = instance; Instance = instance; IntSize = 4; } internal static void SyncInstance(byte[] data) { Instance = DeserializeFromBytes(data); Synced = true; } internal static void RevertSync() { Instance = Default; Synced = false; BuyRateModifier.mls.LogInfo((object)"Successfully reverted config back to default."); } public static byte[] SerializeToBytes(T val) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream memoryStream = new MemoryStream(); try { binaryFormatter.Serialize(memoryStream, val); return memoryStream.ToArray(); } catch (Exception arg) { BuyRateModifier.mls.LogError((object)$"Error serializing instance: {arg}"); return null; } } public static T DeserializeFromBytes(byte[] data) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream serializationStream = new MemoryStream(data); try { return (T)binaryFormatter.Deserialize(serializationStream); } catch (Exception arg) { BuyRateModifier.mls.LogError((object)$"Error deserializing instance: {arg}"); return default(T); } } } }