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 BetterRollover v0.0.4
BetterRollover.dll
Decompiled 5 hours agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CustomQuotaSystem.Patches; using HarmonyLib; using LethalNetworkAPI; 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(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace CustomQuotaSystem { public static class ConfigManager { public static ConfigEntry<int> StartingCredits { get; private set; } public static ConfigEntry<int> StartingQuota { get; private set; } public static ConfigEntry<int> DaysToDeadline { get; private set; } public static ConfigEntry<int> BaseIncrease { get; private set; } public static ConfigEntry<float> CurveSharpness { get; private set; } public static ConfigEntry<float> RandomizerMultiplier { get; private set; } public static ConfigEntry<float> OvertimePayPercent { get; private set; } public static ConfigEntry<bool> DisableQuota { get; private set; } public static ConfigEntry<int> QuotaCap { get; private set; } internal static void Initialize(ConfigFile config) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown StartingCredits = config.Bind<int>("Basic", "StartingCredits", 60, "Starting credits for a new lobby."); StartingQuota = config.Bind<int>("Basic", "StartingQuota", 130, "Starting quota for a new lobby."); DaysToDeadline = config.Bind<int>("Basic", "DaysToDeadline", 3, "Number of days to meet each quota."); BaseIncrease = config.Bind<int>("Quota Scaling", "BaseIncrease", 100, "Base amount the quota increases per cycle."); CurveSharpness = config.Bind<float>("Quota Scaling", "CurveSharpness", 16f, "Controls how fast the quota ramps up. Higher = slower growth."); RandomizerMultiplier = config.Bind<float>("Quota Scaling", "RandomizerMultiplier", 1f, "Random variance on each quota increase. 0 = no randomness, 1 = ±50%."); OvertimePayPercent = config.Bind<float>("Rollover", "OvertimePayPercent", 0.2f, new ConfigDescription("Percentage of excess scrap beyond (new quota - 1) that is paid as bonus credits. 0.2 = 20% of excess becomes credits.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); DisableQuota = config.Bind<bool>("Basic", "DisableQuota", true, "Completely disables the custom quota system."); QuotaCap = config.Bind<int>("Quota Scaling", "QuotaCap", -1, "Maximum quota value. Set -1 for no limit."); } } [BepInPlugin("Syntheal.BetterRollover", "BetterRollover", "0.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class QuotaManager : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("Syntheal.BetterRollover"); public static QuotaManager Instance; public static ManualLogSource Log; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ConfigManager.Initialize(((BaseUnityPlugin)this).Config); NetworkSync.Initialize(); Log.LogInfo((object)"Custom Quota System loaded!"); harmony.PatchAll(); } } } namespace CustomQuotaSystem.Patches { internal static class NetworkSync { private static LNetworkMessage<int> _syncRolloverMessage; private static LNetworkMessage<int> _syncDeadlineMessage; private static LNetworkMessage<int> _syncQuotaMessage; public static void Initialize() { try { _syncRolloverMessage = LNetworkMessage<int>.Connect("CustomQuotaSystem_SyncRollover", (Action<int, ulong>)null, (Action<int>)OnRolloverReceived, (Action<int, ulong>)null); _syncDeadlineMessage = LNetworkMessage<int>.Connect("CustomQuotaSystem_SyncDeadline", (Action<int, ulong>)null, (Action<int>)OnDeadlineReceived, (Action<int, ulong>)null); _syncQuotaMessage = LNetworkMessage<int>.Connect("CustomQuotaSystem_SyncQuota", (Action<int, ulong>)null, (Action<int>)OnQuotaReceived, (Action<int, ulong>)null); QuotaManager.Log.LogInfo((object)"Network sync initialized."); } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not initialize network sync: " + ex.Message)); } } public static void SyncRolloverToClients(int rollover) { try { if (_syncRolloverMessage == null) { QuotaManager.Log.LogWarning((object)"Rollover message not initialized"); return; } _syncRolloverMessage.SendClients(rollover); QuotaManager.Log.LogInfo((object)$"Synced rollover {rollover} to clients"); } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not sync rollover: " + ex.Message)); } } public static void SyncDeadlineToClients(int deadline) { try { if (_syncDeadlineMessage == null) { QuotaManager.Log.LogWarning((object)"Deadline message not initialized"); } else { _syncDeadlineMessage.SendClients(deadline); } } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not sync deadline: " + ex.Message)); } } public static void SyncQuotaToClients(int quota) { try { if (_syncQuotaMessage == null) { QuotaManager.Log.LogWarning((object)"Quota message not initialized"); } else { _syncQuotaMessage.SendClients(quota); } } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not sync quota: " + ex.Message)); } } private static void OnRolloverReceived(int rollover) { try { TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance != (Object)null) { instance.quotaFulfilled = rollover; QuotaManager.Log.LogInfo((object)$"Client received rollover: {rollover}"); } } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not apply synced rollover on client: " + ex.Message)); } } private static void OnDeadlineReceived(int deadline) { try { TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance != (Object)null) { instance.daysUntilDeadline = deadline; if (instance.totalTime > 0f) { instance.timeUntilDeadline = instance.totalTime * (float)deadline; } } } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not apply synced deadline on client: " + ex.Message)); } } private static void OnQuotaReceived(int quota) { try { TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance != (Object)null) { instance.profitQuota = quota; } } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not apply synced quota on client: " + ex.Message)); } } } [HarmonyPatch(typeof(Terminal))] internal static class TerminalPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void ApplyStartingCredits(Terminal __instance) { try { int value = ConfigManager.StartingCredits.Value; if (value >= 0) { __instance.groupCredits = value; QuotaManager.Log.LogInfo((object)$"Starting credits set to {value}."); } } catch (Exception ex) { QuotaManager.Log.LogWarning((object)("Could not apply starting credits: " + ex.Message)); } } } [HarmonyPatch(typeof(TimeOfDay))] internal static class TimeOfDayPatch { private static bool _initialQuotaApplied; [HarmonyPatch("Awake")] [HarmonyPostfix] private static void TimeOfDay_Awake_Postfix(TimeOfDay __instance) { ApplyQuotaVariables(__instance); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void TimeOfDay_Start_Postfix(TimeOfDay __instance) { if (__instance.timesFulfilledQuota == 0 && !_initialQuotaApplied) { _initialQuotaApplied = true; if (((NetworkBehaviour)__instance).IsServer) { int num = (__instance.profitQuota = ConfigManager.StartingQuota.Value); __instance.quotaFulfilled = 0; QuotaManager.Log.LogInfo((object)$"Initial quota set to {num}"); NetworkSync.SyncQuotaToClients(num); NetworkSync.SyncRolloverToClients(0); } } } private static void ApplyQuotaVariables(TimeOfDay instance) { try { if (instance.quotaVariables != null) { instance.quotaVariables.startingQuota = ConfigManager.StartingQuota.Value; instance.quotaVariables.startingCredits = ConfigManager.StartingCredits.Value; QuotaManager.Log.LogInfo((object)$"Quota variables set: startingQuota={ConfigManager.StartingQuota.Value}, startingCredits={ConfigManager.StartingCredits.Value}"); } } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not apply quota settings at startup: " + ex.Message)); } } [HarmonyPatch("SetNewProfitQuota")] [HarmonyPrefix] private static bool SetNewProfitQuota_Prefix(TimeOfDay __instance, ref int ___timesFulfilledQuota, ref int ___profitQuota, ref float ___timeUntilDeadline, ref int ___quotaFulfilled, ref int ___daysUntilDeadline, ref float ___totalTime) { try { if (!((NetworkBehaviour)__instance).IsServer) { return false; } if (ConfigManager.DisableQuota.Value) { ___profitQuota = Mathf.Max(0, ConfigManager.StartingQuota.Value); SetDeadlineTimer(___totalTime, ref ___daysUntilDeadline, ref ___timeUntilDeadline); NetworkSync.SyncQuotaToClients(___profitQuota); NetworkSync.SyncRolloverToClients(0); NetworkSync.SyncDeadlineToClients(___daysUntilDeadline); return false; } int num = ___profitQuota; ___timesFulfilledQuota++; int num2 = CalculateNewQuota(num, ___timesFulfilledQuota); int prevDays = ___daysUntilDeadline; int num3 = ___quotaFulfilled - num; int num4 = num2 - 1; int num5 = Mathf.Min(num3, num4); int num6 = Mathf.Max(0, num3 - num4); int num7 = Mathf.RoundToInt((float)num6 * ConfigManager.OvertimePayPercent.Value); int num8 = SetDeadlineTimer(___totalTime, ref ___daysUntilDeadline, ref ___timeUntilDeadline, prevDays); __instance.quotaVariables.deadlineDaysAmount = num8; ___profitQuota = num2; ___quotaFulfilled = num5; ___daysUntilDeadline = num8; ___timeUntilDeadline = ___totalTime * (float)num8; __instance.SyncNewProfitQuotaClientRpc(num2, num7, ___timesFulfilledQuota); NetworkSync.SyncQuotaToClients(num2); NetworkSync.SyncRolloverToClients(num5); NetworkSync.SyncDeadlineToClients(num8); QuotaManager.Log.LogInfo((object)($"Quota {___timesFulfilledQuota}: {num} -> {num2}, " + $"overage: {num3}, rollover: {num5}/{num4}, " + $"overtime scrap: {num6}, overtime bonus: ${num7}")); return false; } catch (Exception ex) { QuotaManager.Log.LogError((object)("Could not calculate the next quota: " + ex.Message)); return true; } } private static int CalculateNewQuota(int previousQuota, int timesFulfilled) { float num = Mathf.Max(0.1f, ConfigManager.CurveSharpness.Value); float num2 = timesFulfilled; float num3 = Mathf.Clamp(1f + num2 * (num2 / num), 0f, 10000f); float num4 = 1f; float value = ConfigManager.RandomizerMultiplier.Value; if (value > 0f) { num4 = 1f + Random.Range(-0.5f, 0.5f) * value; } float num5 = (float)ConfigManager.BaseIncrease.Value * num3 * num4; int num6 = Mathf.RoundToInt(Mathf.Clamp((float)previousQuota + num5, 0f, 1E+09f)); int value2 = ConfigManager.QuotaCap.Value; if (value2 != -1) { num6 = Mathf.Min(num6, value2); } return num6; } private static int SetDeadlineTimer(float dayDuration, ref int days, ref float timeUntilDeadline, int prevDays = -1) { int num = (days = Mathf.Max(1, ConfigManager.DaysToDeadline.Value)); timeUntilDeadline = (float)num * dayDuration; return num; } } }