Decompiled source of CyclesMod v1.0.0

CyclesMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
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: AssemblyCompany("CyclesMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6d3849bf9368e0ec599947f4a65b5a5d90783594")]
[assembly: AssemblyProduct("CyclesMod")]
[assembly: AssemblyTitle("CyclesMod")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/SpaceMonkeyy86/Silksong.CyclesMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace Silksong.CyclesMod
{
	[HarmonyPatch]
	[BepInPlugin("com.spacemonkeyy.cyclesmod", "CyclesMod", "1.0.0")]
	public class CyclesMod : BaseUnityPlugin
	{
		private static CyclesMod instance;

		private ConfigEntry<bool> normalizeCycles;

		private ConfigEntry<float> extraLoadTime;

		private ConfigEntry<bool> forceClearMemory;

		private TimeControlInstance? timeControl;

		public const string Id = "com.spacemonkeyy.cyclesmod";

		public static string Name => "CyclesMod";

		public static string Version => "1.0.0";

		private void Awake()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			instance = this;
			normalizeCycles = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Normalize Cycles", true, "Prevents cycles from starting until after the load has finished.");
			extraLoadTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Extra Load Time", 0f, "Time in seconds to let cycles run before giving player control.");
			forceClearMemory = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Force Clear Memory", false, "Forces an extra load step which typically desyncs cycles.");
			new Harmony("com.spacemonkeyy.cyclesmod").PatchAll();
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static IEnumerable<CodeInstruction> SceneLoad_BeginRoutine(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Expected O, but got Unknown
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Expected O, but got Unknown
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Expected O, but got Unknown
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Expected O, but got Unknown
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Expected O, but got Unknown
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Expected O, but got Unknown
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Expected O, but got Unknown
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Expected O, but got Unknown
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Expected O, but got Unknown
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Expected O, but got Unknown
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Expected O, but got Unknown
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Expected O, but got Unknown
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Expected O, but got Unknown
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Expected O, but got Unknown
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Expected O, but got Unknown
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Expected O, but got Unknown
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Expected O, but got Unknown
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Expected O, but got Unknown
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Expected O, but got Unknown
			//IL_057a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Expected O, but got Unknown
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Expected O, but got Unknown
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Expected O, but got Unknown
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Expected O, but got Unknown
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Expected O, but got Unknown
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0614: Expected O, but got Unknown
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0623: Expected O, but got Unknown
			//IL_062b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Expected O, but got Unknown
			//IL_0640: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Expected O, but got Unknown
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_0656: Expected O, but got Unknown
			//IL_065f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0665: Expected O, but got Unknown
			//IL_066e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Expected O, but got Unknown
			//IL_0682: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, generator);
			Label label = generator.DefineLabel();
			Label label2 = generator.DefineLabel();
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Leave, (object)null, (string)null)
			});
			Label label3 = (Label)val.Operand;
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.operand is FieldInfo fieldInfo3 && fieldInfo3.Name.EndsWith("__state")), (string)null)
			});
			FieldInfo fieldInfo = (FieldInfo)val.Operand;
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.operand is FieldInfo fieldInfo3 && fieldInfo3.Name.EndsWith("__current")), (string)null)
			});
			FieldInfo fieldInfo2 = (FieldInfo)val.Operand;
			val.Start();
			val.MatchEndForward((CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_2, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_4, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)typeof(SceneLoad).GetMethod("RecordEndTime"), (string)null)
			});
			val.Advance(1);
			val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)new Action(FreezeTimeScale).Method)
			});
			val.Start();
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Switch, (object)null, (string)null)
			});
			Label[] array = (Label[])val.Operand;
			int num = array.Length;
			ref object operand = ref val.Operand;
			Label[] array2 = array;
			int num2 = 0;
			Label[] array3 = new Label[1 + array2.Length];
			ReadOnlySpan<Label> readOnlySpan = new ReadOnlySpan<Label>(array2);
			readOnlySpan.CopyTo(new Span<Label>(array3).Slice(num2, readOnlySpan.Length));
			num2 += readOnlySpan.Length;
			array3[num2] = label2;
			operand = array3;
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_M1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)fieldInfo, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_2, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_7, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)typeof(SceneLoad).GetMethod("RecordEndTime"), (string)null)
			});
			Label label4 = val.Instruction.labels[0];
			int num3 = ((ReadOnlySpan<Label>)array).IndexOf(label4);
			val.Insert((CodeInstruction[])(object)new CodeInstruction[11]
			{
				new CodeInstruction(OpCodes.Call, (object)new Func<bool>(NormalizeLoadsEnabled).Method),
				new CodeInstruction(OpCodes.Brfalse, (object)label4),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldnull, (object)null),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo2),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldc_I4, (object)num3),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldc_I4_1, (object)null),
				new CodeInstruction(OpCodes.Stloc_0, (object)null),
				new CodeInstruction(OpCodes.Leave, (object)label3)
			});
			val.Instruction.labels.Add(label2);
			val.MatchStartBackwards((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)fieldInfo, (string)null)
			});
			val.MatchStartBackwards((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)fieldInfo, (string)null)
			});
			val.Advance(-1);
			val.SetInstruction(new CodeInstruction(OpCodes.Ldc_I4, (object)num));
			val.Start();
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Switch, (object)null, (string)null)
			});
			array = (Label[])val.Operand;
			num = array.Length;
			ref object operand2 = ref val.Operand;
			array3 = array;
			num2 = 0;
			array2 = new Label[1 + array3.Length];
			readOnlySpan = new ReadOnlySpan<Label>(array3);
			readOnlySpan.CopyTo(new Span<Label>(array2).Slice(num2, readOnlySpan.Length));
			num2 += readOnlySpan.Length;
			array2[num2] = label;
			operand2 = array2;
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_2, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)typeof(SceneLoad).GetProperty("IsFinished").SetMethod, (string)null)
			});
			val.Instruction.labels.Add(label);
			val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[14]
			{
				new CodeInstruction(OpCodes.Call, (object)new Action(ResetTimeScale).Method),
				new CodeInstruction(OpCodes.Call, (object)new Func<float>(GetLoadDelay).Method),
				new CodeInstruction(OpCodes.Ldc_R4, (object)0f),
				new CodeInstruction(OpCodes.Ble, (object)label),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)new Func<float>(GetLoadDelay).Method),
				new CodeInstruction(OpCodes.Newobj, (object)typeof(WaitForSecondsRealtime).GetConstructor(new Type[1] { typeof(float) })),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo2),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldc_I4, (object)num),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldc_I4_1, (object)null),
				new CodeInstruction(OpCodes.Stloc_0, (object)null),
				new CodeInstruction(OpCodes.Leave, (object)label3)
			});
			return val.InstructionEnumeration();
			static void FreezeTimeScale()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Expected O, but got Unknown
				if (instance.normalizeCycles.Value)
				{
					instance.timeControl = new TimeControlInstance(0f, (Type)0);
				}
			}
			static float GetLoadDelay()
			{
				return instance.extraLoadTime.Value;
			}
			static bool NormalizeLoadsEnabled()
			{
				return instance.normalizeCycles.Value;
			}
			static void ResetTimeScale()
			{
				TimeControlInstance? obj = instance.timeControl;
				if (obj != null)
				{
					obj.Release();
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static bool SceneLoad_IsUnloadAssetsRequired_Get(ref bool __result)
		{
			if (instance.forceClearMemory.Value)
			{
				__result = true;
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SceneLoad), "BeginRoutine")]
		private static IEnumerator SceneLoad_BeginRoutine_Postfix(IEnumerator __result, SceneLoad __instance)
		{
			while (__result.MoveNext())
			{
				yield return __result.Current;
			}
			((BaseUnityPlugin)instance).Logger.LogDebug((object)"");
			string text = "Scene load stats for " + __instance.TargetSceneName;
			((BaseUnityPlugin)instance).Logger.LogDebug((object)text);
			((BaseUnityPlugin)instance).Logger.LogDebug((object)new string('=', text.Length));
			string[] names = Enum.GetNames(typeof(Phases));
			for (int i = 0; i < names.Length; i++)
			{
				PhaseInfo val = __instance.phaseInfos[i];
				if (val.BeginTime.HasValue && val.EndTime.HasValue)
				{
					((BaseUnityPlugin)instance).Logger.LogDebug((object)$"{names[i]}: {val.EndTime - val.BeginTime}");
				}
			}
			((BaseUnityPlugin)instance).Logger.LogDebug((object)$"TOTAL: {Time.realtimeSinceStartup - __instance.BeginTime}");
			((BaseUnityPlugin)instance).Logger.LogDebug((object)"");
		}
	}
}