Decompiled source of SurvivorToCash v1.0.2

SurvivorToCash.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[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 SurvivorToCashMod
{
	[BepInPlugin("REPOJP.SurvivorToCash", "SurvivorToCash", "1.0.0")]
	public class SurvivorToCashPlugin : BaseUnityPlugin
	{
		internal enum CurrencyApplyMode
		{
			Add,
			Set
		}

		public const string PluginGuid = "REPOJP.SurvivorToCash";

		public const string PluginName = "SurvivorToCash";

		public const string PluginVersion = "1.0.0";

		internal static SurvivorToCashPlugin Instance = null;

		internal static ManualLogSource Log = null;

		internal static Harmony HarmonyInstance = null;

		internal static SurvivorToCashRuntime Runtime = null;

		internal static ConfigEntry<int> BonusPerAlivePlayer = null;

		internal static ConfigEntry<CurrencyApplyMode> ApplyMode = null;

		internal static ConfigEntry<bool> ShowBigMessage = null;

		internal static ConfigEntry<bool> WriteDebugLog = null;

		internal static ConfigEntry<float> ApplyDelaySeconds = null;

		internal static ConfigEntry<float> VerifyDelaySeconds = null;

		internal static ConfigEntry<int> MaxRetryCount = null;

		internal static string LastScheduledKey = string.Empty;

		private void Awake()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			try
			{
				Instance = this;
				Log = ((BaseUnityPlugin)this).Logger;
				BonusPerAlivePlayer = ((BaseUnityPlugin)this).Config.Bind<int>("General", "BonusPerAlivePlayer", 10, new ConfigDescription("Money value per surviving player at the very end of a successful level. / クリア成功レベルの最後の最後で生存していたプレイヤー1人あたりの金額", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100000), Array.Empty<object>()));
				ApplyMode = ((BaseUnityPlugin)this).Config.Bind<CurrencyApplyMode>("General", "ApplyMode", CurrencyApplyMode.Add, "How to apply the calculated survivor cash to current run currency. Add = add missing survivor cash until the expected amount is reached, Set = overwrite current money with survivor cash. / 計算した生存人数分の金額を現在のラン通貨へどう反映するか Add=期待金額に届くまで不足分を加算 Set=現在額を生存人数分の金額で上書き");
				ShowBigMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowBigMessage", true, "Show a big on-screen message when SurvivorToCash is applied or retried. / SurvivorToCash適用時または再適用時に画面中央へ大きな通知を表示");
				WriteDebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "WriteDebugLog", true, "Write SurvivorToCash schedule, apply, verify, retry and success details to the BepInEx log. / SurvivorToCashの予約、適用、検証、再試行、成功詳細をBepInExログへ出力");
				ApplyDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "ApplyDelaySeconds", 2f, new ConfigDescription("Seconds to wait after shop transition before the first survivor cash apply. / ショップ遷移後に最初の生存人数分通貨反映を行うまでの待機秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
				VerifyDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "VerifyDelaySeconds", 5f, new ConfigDescription("Seconds to wait between each verification and retry. / 通貨反映の再確認と再試行を行う間隔秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
				MaxRetryCount = ((BaseUnityPlugin)this).Config.Bind<int>("Timing", "MaxRetryCount", 5, new ConfigDescription("Maximum number of retry attempts after the first apply if the expected currency is still not reached. / 初回反映後に期待金額へ届いていない場合の最大再試行回数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
				CreateRuntime();
				HarmonyInstance = new Harmony("REPOJP.SurvivorToCash");
				HarmonyInstance.PatchAll();
				Log.LogInfo((object)"SurvivorToCash 1.0.0 loaded");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex));
			}
		}

		private void CreateRuntime()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)Runtime != (Object)null))
			{
				GameObject val = new GameObject("SurvivorToCashRuntime");
				val.transform.parent = null;
				((Object)val).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)val);
				Runtime = val.AddComponent<SurvivorToCashRuntime>();
			}
		}
	}
	internal sealed class SurvivorToCashRuntime : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <ApplyAndVerifyCoroutine>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PendingApplyRequest request;

			public SurvivorToCashRuntime <>4__this;

			private float <applyDelay>5__1;

			private float <verifyDelay>5__2;

			private int <maxRetryCount>5__3;

			private int <retryIndex>5__4;

			private int <currentCurrency>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplyAndVerifyCoroutine>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Expected O, but got Unknown
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (request == null)
					{
						<>4__this.pendingCoroutine = null;
						return false;
					}
					request.CoroutineStarted = true;
					<applyDelay>5__1 = <>4__this.GetApplyDelaySeconds();
					<verifyDelay>5__2 = <>4__this.GetVerifyDelaySeconds();
					<maxRetryCount>5__3 = <>4__this.GetMaxRetryCount();
					if (<applyDelay>5__1 > 0f)
					{
						<>2__current = (object)new WaitForSecondsRealtime(<applyDelay>5__1);
						<>1__state = 1;
						return true;
					}
					goto IL_00c0;
				case 1:
					<>1__state = -1;
					goto IL_00c0;
				case 2:
					{
						<>1__state = -1;
						goto IL_0143;
					}
					IL_0143:
					if (!<>4__this.IsShopContext())
					{
						request.CoroutineStarted = false;
						<>4__this.pendingCoroutine = null;
						return false;
					}
					<currentCurrency>5__5 = <>4__this.SafeGetRunCurrency();
					if (<>4__this.IsRequestSatisfied(request, <currentCurrency>5__5))
					{
						if (SurvivorToCashPlugin.WriteDebugLog != null && SurvivorToCashPlugin.WriteDebugLog.Value)
						{
							SurvivorToCashPlugin.Log.LogInfo((object)("Success SurvivorToCash verification | Key=" + request.ApplyKey + " | Current=" + <currentCurrency>5__5 + " | Expected=" + request.ExpectedCurrency + " | Mode=" + request.ApplyMode.ToString() + " | RetryCount=" + <retryIndex>5__4));
						}
						<>4__this.pendingRequest = null;
						<>4__this.pendingCoroutine = null;
						return false;
					}
					if (<retryIndex>5__4 >= <maxRetryCount>5__3)
					{
						if (SurvivorToCashPlugin.Log != null)
						{
							SurvivorToCashPlugin.Log.LogWarning((object)("GiveUp SurvivorToCash verification | Key=" + request.ApplyKey + " | Current=" + <currentCurrency>5__5 + " | Expected=" + request.ExpectedCurrency + " | Mode=" + request.ApplyMode.ToString() + " | MaxRetryCount=" + <maxRetryCount>5__3));
						}
						<>4__this.pendingRequest = null;
						<>4__this.pendingCoroutine = null;
						return false;
					}
					<retryIndex>5__4++;
					if (SurvivorToCashPlugin.Log != null)
					{
						SurvivorToCashPlugin.Log.LogWarning((object)("Retry SurvivorToCash because expected currency is not reached | Key=" + request.ApplyKey + " | Current=" + <currentCurrency>5__5 + " | Expected=" + request.ExpectedCurrency + " | Mode=" + request.ApplyMode.ToString() + " | RetryIndex=" + <retryIndex>5__4));
					}
					<>4__this.ApplyOrCorrectRequest(request, <retryIndex>5__4);
					goto IL_0425;
					IL_0425:
					if (<retryIndex>5__4 <= <maxRetryCount>5__3)
					{
						if (<verifyDelay>5__2 > 0f)
						{
							<>2__current = (object)new WaitForSecondsRealtime(<verifyDelay>5__2);
							<>1__state = 2;
							return true;
						}
						goto IL_0143;
					}
					<>4__this.pendingRequest = null;
					<>4__this.pendingCoroutine = null;
					return false;
					IL_00c0:
					if (!<>4__this.IsShopContext())
					{
						request.CoroutineStarted = false;
						<>4__this.pendingCoroutine = null;
						return false;
					}
					<>4__this.ApplyOrCorrectRequest(request, 0);
					<retryIndex>5__4 = 0;
					goto IL_0425;
				}
			}

			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 PendingApplyRequest pendingRequest = null;

		private Coroutine pendingCoroutine = null;

		private void Awake()
		{
			try
			{
				((Component)this).transform.parent = null;
				((Object)this).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: Runtime Awake\n" + ex));
				}
			}
		}

		private void Update()
		{
			try
			{
				if (pendingRequest != null && !pendingRequest.CoroutineStarted && IsShopContext())
				{
					StartPendingCoroutine();
				}
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: Runtime Update\n" + ex));
				}
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			try
			{
				if (pendingRequest != null && IsShopContext())
				{
					StartPendingCoroutine();
				}
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: OnSceneLoaded\n" + ex));
				}
			}
		}

		internal void Schedule(PendingApplyRequest request)
		{
			try
			{
				pendingRequest = request;
				if (SurvivorToCashPlugin.WriteDebugLog != null && SurvivorToCashPlugin.WriteDebugLog.Value)
				{
					SurvivorToCashPlugin.Log.LogInfo((object)("Scheduled SurvivorToCash | Key=" + request.ApplyKey + " | Before=" + request.BeforeCurrency + " | Alive=" + request.AliveCount + " | Unit=" + request.UnitValue + " | Calculated=" + request.CalculatedValue + " | Expected=" + request.ExpectedCurrency + " | Mode=" + request.ApplyMode));
				}
				if (IsShopContext())
				{
					StartPendingCoroutine();
				}
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: Schedule\n" + ex));
				}
			}
		}

		private void StartPendingCoroutine()
		{
			if (pendingRequest != null)
			{
				if (pendingCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(pendingCoroutine);
					pendingCoroutine = null;
				}
				pendingCoroutine = ((MonoBehaviour)this).StartCoroutine(ApplyAndVerifyCoroutine(pendingRequest));
			}
		}

		internal void ClearPending()
		{
			try
			{
				pendingRequest = null;
				if (pendingCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(pendingCoroutine);
					pendingCoroutine = null;
				}
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: ClearPending\n" + ex));
				}
			}
		}

		[IteratorStateMachine(typeof(<ApplyAndVerifyCoroutine>d__8))]
		private IEnumerator ApplyAndVerifyCoroutine(PendingApplyRequest request)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyAndVerifyCoroutine>d__8(0)
			{
				<>4__this = this,
				request = request
			};
		}

		private void ApplyOrCorrectRequest(PendingApplyRequest request, int retryIndex)
		{
			try
			{
				if (request == null)
				{
					return;
				}
				int num = SafeGetRunCurrency();
				int num2;
				int num3;
				if (request.ApplyMode == SurvivorToCashPlugin.CurrencyApplyMode.Set)
				{
					num2 = request.CalculatedValue;
					num3 = num2 - num;
					SemiFunc.StatSetRunCurrency(num2);
				}
				else
				{
					if (num >= request.ExpectedCurrency)
					{
						if (SurvivorToCashPlugin.WriteDebugLog != null && SurvivorToCashPlugin.WriteDebugLog.Value)
						{
							SurvivorToCashPlugin.Log.LogInfo((object)("Skip SurvivorToCash correction because expected currency is already reached | Key=" + request.ApplyKey + " | Current=" + num + " | Expected=" + request.ExpectedCurrency));
						}
						return;
					}
					num3 = request.ExpectedCurrency - num;
					num2 = num + num3;
					SemiFunc.StatSetRunCurrency(num2);
				}
				if (SurvivorToCashPlugin.WriteDebugLog != null && SurvivorToCashPlugin.WriteDebugLog.Value)
				{
					SurvivorToCashPlugin.Log.LogInfo((object)(((retryIndex > 0) ? "Corrected SurvivorToCash" : "Applied SurvivorToCash") + " | Key=" + request.ApplyKey + " | RetryIndex=" + retryIndex + " | BeforeRead=" + num + " | Target=" + num2 + " | Correction=" + num3 + " | Alive=" + request.AliveCount + " | Unit=" + request.UnitValue + " | Calculated=" + request.CalculatedValue + " | Expected=" + request.ExpectedCurrency + " | Mode=" + request.ApplyMode));
				}
				ShowApplyMessage(request, retryIndex, num3);
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: ApplyOrCorrectRequest\n" + ex));
				}
			}
		}

		private bool IsRequestSatisfied(PendingApplyRequest request, int currentCurrency)
		{
			if (request == null)
			{
				return true;
			}
			if (request.ApplyMode == SurvivorToCashPlugin.CurrencyApplyMode.Set)
			{
				return currentCurrency == request.CalculatedValue;
			}
			return currentCurrency >= request.ExpectedCurrency;
		}

		private void ShowApplyMessage(PendingApplyRequest request, int retryIndex, int correctionAmount)
		{
			//IL_0107: 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)
			try
			{
				if (request != null && SurvivorToCashPlugin.ShowBigMessage != null && SurvivorToCashPlugin.ShowBigMessage.Value && !((Object)(object)BigMessageUI.instance == (Object)null))
				{
					string text = ((retryIndex > 0) ? ("\nRETRY " + retryIndex) : string.Empty);
					string text2;
					string text3;
					if (request.ApplyMode == SurvivorToCashPlugin.CurrencyApplyMode.Set)
					{
						text2 = SafeDollarString(request.CalculatedValue);
						text3 = "SET";
					}
					else
					{
						text2 = "+" + SafeDollarString(Mathf.Max(0, correctionAmount));
						text3 = "ADD";
					}
					string text4 = "SURVIVOR TO CASH\n" + request.AliveCount + " SURVIVORS  " + text3 + " " + text2 + text;
					BigMessageUI.instance.BigMessage(text4, "moneybag", 32f, Color.green, Color.yellow);
				}
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: ShowApplyMessage\n" + ex));
				}
			}
		}

		private bool IsShopContext()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)RunManager.instance != (Object)null)
				{
					if ((Object)(object)RunManager.instance.levelCurrent != (Object)null && (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelShop)
					{
						return true;
					}
					if ((Object)(object)RunManager.instance.levelCurrent != (Object)null && !string.IsNullOrEmpty(((Object)RunManager.instance.levelCurrent).name))
					{
						string name = ((Object)RunManager.instance.levelCurrent).name;
						if (name.IndexOf("shop", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return true;
						}
					}
				}
				Scene activeScene = SceneManager.GetActiveScene();
				if (!string.IsNullOrEmpty(((Scene)(ref activeScene)).name) && ((Scene)(ref activeScene)).name.IndexOf("shop", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: IsShopContext\n" + ex));
				}
			}
			return false;
		}

		private float GetApplyDelaySeconds()
		{
			if (SurvivorToCashPlugin.ApplyDelaySeconds == null)
			{
				return 2f;
			}
			return Mathf.Max(0f, SurvivorToCashPlugin.ApplyDelaySeconds.Value);
		}

		private float GetVerifyDelaySeconds()
		{
			if (SurvivorToCashPlugin.VerifyDelaySeconds == null)
			{
				return 5f;
			}
			return Mathf.Max(1f, SurvivorToCashPlugin.VerifyDelaySeconds.Value);
		}

		private int GetMaxRetryCount()
		{
			if (SurvivorToCashPlugin.MaxRetryCount == null)
			{
				return 5;
			}
			return Mathf.Max(1, SurvivorToCashPlugin.MaxRetryCount.Value);
		}

		private int SafeGetRunCurrency()
		{
			try
			{
				return SemiFunc.StatGetRunCurrency();
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: SafeGetRunCurrency\n" + ex));
				}
				return 0;
			}
		}

		private string SafeDollarString(int value)
		{
			try
			{
				return SemiFunc.DollarGetString(value);
			}
			catch
			{
				return value.ToString();
			}
		}
	}
	internal sealed class PendingApplyRequest
	{
		internal string ApplyKey = string.Empty;

		internal string LevelName = string.Empty;

		internal int AliveCount = 0;

		internal int UnitValue = 0;

		internal int CalculatedValue = 0;

		internal int BeforeCurrency = 0;

		internal int ExpectedCurrency = 0;

		internal SurvivorToCashPlugin.CurrencyApplyMode ApplyMode = SurvivorToCashPlugin.CurrencyApplyMode.Add;

		internal bool CoroutineStarted = false;
	}
	[HarmonyPatch(typeof(RunManager))]
	internal static class SurvivorToCashRunManagerPatch
	{
		[HarmonyPatch("ChangeLevel")]
		[HarmonyPrefix]
		private static void ChangeLevelPrefix(RunManager __instance, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!ShouldSchedule(__instance, _completedLevel, _levelFailed, _changeLevelType) || (Object)(object)SurvivorToCashPlugin.Runtime == (Object)null)
				{
					return;
				}
				string text = BuildApplyKey(__instance);
				if (string.Equals(SurvivorToCashPlugin.LastScheduledKey, text, StringComparison.Ordinal))
				{
					if (SurvivorToCashPlugin.WriteDebugLog != null && SurvivorToCashPlugin.WriteDebugLog.Value)
					{
						SurvivorToCashPlugin.Log.LogInfo((object)("Skip duplicate schedule: " + text));
					}
					return;
				}
				int num = CountAlivePlayers();
				int value = SurvivorToCashPlugin.BonusPerAlivePlayer.Value;
				int num2 = num * value;
				int num3 = SemiFunc.StatGetRunCurrency();
				int expectedCurrency = ((SurvivorToCashPlugin.ApplyMode.Value != SurvivorToCashPlugin.CurrencyApplyMode.Set) ? (num3 + num2) : num2);
				PendingApplyRequest pendingApplyRequest = new PendingApplyRequest();
				pendingApplyRequest.ApplyKey = text;
				pendingApplyRequest.LevelName = GetLevelNameSafe(__instance);
				pendingApplyRequest.AliveCount = num;
				pendingApplyRequest.UnitValue = value;
				pendingApplyRequest.CalculatedValue = num2;
				pendingApplyRequest.BeforeCurrency = num3;
				pendingApplyRequest.ExpectedCurrency = expectedCurrency;
				pendingApplyRequest.ApplyMode = SurvivorToCashPlugin.ApplyMode.Value;
				SurvivorToCashPlugin.LastScheduledKey = text;
				SurvivorToCashPlugin.Runtime.Schedule(pendingApplyRequest);
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: ChangeLevelPrefix\n" + ex));
				}
			}
		}

		[HarmonyPatch("ResetProgress")]
		[HarmonyPostfix]
		private static void ResetProgressPostfix()
		{
			try
			{
				SurvivorToCashPlugin.LastScheduledKey = string.Empty;
				if ((Object)(object)SurvivorToCashPlugin.Runtime != (Object)null)
				{
					SurvivorToCashPlugin.Runtime.ClearPending();
				}
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: ResetProgressPostfix\n" + ex));
				}
			}
		}

		private static bool ShouldSchedule(RunManager runManager, bool completedLevel, bool levelFailed, ChangeLevelType changeLevelType)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			if ((Object)(object)runManager == (Object)null)
			{
				return false;
			}
			if (SurvivorToCashPlugin.BonusPerAlivePlayer == null || SurvivorToCashPlugin.ApplyMode == null)
			{
				return false;
			}
			if (!completedLevel)
			{
				return false;
			}
			if (levelFailed)
			{
				return false;
			}
			if ((int)changeLevelType > 0)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)null)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)(object)runManager.levelLobby)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)(object)runManager.levelShop)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)(object)runManager.levelArena)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)(object)runManager.levelMainMenu)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)(object)runManager.levelLobbyMenu)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)(object)runManager.levelTutorial)
			{
				return false;
			}
			if ((Object)(object)runManager.levelCurrent == (Object)(object)runManager.levelRecording)
			{
				return false;
			}
			if (runManager.restarting)
			{
				return false;
			}
			return true;
		}

		private static string BuildApplyKey(RunManager runManager)
		{
			string levelNameSafe = GetLevelNameSafe(runManager);
			int levelsCompleted = runManager.levelsCompleted;
			return levelNameSafe + "|" + levelsCompleted;
		}

		private static string GetLevelNameSafe(RunManager runManager)
		{
			if ((Object)(object)runManager == (Object)null)
			{
				return "UnknownLevel";
			}
			if ((Object)(object)runManager.levelCurrent == (Object)null)
			{
				return "UnknownLevel";
			}
			if (string.IsNullOrEmpty(((Object)runManager.levelCurrent).name))
			{
				return "UnknownLevel";
			}
			return ((Object)runManager.levelCurrent).name;
		}

		private static int CountAlivePlayers()
		{
			try
			{
				if ((Object)(object)GameDirector.instance == (Object)null)
				{
					return 0;
				}
				List<PlayerAvatar> playerList = GameDirector.instance.PlayerList;
				if (playerList == null)
				{
					return 0;
				}
				int num = 0;
				foreach (PlayerAvatar item in playerList)
				{
					if (!((Object)(object)item == (Object)null) && !item.isDisabled)
					{
						num++;
					}
				}
				return num;
			}
			catch (Exception ex)
			{
				if (SurvivorToCashPlugin.Log != null)
				{
					SurvivorToCashPlugin.Log.LogError((object)("Failure: CountAlivePlayers\n" + ex));
				}
				return 0;
			}
		}
	}
}