Decompiled source of CloverPerformance v1.0.0

CloverPerformance.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.CompilerServices;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Panik;
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: AssemblyCompany("CloverPerformance")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CloverPerformance")]
[assembly: AssemblyTitle("CloverPerformance")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace AethaPerformancePatches
{
	[BepInPlugin("Aetha.PerformancePatches", "AethaPerformancePatches", "1.0.0")]
	public class AethaPerformancePatches : BaseUnityPlugin
	{
		public class PerformancePatchConfig
		{
			public bool SkipRerollSaves = true;

			public bool CacheStrings = true;

			public bool CacheBigIntegerMath = true;

			public bool PatchStringsSanitize = true;
		}

		private const string ConfigFilename = "PerformanceConfig.json";

		public static PerformancePatchConfig config = new PerformancePatchConfig();

		private static string AssemblyDirectory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		private static string ConfigPath => AssemblyDirectory + "/PerformanceConfig.json";

		private void Awake()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (Directory.Exists(AssemblyDirectory))
			{
				if (File.Exists(ConfigPath))
				{
					config = JsonUtility.FromJson<PerformancePatchConfig>(File.ReadAllText(ConfigPath));
				}
				else
				{
					File.WriteAllText(ConfigPath, JsonUtility.ToJson((object)config));
				}
			}
			new Harmony("Aetha.PerformancePatches").PatchAll();
		}
	}
	[HarmonyPatch(typeof(Data))]
	internal static class DataPatches
	{
		[CompilerGenerated]
		private sealed class <AsyncTrue>d__2 : IAsyncStateMachine
		{
			public int <>1__state;

			public AsyncUniTaskMethodBuilder<bool> <>t__builder;

			private void MoveNext()
			{
				int num = <>1__state;
				bool result;
				try
				{
					result = true;
				}
				catch (Exception exception)
				{
					<>1__state = -2;
					<>t__builder.SetException(exception);
					return;
				}
				<>1__state = -2;
				<>t__builder.SetResult(result);
			}

			void IAsyncStateMachine.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				this.MoveNext();
			}

			[DebuggerHidden]
			private void SetStateMachine(IAsyncStateMachine stateMachine)
			{
			}

			void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
			{
				//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
				this.SetStateMachine(stateMachine);
			}
		}

		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AethaPerformancePatches.config.SkipRerollSaves;
		}

		[HarmonyPrefix]
		[HarmonyPatch("SaveGame")]
		private static bool SaveGamePrefix(GameSavingReason reasonForSaving, ref UniTask<bool> __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (reasonForSaving - 13 <= 1)
			{
				__result = AsyncTrue();
				return false;
			}
			return true;
		}

		[AsyncStateMachine(typeof(<AsyncTrue>d__2))]
		[DebuggerStepThrough]
		private static UniTask<bool> AsyncTrue()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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)
			<AsyncTrue>d__2 <AsyncTrue>d__ = new <AsyncTrue>d__2();
			<AsyncTrue>d__.<>t__builder = AsyncUniTaskMethodBuilder<bool>.Create();
			<AsyncTrue>d__.<>1__state = -1;
			<AsyncTrue>d__.<>t__builder.Start<<AsyncTrue>d__2>(ref <AsyncTrue>d__);
			return <AsyncTrue>d__.<>t__builder.Task;
		}
	}
	[HarmonyPatch(typeof(Strings))]
	internal static class StringsCachePatches
	{
		private static readonly Dictionary<string, (string value, int frame)> Cache = new Dictionary<string, (string, int)>();

		private static int _latestFrame = -1;

		private static readonly HashSet<string> NeverCacheStrings = new HashSet<string>();

		private static readonly string[] DoNotCache = new string[3] { "[START_PROMPT]", "[INPUTS_MOVE]", "[CHARGE_BAR]" };

		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AethaPerformancePatches.config.CacheStrings;
		}

		public static void MarkDirty()
		{
			_latestFrame = Time.frameCount;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Sanitize")]
		private static bool SanitizePrefix(SantizationKind santizationKind, string input, SanitizationSubKind subKind, ref string __result)
		{
			if (Cache.TryGetValue(input, out (string, int) value) && value.Item2 > _latestFrame)
			{
				__result = Cache[input].value;
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch("Sanitize")]
		private static void SanitizePostfix(SantizationKind santizationKind, string input, SanitizationSubKind subKind, ref string __result)
		{
			if (Cache.TryGetValue(input, out (string, int) value))
			{
				Cache[input] = (__result, Mathf.Max(value.Item2, Time.frameCount));
			}
			else if (!input.Contains("[") && !input.Contains("]"))
			{
				Cache[input] = (__result, int.MaxValue);
			}
			else
			{
				if (NeverCacheStrings.Contains(input))
				{
					return;
				}
				string[] doNotCache = DoNotCache;
				foreach (string value2 in doNotCache)
				{
					if (input.Contains(value2))
					{
						NeverCacheStrings.Add(input);
						return;
					}
				}
				Cache[input] = (__result, Time.frameCount);
			}
		}
	}
	[HarmonyPatch(typeof(GameplayData))]
	internal static class GameplayDataCachePatches
	{
		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AethaPerformancePatches.config.CacheStrings;
		}

		[HarmonyPostfix]
		[HarmonyPatch]
		private static void MarkDirtyPostfix()
		{
			StringsCachePatches.MarkDirty();
		}

		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> CalculateMethods()
		{
			return from x in AccessTools.GetDeclaredMethods(typeof(GameplayData))
				where x.Name.EndsWith("Set")
				select x;
		}
	}
	[HarmonyPatch(typeof(GameplayData))]
	internal static class BigIntegerCachePatches
	{
		private static readonly Dictionary<string, int> CacheTimestamps = new Dictionary<string, int>();

		private static readonly Dictionary<string, object> CachedValues = new Dictionary<string, object>();

		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AethaPerformancePatches.config.CacheBigIntegerMath;
		}

		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> CalculateMethods()
		{
			yield return AccessTools.Method(typeof(GameplayData), "InterestEarnedHypotetically", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "GetHypotehticalMaxSpinsBuyable", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "GetHypotehticalMidSpinsBuyable", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "DebtGetExt", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "SpinCostGet_Single", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "DebtGet", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "SpinCostMid_Get", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "SpinCostMax_Get", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "InterestRateGet", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "DebtIndexGet", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GameplayData), "DeadlineReward_CoinsGet", (Type[])null, (Type[])null);
		}

		[HarmonyPatch]
		[HarmonyPrefix]
		private static bool FrameCachedValue(MethodBase __originalMethod, ref object __result)
		{
			if (TryGetCachedValue(__originalMethod.Name, out object value))
			{
				__result = value;
				return false;
			}
			return true;
		}

		[HarmonyPatch]
		[HarmonyPostfix]
		private static void CacheCurrentResult(MethodBase __originalMethod, ref object __result)
		{
			if (!CacheTimestamps.TryGetValue(__originalMethod.Name, out var value) || Time.frameCount != value)
			{
				CacheTimestamps[__originalMethod.Name] = Time.frameCount;
				CachedValues[__originalMethod.Name] = __result;
			}
		}

		private static bool TryGetCachedValue(string key, out object value)
		{
			if (CacheTimestamps.TryGetValue(key, out var value2))
			{
				if (Time.frameCount != value2)
				{
					value = BigInteger.Zero;
					return false;
				}
				if (CachedValues.TryGetValue(key, out object value3))
				{
					value = value3;
					return true;
				}
			}
			value = BigInteger.Zero;
			return false;
		}
	}
	[HarmonyPatch(typeof(Strings))]
	[HarmonyPatch("Sanitize")]
	internal static class StringsPatches
	{
		private static readonly string[] KeyReplacements = new string[7] { "[DEBT]", "[DEBT_NEXT]", "[DEBT_30%]", "[INTEREST_REV]", "[2X_INTEREST_REV]", "[3X_INTEREST_REV]", "[REWARD_DEBT_AMMOUNT]" };

		[HarmonyPrepare]
		private static bool Prepare()
		{
			return AethaPerformancePatches.config.PatchStringsSanitize;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator)
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			Label label = default(Label);
			int num = -1;
			int num2 = -1;
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldstr && list[i].operand is string && KeyReplacements.Contains((string)list[i].operand))
				{
					num = i - 1;
					num2 = -1;
				}
				if (list[i].opcode == OpCodes.Pop && num >= 0)
				{
					label = ilGenerator.DefineLabel();
					list[i + 1].labels.Add(label);
					num2 = i;
				}
				if (num >= 0 && num2 >= 0)
				{
					CodeInstruction item = list[num];
					list.RemoveAt(num);
					CodeInstruction item2 = list[num];
					list.RemoveAt(num);
					list.Insert(num++, new CodeInstruction(OpCodes.Ldarg_1, (object)null));
					list.Insert(num++, item2);
					list.Insert(num++, CodeInstruction.Call(typeof(string), "Contains", new Type[1] { typeof(string) }, (Type[])null));
					list.Insert(num++, new CodeInstruction(OpCodes.Brfalse_S, (object)label));
					list.Insert(num++, item);
					list.Insert(num++, item2);
					i = num2 + 4;
					num = -1;
					num2 = -1;
				}
			}
			return list.AsEnumerable();
		}
	}
}