Decompiled source of UnlimitedQuota v1.1.3

UnlimitedQuota.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using Entiffo.UnlimitedQuota.Config;
using Entiffo.UnlimitedQuota.Util;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("UnlimitedQuota")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: AssemblyInformationalVersion("1.1.3")]
[assembly: AssemblyProduct("UnlimitedQuota")]
[assembly: AssemblyTitle("UnlimitedQuota")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 Entiffo.UnlimitedQuota
{
	public static class CompanyAutoRoute
	{
		private static bool _pending;

		private static bool _firedThisCycle;

		private static Coroutine? _routine;

		public static void ClearCycleLatch(string reason = "")
		{
			if (_firedThisCycle || _pending)
			{
				_firedThisCycle = false;
				Plugin.DebugLog("CompanyAutoRoute cycle latch cleared" + (string.IsNullOrEmpty(reason) ? "" : (" (" + reason + ")")) + ".");
			}
		}

		public static void TryScheduleFromShipPhase(string reason)
		{
			if (!Plugin.IsEnabled || (!Plugin.Config.AutoRouteToCompany.Value && !Plugin.Config.AutoLandAtCompany.Value) || !DeadlineApplicator.IsHost() || (Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return;
			}
			if (!StartOfRound.Instance.inShipPhase)
			{
				ClearCycleLatch("left-ship-phase");
			}
			else
			{
				if (StartOfRound.Instance.isChallengeFile)
				{
					return;
				}
				TimeOfDay.Instance.UpdateProfitQuotaCurrentTime();
				if ((TimeOfDay.Instance.daysUntilDeadline <= 0 || !(TimeOfDay.Instance.timeUntilDeadline > 0f)) && !_pending && !_firedThisCycle)
				{
					_pending = true;
					_firedThisCycle = true;
					if (_routine != null)
					{
						((MonoBehaviour)StartOfRound.Instance).StopCoroutine(_routine);
					}
					_routine = ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(RouteAndMaybeLand(reason));
				}
			}
		}

		private static IEnumerator RouteAndMaybeLand(string reason)
		{
			yield return (object)new WaitForSeconds(0.85f);
			try
			{
				StartOfRound sor = StartOfRound.Instance;
				TimeOfDay instance = TimeOfDay.Instance;
				if ((Object)(object)sor == (Object)null || (Object)(object)instance == (Object)null || !((NetworkBehaviour)sor).IsServer || !sor.inShipPhase || sor.isChallengeFile)
				{
					yield break;
				}
				instance.UpdateProfitQuotaCurrentTime();
				if (instance.daysUntilDeadline > 0 && instance.timeUntilDeadline > 0f)
				{
					yield break;
				}
				bool routed = false;
				if (Plugin.Config.AutoRouteToCompany.Value)
				{
					routed = TryRouteNow(sor, reason);
				}
				if (!Plugin.Config.AutoLandAtCompany.Value)
				{
					yield break;
				}
				float waited = 0f;
				while (sor.travellingToNewLevel && waited < 45f)
				{
					waited += Time.unscaledDeltaTime;
					yield return null;
					if ((Object)(object)StartOfRound.Instance == (Object)null)
					{
						yield break;
					}
					sor = StartOfRound.Instance;
				}
				if (sor.travellingToNewLevel || !sor.inShipPhase)
				{
					Plugin.Log.LogWarning((object)"Auto-land skipped: still travelling or left ship phase.");
					yield break;
				}
				yield return (object)new WaitForSeconds(1.1f);
				if (!IsOnCompany(sor))
				{
					Plugin.Log.LogWarning((object)"Auto-land skipped: ship is not at the Company.");
				}
				else
				{
					TryLandNow(sor, routed, reason);
				}
			}
			finally
			{
				_pending = false;
				_routine = null;
			}
		}

		private static bool TryRouteNow(StartOfRound sor, string reason)
		{
			if (sor.travellingToNewLevel)
			{
				return false;
			}
			int num = FindCompanyLevelIndex(sor);
			if (num < 0)
			{
				Plugin.Log.LogWarning((object)"Auto-route to Company failed: no company moon found in levels list.");
				return false;
			}
			if (IsOnCompany(sor) || sor.currentLevelID == num)
			{
				Plugin.DebugLog("Already at Company; skip route (" + reason + ").");
				return false;
			}
			Terminal val = Object.FindObjectOfType<Terminal>();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Auto-route to Company failed: Terminal not found.");
				return false;
			}
			Plugin.Log.LogInfo((object)($"Auto-routing to Company (levels[{num}] '{sor.levels[num].PlanetName}') " + "— 0 days left (" + reason + ")."));
			sor.ChangeLevelServerRpc(num, val.groupCredits);
			if ((Object)(object)HUDManager.Instance != (Object)null)
			{
				HUDManager.Instance.DisplayTip("UnlimitedQuota", "0 days left — ship routed to the Company.", false, false, "UQ_AutoCompany");
			}
			return true;
		}

		private static void TryLandNow(StartOfRound sor, bool justRouted, string reason)
		{
			if (!((NetworkBehaviour)sor).IsServer || !sor.inShipPhase || sor.travellingToNewLevel)
			{
				return;
			}
			StartMatchLever val = Object.FindObjectOfType<StartMatchLever>();
			if ((Object)(object)val != (Object)null)
			{
				try
				{
					val.PlayLeverPullEffectsServerRpc(true);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Auto-land lever FX failed (StartGame still runs): " + ex.Message));
				}
			}
			Plugin.Log.LogInfo((object)$"Auto-landing at Company ({reason}, routed={justRouted}).");
			sor.StartGame();
			if ((Object)(object)HUDManager.Instance != (Object)null)
			{
				HUDManager.Instance.DisplayTip("UnlimitedQuota", "Landing at the Company…", false, false, "UQ_AutoLand");
			}
		}

		private static bool IsOnCompany(StartOfRound sor)
		{
			if ((Object)(object)sor.currentLevel != (Object)null && IsCompanyLevel(sor.currentLevel))
			{
				return true;
			}
			int num = FindCompanyLevelIndex(sor);
			if (num >= 0)
			{
				return sor.currentLevelID == num;
			}
			return false;
		}

		public static int FindCompanyLevelIndex(StartOfRound sor)
		{
			SelectableLevel[] levels = sor.levels;
			if (levels == null || levels.Length == 0)
			{
				return -1;
			}
			for (int i = 0; i < levels.Length; i++)
			{
				if ((Object)(object)levels[i] != (Object)null && levels[i].levelID == 3)
				{
					return i;
				}
			}
			for (int j = 0; j < levels.Length; j++)
			{
				if ((Object)(object)levels[j] != (Object)null && IsCompanyLevel(levels[j]))
				{
					return j;
				}
			}
			return -1;
		}

		public static bool IsCompanyLevel(SelectableLevel level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (level.levelID == 3)
			{
				return true;
			}
			if (!level.planetHasTime && !level.spawnEnemiesAndScrap)
			{
				return true;
			}
			string text = level.PlanetName ?? "";
			if (text.IndexOf("Company", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("Gordion", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}
	}
	public static class DeadlineApplicator
	{
		public static bool IsHost()
		{
			if ((Object)(object)TimeOfDay.Instance != (Object)null)
			{
				return ((NetworkBehaviour)TimeOfDay.Instance).IsServer;
			}
			return false;
		}

		public static void ApplyNewQuotaDeadline(TimeOfDay timeOfDay)
		{
			if (Plugin.IsEnabled && !((Object)(object)timeOfDay == (Object)null) && ((NetworkBehaviour)timeOfDay).IsServer && (!((Object)(object)StartOfRound.Instance != (Object)null) || !StartOfRound.Instance.isChallengeFile))
			{
				CompanyAutoRoute.ClearCycleLatch("new-quota");
				DeadlineCalculator.EnsureBaselineCaptured(timeOfDay);
				int num = ComputeFor(timeOfDay);
				ApplyDays(timeOfDay, num, syncClients: true);
				SaveState.Save(num);
				int num2 = DeadlineCalculator.ResolveBaselineQuota(timeOfDay);
				Plugin.Log.LogInfo((object)($"Deadline days={num} quota={timeOfDay.profitQuota} baseline={num2} " + $"min={Plugin.Config.MinDeadlineDays.Value} step={Plugin.Config.QuotaPerExtraDay.Value} " + $"(formula: {Plugin.Config.MinDeadlineDays.Value}+Floor(max(0,{timeOfDay.profitQuota}-{num2})/{Plugin.Config.QuotaPerExtraDay.Value}))"));
			}
		}

		public static void ApplyOnSaveLoad(TimeOfDay timeOfDay)
		{
			if (!Plugin.IsEnabled || (Object)(object)timeOfDay == (Object)null || !((NetworkBehaviour)timeOfDay).IsServer || ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.isChallengeFile))
			{
				return;
			}
			DeadlineCalculator.EnsureBaselineCaptured(timeOfDay);
			float value = Plugin.Config.MinDeadlineDays.Value;
			int num = ComputeFor(timeOfDay);
			float num2 = SaveState.LoadDeadlineDays(-1f);
			if (num2 < value)
			{
				ApplyDays(timeOfDay, num, syncClients: true);
				SaveState.Save(num);
				Plugin.Log.LogInfo((object)$"Load: fresh deadline days={num} quota={timeOfDay.profitQuota}");
				return;
			}
			int num3 = num;
			float totalTime = DeadlineCalculator.GetTotalTime(timeOfDay);
			if ((float)num3 > num2 + 0.01f)
			{
				timeOfDay.timeUntilDeadline += ((float)num3 - num2) * totalTime;
				Plugin.Log.LogInfo((object)$"Load: extended deadline {num2} → {num3} days (quota={timeOfDay.profitQuota}).");
			}
			else if ((float)num3 + 0.01f < num2)
			{
				float num4 = (float)num3 / Mathf.Max(num2, 1f);
				timeOfDay.timeUntilDeadline = Mathf.Max(0f, timeOfDay.timeUntilDeadline * num4);
				Plugin.Log.LogInfo((object)$"Load: shortened deadline {num2} → {num3} days (quota={timeOfDay.profitQuota}).");
			}
			timeOfDay.quotaVariables.deadlineDaysAmount = num3;
			timeOfDay.UpdateProfitQuotaCurrentTime();
			SaveState.Save(num3);
			if (((NetworkBehaviour)timeOfDay).IsServer)
			{
				timeOfDay.SyncTimeClientRpc(timeOfDay.globalTime, (int)timeOfDay.timeUntilDeadline);
			}
		}

		public static void ResetForNewShip(TimeOfDay timeOfDay)
		{
			if (Plugin.IsEnabled && !((Object)(object)timeOfDay == (Object)null) && ((NetworkBehaviour)timeOfDay).IsServer)
			{
				CompanyAutoRoute.ClearCycleLatch("reset-ship");
				SaveState.Clear();
				DeadlineCalculator.ClearStartingQuotaLatch();
				DeadlineCalculator.EnsureBaselineCaptured(timeOfDay);
				int num = ComputeFor(timeOfDay);
				ApplyDays(timeOfDay, num, syncClients: true);
				SaveState.Save(num);
				Plugin.Log.LogInfo((object)($"ResetShip: deadline days={num} baseline={DeadlineCalculator.ResolveBaselineQuota(timeOfDay)} " + $"quota={timeOfDay.profitQuota}"));
			}
		}

		public static void ApplyDays(TimeOfDay timeOfDay, float days, bool syncClients)
		{
			int num = Mathf.RoundToInt(days);
			timeOfDay.quotaVariables.deadlineDaysAmount = num;
			timeOfDay.timeUntilDeadline = DeadlineCalculator.GetTimeUntilDeadline(timeOfDay, num);
			timeOfDay.UpdateProfitQuotaCurrentTime();
			if (timeOfDay.daysUntilDeadline < num)
			{
				timeOfDay.daysUntilDeadline = num;
			}
			if (syncClients && ((NetworkBehaviour)timeOfDay).IsServer)
			{
				timeOfDay.SyncTimeClientRpc(timeOfDay.globalTime, (int)timeOfDay.timeUntilDeadline);
			}
		}

		public static void SyncDeadlineDaysAmount(TimeOfDay timeOfDay)
		{
			if (!Plugin.IsEnabled || (Object)(object)timeOfDay == (Object)null || timeOfDay.quotaVariables == null || ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.isChallengeFile))
			{
				return;
			}
			int num = ComputeFor(timeOfDay);
			if (num != timeOfDay.quotaVariables.deadlineDaysAmount)
			{
				timeOfDay.quotaVariables.deadlineDaysAmount = num;
				if ((Object)(object)StartOfRound.Instance != (Object)null)
				{
					timeOfDay.SetBuyingRateForDay();
				}
			}
		}

		public static void ReapplyFromQuotaLocal(TimeOfDay timeOfDay)
		{
			if (Plugin.IsEnabled && !((Object)(object)timeOfDay == (Object)null) && timeOfDay.quotaVariables != null && (!((Object)(object)StartOfRound.Instance != (Object)null) || !StartOfRound.Instance.isChallengeFile))
			{
				DeadlineCalculator.EnsureBaselineCaptured(timeOfDay);
				int num = ComputeFor(timeOfDay);
				ApplyDays(timeOfDay, num, syncClients: false);
			}
		}

		internal static int ComputeFor(TimeOfDay timeOfDay)
		{
			return DeadlineCalculator.ComputeDays(timeOfDay.profitQuota, Mathf.RoundToInt(Plugin.Config.MinDeadlineDays.Value), Mathf.RoundToInt(Plugin.Config.QuotaPerExtraDay.Value), DeadlineCalculator.ResolveBaselineQuota(timeOfDay));
		}
	}
	[BepInPlugin("Entiffo.UnlimitedQuota", "UnlimitedQuota", "1.1.3")]
	[BepInDependency("com.sigurd.csync", "5.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "Entiffo.UnlimitedQuota";

		private readonly Harmony _harmony = new Harmony("Entiffo.UnlimitedQuota");

		internal static Plugin Instance { get; private set; }

		internal static ModConfig Config { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static bool IsEnabled => Config.Enabled.Value;

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Config = new ModConfig(((BaseUnityPlugin)this).Config);
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"UnlimitedQuota 1.1.3 loaded.");
		}

		internal static void DebugLog(string message)
		{
			if (Config.DebugLogging.Value)
			{
				Log.LogInfo((object)message);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Entiffo.UnlimitedQuota";

		public const string PLUGIN_NAME = "UnlimitedQuota";

		public const string PLUGIN_VERSION = "1.1.3";
	}
}
namespace Entiffo.UnlimitedQuota.Util
{
	public static class DeadlineCalculator
	{
		public const int MaxDeadlineDays = 20;

		public const int FallbackStartingQuota = 160;

		private static int _latchedBaseline = -1;

		public static int ComputeDays(int profitQuota, int minDays, int quotaPerExtraDay, int baselineQuota)
		{
			int num = Math.Max(1, minDays);
			int num2 = Math.Max(1, quotaPerExtraDay);
			int num3 = Math.Max(0, baselineQuota);
			int num4 = Math.Max(0, profitQuota - num3) / num2;
			int num5 = num + num4;
			if (num5 > 20)
			{
				num5 = 20;
			}
			if (num5 < num)
			{
				num5 = num;
			}
			return num5;
		}

		public static float ComputeDays(float profitQuota, float minDays, float quotaPerExtraDay, float startingQuota)
		{
			return ComputeDays(Mathf.RoundToInt(profitQuota), Mathf.RoundToInt(minDays), Mathf.RoundToInt(quotaPerExtraDay), Mathf.RoundToInt(startingQuota));
		}

		public static int ResolveBaselineQuota(TimeOfDay timeOfDay)
		{
			if (_latchedBaseline > 0)
			{
				return _latchedBaseline;
			}
			int num = SaveState.LoadBaselineQuota(-1);
			if (num > 0)
			{
				_latchedBaseline = num;
				return _latchedBaseline;
			}
			if ((Object)(object)timeOfDay != (Object)null && timeOfDay.profitQuota > 0 && timeOfDay.timesFulfilledQuota == 0)
			{
				_latchedBaseline = timeOfDay.profitQuota;
				SaveState.SaveBaselineQuota(_latchedBaseline);
				return _latchedBaseline;
			}
			_latchedBaseline = 160;
			SaveState.SaveBaselineQuota(_latchedBaseline);
			return _latchedBaseline;
		}

		public static void EnsureBaselineCaptured(TimeOfDay timeOfDay)
		{
			if (!((Object)(object)timeOfDay == (Object)null) && _latchedBaseline <= 0 && SaveState.LoadBaselineQuota(-1) <= 0 && timeOfDay.profitQuota > 0 && timeOfDay.timesFulfilledQuota == 0)
			{
				_latchedBaseline = timeOfDay.profitQuota;
				SaveState.SaveBaselineQuota(_latchedBaseline);
			}
		}

		public static void ClearStartingQuotaLatch()
		{
			_latchedBaseline = -1;
		}

		public static float GetTotalTime(TimeOfDay timeOfDay)
		{
			float num = timeOfDay.totalTime;
			if (num <= 0f)
			{
				num = timeOfDay.lengthOfHours * (float)timeOfDay.numberOfHours;
			}
			return Mathf.Max(num, 1f);
		}

		public static float GetTimeUntilDeadline(TimeOfDay timeOfDay, float days)
		{
			return days * GetTotalTime(timeOfDay) + 0.05f;
		}
	}
	public static class SaveState
	{
		public const string DeadlineDaysKey = "UQ_deadlineDays";

		public const string BaselineQuotaKey = "UQ_baselineQuota";

		private const string LegacyPreviousDailyKey = "UQ_previousDaily";

		private const string LegacyPreviousQuotaKey = "UQ_previousQuota";

		public static string? CurrentSaveName()
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return null;
			}
			return GameNetworkManager.Instance.currentSaveFileName;
		}

		public static float LoadDeadlineDays(float defaultValue)
		{
			string text = CurrentSaveName();
			if (string.IsNullOrEmpty(text))
			{
				return defaultValue;
			}
			return ES3.Load<float>("UQ_deadlineDays", text, defaultValue);
		}

		public static int LoadBaselineQuota(int defaultValue)
		{
			string text = CurrentSaveName();
			if (string.IsNullOrEmpty(text))
			{
				return defaultValue;
			}
			return ES3.Load<int>("UQ_baselineQuota", text, defaultValue);
		}

		public static void Save(float deadlineDays)
		{
			string text = CurrentSaveName();
			if (!string.IsNullOrEmpty(text))
			{
				ES3.Save<float>("UQ_deadlineDays", deadlineDays, text);
			}
		}

		public static void SaveBaselineQuota(int baselineQuota)
		{
			string text = CurrentSaveName();
			if (!string.IsNullOrEmpty(text))
			{
				ES3.Save<int>("UQ_baselineQuota", baselineQuota, text);
			}
		}

		public static void Clear()
		{
			string text = CurrentSaveName();
			if (!string.IsNullOrEmpty(text))
			{
				if (ES3.KeyExists("UQ_deadlineDays", text))
				{
					ES3.DeleteKey("UQ_deadlineDays", text);
				}
				if (ES3.KeyExists("UQ_baselineQuota", text))
				{
					ES3.DeleteKey("UQ_baselineQuota", text);
				}
				if (ES3.KeyExists("UQ_previousDaily", text))
				{
					ES3.DeleteKey("UQ_previousDaily", text);
				}
				if (ES3.KeyExists("UQ_previousQuota", text))
				{
					ES3.DeleteKey("UQ_previousQuota", text);
				}
			}
		}
	}
}
namespace Entiffo.UnlimitedQuota.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")]
	internal static class GameNetworkManagerPatches
	{
		[HarmonyPostfix]
		private static void ResetSavedGameValues_Postfix()
		{
			if (DeadlineApplicator.IsHost())
			{
				SaveState.Clear();
				Plugin.DebugLog("Cleared UnlimitedQuota save keys after ResetSavedGameValues.");
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatches
	{
		[HarmonyPatch("SetTimeAndPlanetToSavedSettings")]
		[HarmonyPostfix]
		private static void SetTimeAndPlanetToSavedSettings_Postfix()
		{
			if (!((Object)(object)TimeOfDay.Instance == (Object)null))
			{
				DeadlineApplicator.ApplyOnSaveLoad(TimeOfDay.Instance);
				CompanyAutoRoute.TryScheduleFromShipPhase("save load");
			}
		}

		[HarmonyPatch("ResetShip")]
		[HarmonyPostfix]
		private static void ResetShip_Postfix()
		{
			if (!((Object)(object)TimeOfDay.Instance == (Object)null))
			{
				DeadlineApplicator.ResetForNewShip(TimeOfDay.Instance);
			}
		}

		[HarmonyPatch("SetShipReadyToLand")]
		[HarmonyPostfix]
		private static void SetShipReadyToLand_Postfix()
		{
			CompanyAutoRoute.TryScheduleFromShipPhase("orbit ready");
		}
	}
	[HarmonyPatch(typeof(TimeOfDay))]
	internal static class TimeOfDayPatches
	{
		[HarmonyPatch("SetNewProfitQuota")]
		[HarmonyPrefix]
		private static void SetNewProfitQuota_Prefix(TimeOfDay __instance, out int __state)
		{
			__state = (((Object)(object)__instance != (Object)null) ? __instance.timesFulfilledQuota : (-1));
		}

		[HarmonyPatch("SetNewProfitQuota")]
		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "Boxofbiscuits97.QuotraRollover" })]
		private static void SetNewProfitQuota_Postfix(TimeOfDay __instance, int __state)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				if (__instance.timesFulfilledQuota == __state)
				{
					Plugin.DebugLog("Skipped deadline apply: SetNewProfitQuota did not advance " + $"(fulfilled still {__state}). Compatible with Quota Rollover cancel.");
				}
				else
				{
					DeadlineApplicator.ApplyNewQuotaDeadline(__instance);
				}
			}
		}

		[HarmonyPatch("SyncTimeClientRpc")]
		[HarmonyPostfix]
		private static void SyncTimeClientRpc_Postfix(TimeOfDay __instance)
		{
			DeadlineApplicator.SyncDeadlineDaysAmount(__instance);
			if ((Object)(object)__instance != (Object)null && ((NetworkBehaviour)__instance).IsServer)
			{
				CompanyAutoRoute.TryScheduleFromShipPhase("sync time");
			}
		}

		[HarmonyPatch("SyncNewProfitQuotaClientRpc")]
		[HarmonyPostfix]
		private static void SyncNewProfitQuotaClientRpc_Postfix(TimeOfDay __instance)
		{
			DeadlineApplicator.ReapplyFromQuotaLocal(__instance);
		}
	}
}
namespace Entiffo.UnlimitedQuota.Config
{
	public class ModConfig : SyncedConfig2<ModConfig>
	{
		public ConfigEntry<bool> DebugLogging { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> Enabled { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> MinDeadlineDays { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> QuotaPerExtraDay { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> AutoRouteToCompany { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> AutoLandAtCompany { get; private set; }

		public ModConfig(ConfigFile cfg)
			: base("Entiffo.UnlimitedQuota")
		{
			//IL_0017: 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_0032: Expected O, but got Unknown
			//IL_0032: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0062: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_0092: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00be: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00ea: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0116: Expected O, but got Unknown
			Enabled = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, new ConfigDefinition("General", "Enabled"), true, new ConfigDescription("Master toggle. When false, vanilla deadlines are used.", (AcceptableValueBase)null, Array.Empty<object>()));
			MinDeadlineDays = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Deadline", "MinDeadlineDays"), 3f, new ConfigDescription("Deadline days at the starting quota.", (AcceptableValueBase)null, Array.Empty<object>()));
			QuotaPerExtraDay = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Deadline", "QuotaPerExtraDay"), 500f, new ConfigDescription("Quota must rise by this much above the FIRST quota of the contract to add +1 deadline day. Does not change how large the quota is — only the day count. Example step 200, first quota 160: 160=3d, 360=4d, 560=5d, 760=6d (555 still 4d, 752 still 5d). Example step 500: 160=3d, 660=4d, 1160=5d.", (AcceptableValueBase)null, Array.Empty<object>()));
			AutoRouteToCompany = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, new ConfigDefinition("Deadline", "AutoRouteToCompany"), true, new ConfigDescription("When 0 days are left, automatically route the ship to the Company.", (AcceptableValueBase)null, Array.Empty<object>()));
			AutoLandAtCompany = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, new ConfigDefinition("Deadline", "AutoLandAtCompany"), false, new ConfigDescription("If on, after routing to the Company on day 0, also pull the lever and land automatically. Default off.", (AcceptableValueBase)null, Array.Empty<object>()));
			DebugLogging = cfg.Bind<bool>(new ConfigDefinition("General", "DebugLogging"), false, new ConfigDescription("Extra logs (local only).", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigManager.Register<ModConfig>((SyncedConfig2<ModConfig>)(object)this);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}