Decompiled source of AutoReturnToLobby v4.0.0

AutoReturnToLobby.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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Photon.Pun;
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 REPOJP.AutoReturnToLobby
{
	[BepInPlugin("REPOJP.AutoReturnToLobby", "AutoReturnToLobby", "4.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class AutoReturnToLobbyPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <HardReloadFallbackCoroutine>d__61 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AutoReturnToLobbyPlugin <>4__this;

			private float <delay>5__1;

			private int <repeatCount>5__2;

			private float <interval>5__3;

			private int <count>5__4;

			private bool <success>5__5;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Expected O, but got Unknown
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0135: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<delay>5__1 = Mathf.Max(0f, <>4__this.hardReloadDelaySeconds.Value);
					if (<delay>5__1 > 0f)
					{
						<>2__current = (object)new WaitForSecondsRealtime(<delay>5__1);
						<>1__state = 1;
						return true;
					}
					goto IL_0082;
				case 1:
					<>1__state = -1;
					goto IL_0082;
				case 2:
					{
						<>1__state = -1;
						goto IL_0146;
					}
					IL_0146:
					<count>5__4++;
					goto IL_0159;
					IL_0082:
					<repeatCount>5__2 = Mathf.Clamp(<>4__this.hardReloadRepeatCount.Value, 1, 10);
					<interval>5__3 = Mathf.Clamp(<>4__this.hardReloadRepeatIntervalSeconds.Value, 0.1f, 10f);
					<count>5__4 = 1;
					goto IL_0159;
					IL_0159:
					if (<count>5__4 <= <repeatCount>5__2)
					{
						<success>5__5 = <>4__this.TryForceReloadToLobbyMenu(<count>5__4);
						if (!<success>5__5)
						{
							<>4__this.transitionLocked = false;
							<>4__this.hardReloadCoroutine = null;
							return false;
						}
						if (<count>5__4 < <repeatCount>5__2)
						{
							<>2__current = (object)new WaitForSecondsRealtime(<interval>5__3);
							<>1__state = 2;
							return true;
						}
						goto IL_0146;
					}
					<>4__this.hardReloadCoroutine = null;
					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.AutoReturnToLobby";

		public const string PluginName = "AutoReturnToLobby";

		public const string PluginVersion = "4.0.0";

		private const string ReturnToLobbyPluginGuid = "OrigamiCoder.ReturnToLobby";

		private const string ReturnToLobbyClickMethodName = "ReturnLobbyClick";

		private static ManualLogSource Log;

		private ConfigEntry<bool> enableMod;

		private ConfigEntry<KeyCode> holdKey;

		private ConfigEntry<float> displayDelaySeconds;

		private ConfigEntry<float> requiredProgressSeconds;

		private ConfigEntry<float> cooldownSeconds;

		private ConfigEntry<bool> enableHardReloadFallback;

		private ConfigEntry<float> hardReloadDelaySeconds;

		private ConfigEntry<int> hardReloadRepeatCount;

		private ConfigEntry<float> hardReloadRepeatIntervalSeconds;

		private ConfigEntry<float> transitionLockSeconds;

		private ConfigEntry<bool> destroyNetworkObjectsBeforeReload;

		private ConfigEntry<bool> enableAutoLoadingStuckReturn;

		private ConfigEntry<float> autoReturnDelayAfterStuckUiSeconds;

		private ConfigEntry<bool> showAutoReturnCountdown;

		private ConfigEntry<bool> logAutoReturn;

		private ConfigEntry<bool> showProgressBar;

		private ConfigEntry<float> progressBarWidth;

		private ConfigEntry<float> progressBarHeight;

		private ConfigEntry<float> progressBarVerticalPosition;

		private ConfigEntry<int> titleFontSize;

		private ConfigEntry<int> percentFontSize;

		private ConfigEntry<bool> logExecution;

		private ConfigEntry<bool> logFailure;

		private ConfigEntry<bool> logFallback;

		private BaseUnityPlugin returnToLobbyPluginInstance;

		private MethodInfo returnToLobbyClickMethod;

		private Coroutine hardReloadCoroutine;

		private bool isHolding;

		private bool hasExecutedThisHold;

		private bool shouldDrawProgress;

		private bool transitionLocked;

		private float holdStartTime;

		private float currentProgress;

		private float nextAllowedTime;

		private float transitionLockEndTime;

		private float lastFailureLogTime;

		private bool autoCountdownActive;

		private bool autoExecutedThisStuck;

		private bool shouldDrawAutoCountdown;

		private float autoCountdownStartTime;

		private float autoCountdownProgress;

		private FieldInfo loadingUiStuckActiveField;

		private GUIStyle titleStyle;

		private GUIStyle percentStyle;

		private GUIStyle hintStyle;

		private GUIStyle boxStyle;

		private Texture2D whiteTexture;

		private void Awake()
		{
			try
			{
				((Component)this).transform.parent = null;
				((Object)this).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				Log = ((BaseUnityPlugin)this).Logger;
				BindConfig();
				TryCacheReturnToLobbyMethod(logOnSuccess: true);
				Log.LogInfo((object)"REPOJP.AutoReturnToLobby v4.0.0 loaded");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex));
			}
		}

		private void BindConfig()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Expected O, but got Unknown
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Expected O, but got Unknown
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Expected O, but got Unknown
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Expected O, but got Unknown
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Expected O, but got Unknown
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Expected O, but got Unknown
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Expected O, but got Unknown
			enableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enables this mod.このMODを有効化します");
			holdKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "HoldKey", (KeyCode)278, "Key to hold before the progress UI starts.HOME長押し開始キー");
			displayDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DisplayDelaySeconds", 2f, new ConfigDescription("Seconds before showing the progress bar.プログレスバー表示までの秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
			requiredProgressSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RequiredProgressSeconds", 5f, new ConfigDescription("Seconds required after the progress UI appears.プログレスバー表示後に実行まで必要な秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 60f), Array.Empty<object>()));
			cooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CooldownSeconds", 3f, new ConfigDescription("Cooldown seconds after execution.実行後のクールダウン秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			transitionLockSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TransitionLockSeconds", 20f, new ConfigDescription("Seconds to block repeated execution after one trigger.一度実行した後に再実行を防ぐ秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
			enableHardReloadFallback = ((BaseUnityPlugin)this).Config.Bind<bool>("Recovery", "EnableHardReloadFallback", true, "Forces Reload scene after ReturnToLobby yes action.詰まり対策としてYes処理後にReloadシーンを強制します");
			hardReloadDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "HardReloadDelaySeconds", 0.25f, new ConfigDescription("Seconds to wait before hard reload fallback.Yes処理後に強制Reloadするまでの秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			hardReloadRepeatCount = ((BaseUnityPlugin)this).Config.Bind<int>("Recovery", "HardReloadRepeatCount", 2, new ConfigDescription("Hard reload retry count.強制Reloadの試行回数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			hardReloadRepeatIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "HardReloadRepeatIntervalSeconds", 1.25f, new ConfigDescription("Seconds between hard reload retries.強制Reload再試行の間隔秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			destroyNetworkObjectsBeforeReload = ((BaseUnityPlugin)this).Config.Bind<bool>("Recovery", "DestroyNetworkObjectsBeforeReload", true, "Destroys Photon network objects before forced lobby-menu reload.強制ロビーメニュー復帰前にPhotonネットワークオブジェクトを削除します");
			enableAutoLoadingStuckReturn = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLoadingStuckReturn", "Enabled", true, "Automatically runs the same forced ReturnToLobby sequence after the vanilla loading-stuck UI appears.REPO標準のロードスタックUI表示後に同じ強制ReturnToLobby処理を自動実行します");
			autoReturnDelayAfterStuckUiSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("AutoLoadingStuckReturn", "DelayAfterStuckUISeconds", 5f, new ConfigDescription("Seconds to wait after the vanilla loading-stuck UI appears before executing.標準ロードスタックUI表示後に実行まで待つ秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
			showAutoReturnCountdown = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLoadingStuckReturn", "ShowCountdown", true, "Shows an additional countdown while auto ReturnToLobby is waiting.自動ReturnToLobby待機中に追加カウントダウンを表示します");
			logAutoReturn = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLoadingStuckReturn", "LogAutoReturn", true, "Writes logs when auto loading-stuck return starts and executes.ロードスタック自動復帰の開始時と実行時にログを出力します");
			showProgressBar = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowProgressBar", true, "Shows the progress bar after the display delay.表示待機後にプログレスバーを表示します");
			progressBarWidth = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ProgressBarWidth", 520f, new ConfigDescription("Width of the progress bar.プログレスバーの横幅", (AcceptableValueBase)(object)new AcceptableValueRange<float>(120f, 2000f), Array.Empty<object>()));
			progressBarHeight = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ProgressBarHeight", 28f, new ConfigDescription("Height of the progress bar.プログレスバーの高さ", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 120f), Array.Empty<object>()));
			progressBarVerticalPosition = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ProgressBarVerticalPosition", 0.72f, new ConfigDescription("Normalized vertical position from top to bottom.上から下への正規化Y位置", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			titleFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "TitleFontSize", 22, new ConfigDescription("Title font size.タイトル文字サイズ", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 64), Array.Empty<object>()));
			percentFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PercentFontSize", 18, new ConfigDescription("Percent font size.進捗文字サイズ", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 64), Array.Empty<object>()));
			logExecution = ((BaseUnityPlugin)this).Config.Bind<bool>("Log", "LogExecution", true, "Writes a log when the lobby return is executed.ロビー戻り実行時にログを出力します");
			logFailure = ((BaseUnityPlugin)this).Config.Bind<bool>("Log", "LogFailure", true, "Writes throttled failure logs.抑制付き失敗ログを出力します");
			logFallback = ((BaseUnityPlugin)this).Config.Bind<bool>("Log", "LogFallback", true, "Writes a log when hard reload fallback runs.強制Reload実行時にログを出力します");
		}

		private void Update()
		{
			try
			{
				if (!enableMod.Value)
				{
					ResetHoldState();
					ResetAutoReturnState();
				}
				else
				{
					UpdateTransitionLock();
					HandleAutoLoadingStuckReturn();
					HandleManualHoldReturn();
				}
			}
			catch (Exception ex)
			{
				shouldDrawProgress = false;
				shouldDrawAutoCountdown = false;
				WriteFailureLog("Failure: Update\n" + ex);
			}
		}

		private void HandleManualHoldReturn()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetKey(holdKey.Value))
			{
				ResetHoldState();
				return;
			}
			if (transitionLocked)
			{
				shouldDrawProgress = false;
				return;
			}
			if (!isHolding)
			{
				isHolding = true;
				hasExecutedThisHold = false;
				shouldDrawProgress = false;
				currentProgress = 0f;
				holdStartTime = Time.realtimeSinceStartup;
			}
			if (hasExecutedThisHold)
			{
				shouldDrawProgress = false;
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (realtimeSinceStartup < nextAllowedTime)
			{
				shouldDrawProgress = false;
				return;
			}
			float num = holdStartTime + Mathf.Max(0f, displayDelaySeconds.Value);
			if (realtimeSinceStartup < num)
			{
				shouldDrawProgress = false;
				currentProgress = 0f;
				return;
			}
			float num2 = Mathf.Max(0.1f, requiredProgressSeconds.Value);
			currentProgress = Mathf.Clamp01((realtimeSinceStartup - num) / num2);
			shouldDrawProgress = showProgressBar.Value;
			if (currentProgress >= 1f)
			{
				hasExecutedThisHold = true;
				shouldDrawProgress = false;
				nextAllowedTime = realtimeSinceStartup + Mathf.Max(0f, cooldownSeconds.Value);
				transitionLocked = true;
				transitionLockEndTime = realtimeSinceStartup + Mathf.Max(0f, transitionLockSeconds.Value);
				KeyCode value = holdKey.Value;
				ExecuteReturnToLobbySequence("by holding " + ((object)(KeyCode)(ref value)).ToString());
			}
		}

		private void HandleAutoLoadingStuckReturn()
		{
			if (!enableAutoLoadingStuckReturn.Value)
			{
				ResetAutoReturnState();
				return;
			}
			if (transitionLocked)
			{
				shouldDrawAutoCountdown = false;
				return;
			}
			if (!TryGetLoadingStuckActive())
			{
				ResetAutoReturnState();
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!autoCountdownActive)
			{
				autoCountdownActive = true;
				autoExecutedThisStuck = false;
				autoCountdownStartTime = realtimeSinceStartup;
				autoCountdownProgress = 0f;
				if (logAutoReturn.Value)
				{
					Log.LogInfo((object)"Loading stuck UI detected. Auto ReturnToLobby countdown started");
				}
			}
			if (autoExecutedThisStuck)
			{
				shouldDrawAutoCountdown = false;
				return;
			}
			float num = Mathf.Max(0f, autoReturnDelayAfterStuckUiSeconds.Value);
			if (num <= 0f)
			{
				autoCountdownProgress = 1f;
			}
			else
			{
				autoCountdownProgress = Mathf.Clamp01((realtimeSinceStartup - autoCountdownStartTime) / num);
			}
			shouldDrawAutoCountdown = showAutoReturnCountdown.Value;
			if (autoCountdownProgress >= 1f)
			{
				autoExecutedThisStuck = true;
				shouldDrawAutoCountdown = false;
				nextAllowedTime = realtimeSinceStartup + Mathf.Max(0f, cooldownSeconds.Value);
				transitionLocked = true;
				transitionLockEndTime = realtimeSinceStartup + Mathf.Max(0f, transitionLockSeconds.Value);
				if (logAutoReturn.Value)
				{
					Log.LogInfo((object)"Loading stuck auto ReturnToLobby threshold reached");
				}
				ExecuteReturnToLobbySequence("after loading stuck UI was active for " + num.ToString("0.###") + " seconds");
			}
		}

		private void OnGUI()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				bool flag = shouldDrawProgress && showProgressBar.Value;
				bool flag2 = shouldDrawAutoCountdown && showAutoReturnCountdown.Value;
				if (flag || flag2)
				{
					EnsureGuiResources();
					GUI.depth = int.MinValue;
					if (flag)
					{
						KeyCode value = holdKey.Value;
						DrawProgressPanel("RETURNING TO LOBBY", "Keep holding " + ((object)(KeyCode)(ref value)).ToString(), currentProgress, Mathf.Clamp01(progressBarVerticalPosition.Value));
					}
					if (flag2)
					{
						DrawProgressPanel("LOADING STUCK AUTO RETURN", "Auto ReturnToLobby is armed", autoCountdownProgress, Mathf.Clamp01(progressBarVerticalPosition.Value - 0.14f));
					}
				}
			}
			catch (Exception ex)
			{
				shouldDrawProgress = false;
				shouldDrawAutoCountdown = false;
				WriteFailureLog("Failure: OnGUI\n" + ex);
			}
		}

		private void DrawProgressPanel(string title, string hint, float progress, float normalizedY)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(progressBarWidth.Value, 120f, 2000f);
			float num2 = Mathf.Clamp(progressBarHeight.Value, 8f, 120f);
			float num3 = ((float)Screen.width - num) * 0.5f;
			float num4 = normalizedY * (float)Screen.height;
			float num5 = 16f;
			float num6 = num2 + 88f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(num3 - num5, num4 - 44f, num + num5 * 2f, num6);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(num3 - num5, num4 - 38f, num + num5 * 2f, 28f);
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(num3, num4, num, num2);
			Rect rect = default(Rect);
			((Rect)(ref rect))..ctor(num3, num4, num * Mathf.Clamp01(progress), num2);
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(num3 - num5, num4 + num2 + 8f, num + num5 * 2f, 24f);
			Rect val5 = default(Rect);
			((Rect)(ref val5))..ctor(num3 - num5, num4 + num2 + 34f, num + num5 * 2f, 22f);
			DrawRect(val, new Color(0f, 0f, 0f, 0.72f));
			GUI.Box(val, GUIContent.none, boxStyle);
			GUI.Label(val2, title, titleStyle);
			DrawRect(val3, new Color(0.08f, 0.08f, 0.08f, 0.92f));
			DrawRect(rect, GetProgressColor(progress));
			GUI.Box(val3, GUIContent.none, boxStyle);
			int num7 = Mathf.RoundToInt(Mathf.Clamp01(progress) * 100f);
			GUI.Label(val4, num7 + "%", percentStyle);
			GUI.Label(val5, hint, hintStyle);
		}

		private void ExecuteReturnToLobbySequence(string triggerReason)
		{
			try
			{
				if (!IsExecutableState())
				{
					transitionLocked = false;
					return;
				}
				if (!TryCacheReturnToLobbyMethod(logOnSuccess: false))
				{
					transitionLocked = false;
					return;
				}
				returnToLobbyClickMethod.Invoke(returnToLobbyPluginInstance, null);
				if (hardReloadCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(hardReloadCoroutine);
					hardReloadCoroutine = null;
				}
				if (enableHardReloadFallback.Value)
				{
					hardReloadCoroutine = ((MonoBehaviour)this).StartCoroutine(HardReloadFallbackCoroutine());
				}
				if (logExecution.Value)
				{
					Log.LogInfo((object)("Success: ReturnToLobby yes action executed " + triggerReason));
				}
			}
			catch (TargetInvocationException ex)
			{
				Exception ex2 = ((ex.InnerException != null) ? ex.InnerException : ex);
				transitionLocked = false;
				WriteFailureLog("Failure: ReturnToLobby yes action invocation\n" + ex2);
			}
			catch (Exception ex3)
			{
				transitionLocked = false;
				WriteFailureLog("Failure: ReturnToLobby yes action\n" + ex3);
			}
		}

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

		private bool TryForceReloadToLobbyMenu(int attempt)
		{
			try
			{
				RunManager instance = RunManager.instance;
				if ((Object)(object)instance == (Object)null)
				{
					WriteFailureLog("Failure: RunManager.instance is null before hard reload");
					return false;
				}
				if ((Object)(object)instance.levelLobbyMenu != (Object)null)
				{
					instance.levelCurrent = instance.levelLobbyMenu;
				}
				SetRunManagerInternalField(instance, "waitToChangeScene", false);
				SetRunManagerInternalField(instance, "lobbyJoin", false);
				SetRunManagerInternalField(instance, "restarting", false);
				SetRunManagerInternalField(instance, "restartingDone", false);
				SetRunManagerInternalField(instance, "gameOver", false);
				SetRunManagerInternalField(instance, "allPlayersDead", false);
				SetRunManagerInternalField(instance, "allPlayersDeadCheckDisabled", true);
				TrySaveCurrentStats();
				TryDestroyNetworkObjects();
				if (GameManager.Multiplayer() && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
				{
					PhotonNetwork.AutomaticallySyncScene = true;
					PhotonNetwork.LoadLevel("Reload");
				}
				else
				{
					SceneManager.LoadSceneAsync("Reload");
				}
				if (logFallback.Value && attempt == 1)
				{
					Log.LogInfo((object)"Success: Hard reload fallback requested for lobby menu");
				}
				return true;
			}
			catch (Exception ex)
			{
				WriteFailureLog("Failure: Hard reload fallback\n" + ex);
				return false;
			}
		}

		private void TrySaveCurrentStats()
		{
			try
			{
				if ((Object)(object)StatsManager.instance != (Object)null)
				{
					StatsManager.instance.SaveFileSave();
				}
			}
			catch (Exception ex)
			{
				WriteFailureLog("Failure: SaveFileSave before hard reload\n" + ex);
			}
		}

		private void TryDestroyNetworkObjects()
		{
			try
			{
				if (destroyNetworkObjectsBeforeReload.Value && GameManager.Multiplayer() && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && (Object)(object)NetworkManager.instance != (Object)null)
				{
					NetworkManager.instance.DestroyAll();
				}
			}
			catch (Exception ex)
			{
				WriteFailureLog("Failure: DestroyAll before hard reload\n" + ex);
			}
		}

		private void SetRunManagerInternalField(RunManager runManager, string fieldName, object value)
		{
			try
			{
				FieldInfo field = typeof(RunManager).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null))
				{
					field.SetValue(runManager, value);
				}
			}
			catch (Exception ex)
			{
				WriteFailureLog("Failure: Set RunManager field " + fieldName + "\n" + ex);
			}
		}

		private bool IsExecutableState()
		{
			try
			{
				if ((Object)(object)RunManager.instance == (Object)null)
				{
					WriteFailureLog("Failure: RunManager.instance is null");
					return false;
				}
				if ((Object)(object)StatsManager.instance == (Object)null)
				{
					WriteFailureLog("Failure: StatsManager.instance is null");
					return false;
				}
				if ((Object)(object)GameManager.instance == (Object)null)
				{
					WriteFailureLog("Failure: GameManager.instance is null");
					return false;
				}
				if (!SemiFunc.IsMasterClientOrSingleplayer())
				{
					WriteFailureLog("Failure: Not master client or singleplayer");
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				WriteFailureLog("Failure: Executable state check\n" + ex);
				return false;
			}
		}

		private bool TryCacheReturnToLobbyMethod(bool logOnSuccess)
		{
			try
			{
				if ((Object)(object)returnToLobbyPluginInstance != (Object)null && returnToLobbyClickMethod != null)
				{
					return true;
				}
				if (!Chainloader.PluginInfos.TryGetValue("OrigamiCoder.ReturnToLobby", out var value) || value == null || (Object)(object)value.Instance == (Object)null)
				{
					WriteFailureLog("Failure: ReturnToLobby plugin not found");
					return false;
				}
				returnToLobbyPluginInstance = value.Instance;
				returnToLobbyClickMethod = ((object)returnToLobbyPluginInstance).GetType().GetMethod("ReturnLobbyClick", BindingFlags.Instance | BindingFlags.NonPublic);
				if (returnToLobbyClickMethod == null)
				{
					WriteFailureLog("Failure: ReturnLobbyClick method not found");
					return false;
				}
				if (logOnSuccess)
				{
					Log.LogInfo((object)("ReturnToLobby target method cached: " + ((object)returnToLobbyPluginInstance).GetType().FullName + ".ReturnLobbyClick"));
				}
				return true;
			}
			catch (Exception ex)
			{
				WriteFailureLog("Failure: ReturnToLobby method cache\n" + ex);
				return false;
			}
		}

		private bool TryGetLoadingStuckActive()
		{
			try
			{
				LoadingUI instance = LoadingUI.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return false;
				}
				if (loadingUiStuckActiveField == null)
				{
					loadingUiStuckActiveField = typeof(LoadingUI).GetField("stuckActive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (loadingUiStuckActiveField == null)
					{
						WriteFailureLog("Failure: LoadingUI.stuckActive field not found");
						return false;
					}
				}
				if (!(loadingUiStuckActiveField.GetValue(instance) is bool result))
				{
					return false;
				}
				return result;
			}
			catch (Exception ex)
			{
				WriteFailureLog("Failure: Loading stuck UI check\n" + ex);
				return false;
			}
		}

		private void UpdateTransitionLock()
		{
			if (transitionLocked)
			{
				if (transitionLockSeconds.Value <= 0f)
				{
					transitionLocked = false;
				}
				else if (Time.realtimeSinceStartup >= transitionLockEndTime)
				{
					transitionLocked = false;
				}
			}
		}

		private void ResetHoldState()
		{
			isHolding = false;
			hasExecutedThisHold = false;
			shouldDrawProgress = false;
			currentProgress = 0f;
		}

		private void ResetAutoReturnState()
		{
			autoCountdownActive = false;
			autoExecutedThisStuck = false;
			shouldDrawAutoCountdown = false;
			autoCountdownProgress = 0f;
		}

		private void EnsureGuiResources()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Expected O, but got Unknown
			if ((Object)(object)whiteTexture == (Object)null)
			{
				whiteTexture = Texture2D.whiteTexture;
			}
			if (titleStyle == null)
			{
				titleStyle = new GUIStyle(GUI.skin.label);
				titleStyle.alignment = (TextAnchor)4;
				titleStyle.fontStyle = (FontStyle)1;
				titleStyle.fontSize = Mathf.Clamp(titleFontSize.Value, 8, 64);
				titleStyle.normal.textColor = Color.white;
			}
			else
			{
				titleStyle.fontSize = Mathf.Clamp(titleFontSize.Value, 8, 64);
			}
			if (percentStyle == null)
			{
				percentStyle = new GUIStyle(GUI.skin.label);
				percentStyle.alignment = (TextAnchor)4;
				percentStyle.fontStyle = (FontStyle)1;
				percentStyle.fontSize = Mathf.Clamp(percentFontSize.Value, 8, 64);
				percentStyle.normal.textColor = Color.white;
			}
			else
			{
				percentStyle.fontSize = Mathf.Clamp(percentFontSize.Value, 8, 64);
			}
			if (hintStyle == null)
			{
				hintStyle = new GUIStyle(GUI.skin.label);
				hintStyle.alignment = (TextAnchor)4;
				hintStyle.fontSize = Mathf.Max(8, Mathf.Clamp(percentFontSize.Value, 8, 64) - 4);
				hintStyle.normal.textColor = new Color(1f, 1f, 1f, 0.82f);
			}
			else
			{
				hintStyle.fontSize = Mathf.Max(8, Mathf.Clamp(percentFontSize.Value, 8, 64) - 4);
			}
			if (boxStyle == null)
			{
				boxStyle = new GUIStyle(GUI.skin.box);
			}
		}

		private void DrawRect(Rect rect, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Color color2 = GUI.color;
			GUI.color = color;
			GUI.DrawTexture(rect, (Texture)(object)whiteTexture);
			GUI.color = color2;
		}

		private Color GetProgressColor(float progress)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (progress >= 0.9f)
			{
				return new Color(1f, 0.35f, 0.15f, 0.96f);
			}
			return new Color(1f, 0.62f, 0.08f, 0.96f);
		}

		private void WriteFailureLog(string message)
		{
			if (logFailure != null && !logFailure.Value)
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!(realtimeSinceStartup - lastFailureLogTime < 2f))
			{
				lastFailureLogTime = realtimeSinceStartup;
				if (Log != null)
				{
					Log.LogWarning((object)message);
				}
			}
		}
	}
}