Decompiled source of JustRetryPlus v1.0.4

RetryMod.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.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RetryMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RetryMod")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("045c5e0e-dbf3-4310-912d-eb59e0fca719")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("cody.retryfix", "Retry Fix", "1.0.0")]
public class RetryFix : BaseUnityPlugin
{
	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	public class ChangeLevelPatch
	{
		private static bool Prefix(bool __0, bool __1)
		{
			if (!__1)
			{
				return true;
			}
			Log.LogInfo((object)"Retry triggered");
			isRestarting = true;
			RunManager.instance.RestartScene();
			return false;
		}
	}

	[HarmonyPatch(typeof(RoundDirector), "StartRoundLogic")]
	public class RoundStartPatch
	{
		private static void Postfix(RoundDirector __instance)
		{
			if (isRestarting)
			{
				((MonoBehaviour)__instance).StartCoroutine(HandleRestart());
				isRestarting = false;
			}
		}
	}

	[HarmonyPatch(typeof(RoundDirector), "StartRoundLogic")]
	public class SaveStatePatch
	{
		private static void Prefix(RoundDirector __instance)
		{
			if (isRestarting)
			{
				Log.LogInfo((object)"Skipping save (retry in progress)");
			}
			else
			{
				((MonoBehaviour)__instance).StartCoroutine(SaveStateDelayed());
			}
		}
	}

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

		private object <>2__current;

		private List<PlayerAvatar>.Enumerator <>s__1;

		private PlayerAvatar <p>5__2;

		private PlayerHealth <health>5__3;

		private Type <healthType>5__4;

		private FieldInfo <healthField>5__5;

		private int <max>5__6;

