Decompiled source of ShopMoneySetter v4.0.0

ShopMoneySetter.dll

Decompiled a day 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 HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Release")]
[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 REPOJP.ShopMoneySetter
{
	[BepInPlugin("REPOJP.ShopMoneySetter", "ShopMoneySetter", "4.0.0")]
	public sealed class ShopMoneySetterPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ShopManager), "ShopInitialize")]
		private static class ShopManagerShopInitializePatch
		{
			private static void Prefix()
			{
				if (!((Object)(object)Instance == (Object)null))
				{
					Instance.OnShopInitializePrefix();
				}
			}

			private static void Postfix()
			{
				if (!((Object)(object)Instance == (Object)null))
				{
					Instance.OnShopInitializePostfix();
				}
			}
		}

		[CompilerGenerated]
		private sealed class <CoApplyFinalMoneyAfterShopStart>d__38 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ShopMoneySetterPlugin <>4__this;

			private int <retryCount>5__2;

			private float <retryInterval>5__3;

			private int <count>5__4;

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

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

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

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

			private bool MoveNext()
			{
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Expected O, but got Unknown
				int num = <>1__state;
				ShopMoneySetterPlugin shopMoneySetterPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_0031;
				case 1:
					<>1__state = -1;
					goto IL_0031;
				case 2:
					<>1__state = -1;
					if (!shopMoneySetterPlugin.PrepareFinalTargetMoney())
					{
						shopMoneySetterPlugin._applyFinalMoneyCoroutine = null;
						return false;
					}
					<retryCount>5__2 = Math.Max(1, CfgFinalApplyRetryCount.Value);
					<retryInterval>5__3 = Mathf.Max(0f, CfgFinalApplyRetryIntervalSeconds.Value);
					<count>5__4 = 0;
					break;
				case 3:
					<>1__state = -1;
					goto IL_0160;
				case 4:
					{
						<>1__state = -1;
						goto IL_0160;
					}
					IL_0160:
					<count>5__4++;
					break;
					IL_0031:
					if (!CanRun())
					{
						shopMoneySetterPlugin._applyFinalMoneyCoroutine = null;
						return false;
					}
					if (!IsInShopSafe())
					{
						shopMoneySetterPlugin._applyFinalMoneyCoroutine = null;
						return false;
					}
					if (!IsShopMainStartedSafe())
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				if (<count>5__4 < <retryCount>5__2)
				{
					if (!CanRun())
					{
						shopMoneySetterPlugin._applyFinalMoneyCoroutine = null;
						return false;
					}
					if (!IsInShopSafe())
					{
						shopMoneySetterPlugin._applyFinalMoneyCoroutine = null;
						return false;
					}
					shopMoneySetterPlugin.ApplyFinalTargetMoney(<count>5__4 + 1, <retryCount>5__2);
					if (<count>5__4 < <retryCount>5__2 - 1 && <retryInterval>5__3 > 0f)
					{
						<>2__current = (object)new WaitForSeconds(<retryInterval>5__3);
						<>1__state = 3;
						return true;
					}
					<>2__current = null;
					<>1__state = 4;
					return true;
				}
				shopMoneySetterPlugin._finalMoneyAppliedThisShop = true;
				shopMoneySetterPlugin._applyFinalMoneyCoroutine = null;
				shopMoneySetterPlugin.WriteInfo("Final shop money applied: " + shopMoneySetterPlugin._finalTargetMoneyK + "k$");
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGuid = "REPOJP.ShopMoneySetter";

		public const string PluginName = "ShopMoneySetter";

		public const string PluginVersion = "4.0.0";

		internal static ShopMoneySetterPlugin Instance;

		private Harmony _harmony;

		private static ConfigEntry<bool> CfgEnableMod;

		private static ConfigEntry<bool> CfgShowDebugLog;

		private static ConfigEntry<int> CfgTemporaryShopPopulateMoneyK;

		private static ConfigEntry<int> CfgMinMoneyK;

		private static ConfigEntry<int> CfgMaxMoneyK;

		private static ConfigEntry<bool> CfgEnableAddToEarnedMoneyMode;

		private static ConfigEntry<int> CfgAddMoneyMinK;

		private static ConfigEntry<int> CfgAddMoneyMaxK;

		private static ConfigEntry<int> CfgFinalApplyRetryCount;

		private static ConfigEntry<float> CfgFinalApplyRetryIntervalSeconds;

		private bool _temporaryMoneyAppliedThisShop;

		private bool _finalMoneyAppliedThisShop;

		private bool _originalMoneyCapturedThisShop;

		private int _originalMoneyBeforeTemporaryK;

		private int _finalTargetMoneyK;

		private bool _finalTargetMoneyPrepared;

		private Coroutine _applyFinalMoneyCoroutine;

		private void Awake()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			try
			{
				((Component)this).transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				Instance = this;
				BindConfig();
				_harmony = new Harmony("REPOJP.ShopMoneySetter");
				_harmony.PatchAll();
				WriteInfo("ShopMoneySetter loaded. Version: 4.0.0");
			}
			catch (Exception ex)
			{
				WriteError("Failure: Awake\n" + ex);
				throw;
			}
		}

		private void OnDestroy()
		{
			try
			{
				StopApplyFinalMoneyCoroutine();
				if (_harmony != null)
				{
					_harmony.UnpatchSelf();
					_harmony = null;
				}
			}
			catch
			{
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void BindConfig()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			CfgEnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "EnableMod", true, "Enable or disable this mod.このMODの有効無効");
			CfgShowDebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "ShowDebugLog", false, "Show detailed debug logs.詳細デバッグログ表示");
			CfgTemporaryShopPopulateMoneyK = ((BaseUnityPlugin)this).Config.Bind<int>("B Shop Populate", "TemporaryShopPopulateMoneyK", 100, new ConfigDescription("Temporary money in k$ used only before shop item population.ショップ品揃え生成前だけ使用する一時所持金(k$)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>()));
			CfgMinMoneyK = ((BaseUnityPlugin)this).Config.Bind<int>("C Direct Set Mode", "MinMoneyK", 0, new ConfigDescription("Minimum final money in k$ when add mode is disabled.加算モード無効時の最終所持金最小値(k$)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>()));
			CfgMaxMoneyK = ((BaseUnityPlugin)this).Config.Bind<int>("C Direct Set Mode", "MaxMoneyK", 30, new ConfigDescription("Maximum final money in k$ when add mode is disabled.加算モード無効時の最終所持金最大値(k$)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>()));
			CfgEnableAddToEarnedMoneyMode = ((BaseUnityPlugin)this).Config.Bind<bool>("D Add Bonus Mode", "EnableAddToEarnedMoneyMode", false, "Add bonus money to earned money instead of setting final money directly.最終所持金を直接設定せず稼いだ貯金へボーナス加算");
			CfgAddMoneyMinK = ((BaseUnityPlugin)this).Config.Bind<int>("D Add Bonus Mode", "AddMoneyMinK", 0, new ConfigDescription("Minimum bonus money in k$ when add mode is enabled.加算モード有効時のボーナス最小値(k$)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>()));
			CfgAddMoneyMaxK = ((BaseUnityPlugin)this).Config.Bind<int>("D Add Bonus Mode", "AddMoneyMaxK", 30, new ConfigDescription("Maximum bonus money in k$ when add mode is enabled.加算モード有効時のボーナス最大値(k$)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>()));
			CfgFinalApplyRetryCount = ((BaseUnityPlugin)this).Config.Bind<int>("E Sync", "FinalApplyRetryCount", 3, new ConfigDescription("Number of times to reapply final money after shop starts.ショップ開始後に最終所持金を再適用する回数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			CfgFinalApplyRetryIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("E Sync", "FinalApplyRetryIntervalSeconds", 0.5f, new ConfigDescription("Interval in seconds between final money reapply attempts.最終所持金再適用の間隔秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
		}

		private void OnShopInitializePrefix()
		{
			if (!CanRun() || !IsInShopSafe())
			{
				return;
			}
			try
			{
				ResetShopApplyState();
				CaptureOriginalMoneyBeforeTemporaryApply();
				ApplyTemporaryMoneyForShopPopulate();
			}
			catch (Exception ex)
			{
				WriteError("Failure: OnShopInitializePrefix\n" + ex);
			}
		}

		private void OnShopInitializePostfix()
		{
			if (!CanRun() || !IsInShopSafe())
			{
				return;
			}
			try
			{
				StartApplyFinalMoneyAfterShopStart();
			}
			catch (Exception ex)
			{
				WriteError("Failure: OnShopInitializePostfix\n" + ex);
			}
		}

		private void ResetShopApplyState()
		{
			StopApplyFinalMoneyCoroutine();
			_temporaryMoneyAppliedThisShop = false;
			_finalMoneyAppliedThisShop = false;
			_originalMoneyCapturedThisShop = false;
			_originalMoneyBeforeTemporaryK = 0;
			_finalTargetMoneyK = 0;
			_finalTargetMoneyPrepared = false;
			WriteDebug("Shop apply state reset.");
		}

		private void StopApplyFinalMoneyCoroutine()
		{
			if (_applyFinalMoneyCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_applyFinalMoneyCoroutine);
				_applyFinalMoneyCoroutine = null;
			}
		}

		private static bool CanRun()
		{
			if (CfgEnableMod == null || !CfgEnableMod.Value)
			{
				return false;
			}
			if ((Object)(object)Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameManager.instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)StatsManager.instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)PunManager.instance == (Object)null)
			{
				return false;
			}
			return IsMasterClientOrSingleplayerSafe();
		}

		private static bool IsMasterClientOrSingleplayerSafe()
		{
			try
			{
				return SemiFunc.IsMasterClientOrSingleplayer();
			}
			catch
			{
				return false;
			}
		}

		private static bool IsInShopSafe()
		{
			try
			{
				if ((Object)(object)RunManager.instance == (Object)null)
				{
					return false;
				}
				object runManagerFieldValue = GetRunManagerFieldValue("levelCurrent");
				if (runManagerFieldValue == null)
				{
					return false;
				}
				object runManagerFieldValue2 = GetRunManagerFieldValue("levelIsShop");
				if (runManagerFieldValue2 is bool && (bool)runManagerFieldValue2)
				{
					return true;
				}
				object runManagerFieldValue3 = GetRunManagerFieldValue("levelShop");
				if (runManagerFieldValue3 == null)
				{
					return false;
				}
				if (runManagerFieldValue3 is IEnumerable enumerable && !(runManagerFieldValue3 is string))
				{
					foreach (object item in enumerable)
					{
						if (runManagerFieldValue == item)
						{
							return true;
						}
					}
					return false;
				}
				return runManagerFieldValue == runManagerFieldValue3;
			}
			catch
			{
				return false;
			}
		}

		private static object GetRunManagerFieldValue(string fieldName)
		{
			try
			{
				if ((Object)(object)RunManager.instance == (Object)null)
				{
					return null;
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(RunManager), fieldName);
				if (fieldInfo == null)
				{
					return null;
				}
				return fieldInfo.GetValue(RunManager.instance);
			}
			catch
			{
				return null;
			}
		}

		private static bool IsShopMainStartedSafe()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			try
			{
				if (!IsInShopSafe())
				{
					return false;
				}
				if ((Object)(object)GameDirector.instance == (Object)null)
				{
					return false;
				}
				return (int)GameDirector.instance.currentState == 2;
			}
			catch
			{
				return false;
			}
		}

		private static int GetCurrentRunCurrencyK()
		{
			if ((Object)(object)StatsManager.instance == (Object)null)
			{
				return 0;
			}
			return StatsManager.instance.GetRunStatCurrency();
		}

		private void CaptureOriginalMoneyBeforeTemporaryApply()
		{
			if (!_originalMoneyCapturedThisShop)
			{
				_originalMoneyBeforeTemporaryK = GetCurrentRunCurrencyK();
				_originalMoneyCapturedThisShop = true;
				WriteInfo("Original shop money captured: " + _originalMoneyBeforeTemporaryK + "k$");
			}
		}

		private void ApplyTemporaryMoneyForShopPopulate()
		{
			if (!_temporaryMoneyAppliedThisShop)
			{
				int num = Math.Max(0, CfgTemporaryShopPopulateMoneyK.Value);
				SemiFunc.StatSetRunCurrency(num);
				_temporaryMoneyAppliedThisShop = true;
				WriteInfo("Temporary shop populate money applied: " + num + "k$");
			}
		}

		private void StartApplyFinalMoneyAfterShopStart()
		{
			if (!_finalMoneyAppliedThisShop)
			{
				StopApplyFinalMoneyCoroutine();
				_applyFinalMoneyCoroutine = ((MonoBehaviour)this).StartCoroutine(CoApplyFinalMoneyAfterShopStart());
			}
		}

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

		private bool PrepareFinalTargetMoney()
		{
			try
			{
				if (_finalTargetMoneyPrepared)
				{
					return true;
				}
				if (CfgEnableAddToEarnedMoneyMode.Value)
				{
					int num = (_originalMoneyCapturedThisShop ? _originalMoneyBeforeTemporaryK : GetCurrentRunCurrencyK());
					int randomValueInRange = GetRandomValueInRange(CfgAddMoneyMinK.Value, CfgAddMoneyMaxK.Value);
					long num2 = (long)num + (long)randomValueInRange;
					if (num2 > int.MaxValue)
					{
						num2 = 2147483647L;
					}
					_finalTargetMoneyK = (int)num2;
					_finalTargetMoneyPrepared = true;
					WriteInfo("Add bonus mode enabled. Base: " + num + "k$, Bonus: " + randomValueInRange + "k$, Final: " + _finalTargetMoneyK + "k$");
					return true;
				}
				_finalTargetMoneyK = GetRandomValueInRange(CfgMinMoneyK.Value, CfgMaxMoneyK.Value);
				_finalTargetMoneyPrepared = true;
				WriteInfo("Direct set mode enabled. Final: " + _finalTargetMoneyK + "k$");
				return true;
			}
			catch (Exception ex)
			{
				WriteError("Failure: PrepareFinalTargetMoney\n" + ex);
				return false;
			}
		}

		private void ApplyFinalTargetMoney(int count, int totalCount)
		{
			try
			{
				SemiFunc.StatSetRunCurrency(_finalTargetMoneyK);
				WriteDebug("Final shop money apply retry [" + count + "/" + totalCount + "]: " + _finalTargetMoneyK + "k$");
			}
			catch (Exception ex)
			{
				WriteError("Failure: ApplyFinalTargetMoney\n" + ex);
			}
		}

		private static int GetRandomValueInRange(int minValue, int maxValue)
		{
			if (minValue < 0)
			{
				minValue = 0;
			}
			if (maxValue < 0)
			{
				maxValue = 0;
			}
			if (minValue > maxValue)
			{
				int num = minValue;
				minValue = maxValue;
				maxValue = num;
			}
			if (minValue == maxValue)
			{
				return minValue;
			}
			if (maxValue == int.MaxValue)
			{
				double num2 = Random.value;
				double num3 = (double)maxValue - (double)minValue + 1.0;
				double val = Math.Floor(num2 * num3);
				return minValue + (int)Math.Min(val, int.MaxValue - minValue);
			}
			return Random.Range(minValue, maxValue + 1);
		}

		private void WriteInfo(string message)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)message);
		}

		private void WriteDebug(string message)
		{
			if (CfgShowDebugLog != null && CfgShowDebugLog.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)message);
			}
		}

		private void WriteError(string message)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)message);
		}
	}
}