		private int <target>5__7;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>s__1 = default(List<PlayerAvatar>.Enumerator);
			<p>5__2 = null;
			<health>5__3 = null;
			<healthType>5__4 = null;
			<healthField>5__5 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(2f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<>s__1 = SemiFunc.PlayerGetAll().GetEnumerator();
				try
				{
					while (<>s__1.MoveNext())
					{
						<p>5__2 = <>s__1.Current;
						<health>5__3 = <p>5__2.playerHealth;
						if (savedHealth > 0)
						{
							<healthType>5__4 = ((object)<health>5__3).GetType();
							<healthField>5__5 = AccessTools.Field(<healthType>5__4, "health");
							<max>5__6 = GetMaxHealth(<health>5__3);
							<target>5__7 = Mathf.Clamp(savedHealth, 1, <max>5__6);
							<healthField>5__5?.SetValue(<health>5__3, <target>5__7);
							RestoreItemCharges();
							Log.LogInfo((object)$"Restored health to {<target>5__7}");
							<healthType>5__4 = null;
							<healthField>5__5 = null;
						}
						SetMoney(savedMoney);
						Log.LogInfo((object)$"Restored money to {savedMoney}");
						ResetEnergyPool();
						<health>5__3 = null;
						<p>5__2 = null;
					}
				}
				finally
				{
					((IDisposable)<>s__1).Dispose();
				}
				<>s__1 = default(List<PlayerAvatar>.Enumerator);
				Log.LogInfo((object)"Player state restored after retry");
				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();
		}
	}

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

		private object <>2__current;

		private List<PlayerAvatar> <players>5__1;

		private PlayerAvatar <firstPlayer>5__2;

		private PlayerHealth <health>5__3;

		private ChargingStation <station>5__4;

		private FieldInfo <field>5__5;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<players>5__1 = null;
			<firstPlayer>5__2 = null;
			<health>5__3 = null;
			<station>5__4 = null;
			<field>5__5 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(1.5f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<players>5__1 = SemiFunc.PlayerGetAll();
				if (<players>5__1 == null || <players>5__1.Count == 0)
				{
					return false;
				}
				<firstPlayer>5__2 = <players>5__1[0];
				<health>5__3 = <firstPlayer>5__2.playerHealth;
				<station>5__4 = ChargingStation.instance;
				if ((Object)(object)<station>5__4 != (Object)null)
				{
					<field>5__5 = AccessTools.Field(typeof(ChargingStation), "chargeTotal");
					originalChargeTotal = (int)<field>5__5.GetValue(<station>5__4);
					Log.LogInfo((object)("Saved energy (delayed): " + originalChargeTotal));
					<field>5__5 = null;
				}
				savedHealth = GetCurrentHealth(<health>5__3);
				savedMoney = GetMoney();
				SaveItemCharges();
				Log.LogInfo((object)("Saved health (delayed): " + savedHealth));
				Log.LogInfo((object)("Saved money (delayed): " + savedMoney));
				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 static ManualLogSource Log;

	private static bool isRestarting = false;

	private static int originalChargeTotal = -1;

	private static int savedHealth = -1;

	private static Dictionary<string, float> savedItemCharges = new Dictionary<string, float>();

	private static int savedMoney = 0;

	private void Awake()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Log.LogInfo((object)"RetryFix loaded!");
		Harmony val = new Harmony("cody.retryfix");
		val.PatchAll();
	}

	[IteratorStateMachine(typeof(<SaveStateDelayed>d__7))]
	private static IEnumerator SaveStateDelayed()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <SaveStateDelayed>d__7(0);
	}

	private static void SaveItemCharges()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		savedItemCharges.Clear();
		ItemBattery[] array = Object.FindObjectsOfType<ItemBattery>();
		ItemBattery[] array2 = array;
		foreach (ItemBattery val in array2)
		{
			Type type = ((object)val).GetType();
			FieldInfo fieldInfo = AccessTools.Field(type, "batteryLife");
			if (fieldInfo != null)
			{
				float num = (float)fieldInfo.GetValue(val);
				string name = ((Object)((Component)val).gameObject).name;
				Vector3 position = ((Component)val).transform.position;
				string text = name + "_" + ((object)(Vector3)(ref position)).ToString();
				savedItemCharges[text] = num;
				Log.LogInfo((object)$"Saved item {text} = {num}");
			}
		}
	}

	private static void ResetEnergyPool()
	{
		if (!((Object)(object)StatsManager.instance == (Object)null) && originalChargeTotal != -1)
		{
			Log.LogInfo((object)"Restoring ORIGINAL charging station state...");
			StatsManager.instance.runStats["chargingStationChargeTotal"] = originalChargeTotal;
			ChargingStation instance = ChargingStation.instance;
			if ((Object)(object)instance != (Object)null)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(ChargingStation), "chargeTotal");
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(ChargingStation), "chargeFloat");
				FieldInfo fieldInfo3 = AccessTools.Field(typeof(ChargingStation), "chargeSegmentCurrent");
				fieldInfo?.SetValue(instance, originalChargeTotal);
				fieldInfo2?.SetValue(instance, (float)originalChargeTotal / 100f);
				fieldInfo3?.SetValue(instance, Mathf.RoundToInt((float)originalChargeTotal / 100f * 40f));
			}
			Log.LogInfo((object)("Charging station restored to ORIGINAL startup value: " + originalChargeTotal));
		}
	}

	private static int GetMoney()
	{
		if (StatsManager.instance.runStats.ContainsKey("currency"))
		{
			return StatsManager.instance.runStats["currency"];
		}
		return 0;
	}

	private static int GetCurrentHealth(object playerHealth)
	{
		FieldInfo fieldInfo = AccessTools.Field(playerHealth.GetType(), "health");
		return (int)fieldInfo.GetValue(playerHealth);
	}

	private static int GetMaxHealth(object playerHealth)
	{
		FieldInfo fieldInfo = AccessTools.Field(playerHealth.GetType(), "maxHealth");
		return (int)fieldInfo.GetValue(playerHealth);
	}

	private static void SetMoney(int value)
	{
		if (StatsManager.instance.runStats.ContainsKey("currency"))
		{
			StatsManager.instance.runStats["currency"] = value;
		}
	}

	private static void RestoreItemCharges()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		ItemBattery[] array = Object.FindObjectsOfType<ItemBattery>();
		ItemBattery[] array2 = array;
		foreach (ItemBattery val in array2)
		{
			Type type = ((object)val).GetType();
			FieldInfo fieldInfo = AccessTools.Field(type, "batteryLife");
			string name = ((Object)((Component)val).gameObject).name;
			Vector3 position = ((Component)val).transform.position;
			string text = name + "_" + ((object)(Vector3)(ref position)).ToString();
			if (fieldInfo != null && savedItemCharges.TryGetValue(text, out var value))
			{
				fieldInfo.SetValue(val, value);
				Log.LogInfo((object)$"Restored item {text} = {value}");
			}
			else
			{
				Log.LogInfo((object)("Could not Restored item " + text));
			}
		}
	}

	[IteratorStateMachine(typeof(<HandleRestart>d__17))]
	private static IEnumerator HandleRestart()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <HandleRestart>d__17(0);
	}
}