Decompiled source of Challenges v0.1.2

BepInEx/plugins/Challenges/Challenges.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using Challenges;
using Challenges.ChallengeScripts;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
public class ChallengeKiosk : MonoBehaviourPun, IInteractibleConstant, IInteractible
{
	public float interactTime = 0.5f;

	public GameObject challengesGUI;

	private MaterialPropertyBlock mpb;

	private MeshRenderer[] _mr;

	private static readonly Action<MenuWindow> OpenMenu = AccessTools.MethodDelegate<Action<MenuWindow>>(AccessTools.Method(typeof(MenuWindow), "Open", (Type[])null, (Type[])null), (object)null, true);

	private static MethodInfo _miLoadSceneProcess;

	private MeshRenderer[] meshRenderers
	{
		get
		{
			if (_mr == null)
			{
				_mr = ((Component)this).GetComponentsInChildren<MeshRenderer>();
				MonoBehaviour.print((object)_mr.Length);
			}
			return _mr;
		}
		set
		{
			_mr = value;
		}
	}

	public bool holdOnFinish { get; }

	public bool IsInteractible(Character interactor)
	{
		return true;
	}

	public void Awake()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		mpb = new MaterialPropertyBlock();
	}

	private void Start()
	{
		//IL_0020: 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)
		if (GameHandler.GetService<NextLevelService>().Data.IsSome)
		{
			NextLevelData value = GameHandler.GetService<NextLevelService>().Data.Value;
			Debug.Log((object)$"seconds left until next map... {((NextLevelData)(ref value)).SecondsLeft}");
		}
		GameHandler.GetService<RichPresenceService>().SetState((RichPresenceState)1);
	}

	public void Interact(Character interactor)
	{
	}

	public void HoverEnter()
	{
		if (mpb == null)
		{
			return;
		}
		mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 1f);
		for (int i = 0; i < meshRenderers.Length; i++)
		{
			if ((Object)(object)meshRenderers[i] != (Object)null)
			{
				((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
			}
		}
	}

	public void HoverExit()
	{
		if (mpb != null)
		{
			mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 0f);
			for (int i = 0; i < meshRenderers.Length; i++)
			{
				((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
			}
		}
	}

	public Vector3 Center()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		return ((Component)this).transform.position;
	}

	public Transform GetTransform()
	{
		return ((Component)this).transform;
	}

	public string GetInteractionText()
	{
		return LocalizedText.GetText("BOARDFLIGHT", true);
	}

	public string GetName()
	{
		return "CHALLENGE KIOSK";
	}

	public bool IsConstantlyInteractable(Character interactor)
	{
		return IsInteractible(interactor);
	}

	public float GetInteractTime(Character interactor)
	{
		return interactTime;
	}

	public void Interact_CastFinished(Character interactor)
	{
		ChallengesGUILoader.EnsureMenuReady();
		if ((Object)(object)challengesGUI == (Object)null)
		{
			Debug.LogWarning((object)"ChallengeKiosk.Interact_CastFinished called without a linked challenges GUI instance.");
			return;
		}
		MenuWindow component = challengesGUI.GetComponent<MenuWindow>();
		if ((Object)(object)component == (Object)null)
		{
			Debug.LogWarning((object)"ChallengeKiosk.Interact_CastFinished could not find MenuWindow on challenges GUI instance.");
		}
		else
		{
			OpenMenu(component);
		}
	}

	public void StartGame(int ascent)
	{
		ChallengeMultiplayerSync.RequestChallengeStart(ascent);
	}

	public void CancelCast(Character interactor)
	{
	}

	public void ReleaseInteract(Character interactor)
	{
	}

	[PunRPC]
	public void LoadIslandMaster(int ascent)
	{
		if (PhotonNetwork.IsMasterClient)
		{
			ChallengeMultiplayerSync.HandleMasterStartRequest(ascent);
		}
	}

	[PunRPC]
	public void BeginIslandLoadRPC(string sceneName, int ascent)
	{
		BeginIslandLoad(sceneName, ascent);
	}

	internal static void BeginIslandLoad(string sceneName, int ascent)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Expected O, but got Unknown
		MenuWindow.CloseAllWindows();
		GameHandler.AddStatus<SceneSwitchingStatus>((GameStatus)new SceneSwitchingStatus());
		Debug.Log((object)("Begin scene load RPC: " + sceneName));
		Ascents.currentAscent = ascent;
		LoadingScreenHandler instance = RetrievableResourceSingleton<LoadingScreenHandler>.Instance;
		IEnumerator enumerator = LoadSceneProcess_Internal(instance, sceneName, networked: true, yieldForCharacterSpawn: true, 0f);
		instance.Load((LoadingScreenType)1, (Action)null, new IEnumerator[1] { enumerator });
	}

	internal static string DetermineSceneName()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		NextLevelService service = GameHandler.GetService<NextLevelService>();
		string text = "WilIsland";
		if (service != null && service.Data.IsSome)
		{
			text = SingletonAsset<MapBaker>.Instance.GetLevel(service.Data.Value.CurrentLevelIndex);
		}
		else if (PhotonNetwork.OfflineMode)
		{
			text = SingletonAsset<MapBaker>.Instance.GetLevel(0);
		}
		if (string.IsNullOrEmpty(text))
		{
			text = "WilIsland";
		}
		return text;
	}

	private static IEnumerator LoadSceneProcess_Internal(object handler, string sceneName, bool networked, bool yieldForCharacterSpawn, float delay)
	{
		if (handler == null)
		{
			throw new ArgumentNullException("handler");
		}
		if (_miLoadSceneProcess == null)
		{
			_miLoadSceneProcess = handler.GetType().GetMethod("LoadSceneProcess", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[4]
			{
				typeof(string),
				typeof(bool),
				typeof(bool),
				typeof(float)
			}, null);
			if (_miLoadSceneProcess == null)
			{
				throw new MissingMethodException(handler.GetType().FullName, "LoadSceneProcess(string, bool, bool, float)");
			}
		}
		return (_miLoadSceneProcess.Invoke(handler, new object[4] { sceneName, networked, yieldForCharacterSpawn, delay }) as IEnumerator) ?? throw new InvalidOperationException("LoadSceneProcess did not return an IEnumerator.");
	}
}
public static class ChallengeMultiplayerSync
{
	private sealed class CallbackTarget : IOnEventCallback, IInRoomCallbacks, IMatchmakingCallbacks
	{
		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent != null)
			{
				switch (photonEvent.Code)
				{
				case 101:
					HandleSelectionEvent(photonEvent.CustomData);
					break;
				case 102:
					HandleStartRequestEvent(photonEvent.CustomData, photonEvent.Sender);
					break;
				case 103:
					HandleStartConfirmedEvent(photonEvent.CustomData);
					break;
				}
			}
		}

		public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			ApplySelectionFromProperties(propertiesThatChanged);
		}

		public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
		}

		public void OnPlayerLeftRoom(Player otherPlayer)
		{
		}

		public void OnPlayerEnteredRoom(Player newPlayer)
		{
		}

		public void OnMasterClientSwitched(Player newMasterClient)
		{
		}

		public void OnFriendListUpdate(List<FriendInfo> friendList)
		{
		}

		public void OnCreatedRoom()
		{
		}

		public void OnCreateRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRandomFailed(short returnCode, string message)
		{
		}

		public void OnLeftRoom()
		{
		}

		public void OnJoinedRoom()
		{
			if (PhotonNetwork.CurrentRoom != null)
			{
				ApplySelectionFromProperties(((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties);
			}
		}

		public void ApplySelectionFromProperties(Hashtable props)
		{
			if (props == null || ((Dictionary<object, object>)(object)props).Count == 0 || (!((Dictionary<object, object>)(object)props).ContainsKey((object)"challenge.selected") && !((Dictionary<object, object>)(object)props).ContainsKey((object)"challenge.ascent")))
			{
				return;
			}
			((Dictionary<object, object>)(object)props).TryGetValue((object)"challenge.selected", out object value);
			((Dictionary<object, object>)(object)props).TryGetValue((object)"challenge.ascent", out object value2);
			string text = value as string;
			int? ascent = null;
			if (value2 != null)
			{
				try
				{
					ascent = Convert.ToInt32(value2);
				}
				catch
				{
					ascent = null;
				}
			}
			ChallengesGUILoader.ApplyNetworkSelection(string.IsNullOrEmpty(text) ? null : text, ascent);
		}

		private void HandleSelectionEvent(object payload)
		{
			if (!(payload is object[] array) || array.Length == 0)
			{
				return;
			}
			string text = array[0] as string;
			int? ascent = null;
			if (array.Length > 1 && array[1] != null)
			{
				try
				{
					ascent = Convert.ToInt32(array[1]);
				}
				catch
				{
					ascent = null;
				}
			}
			ChallengesGUILoader.ApplyNetworkSelection(string.IsNullOrEmpty(text) ? null : text, ascent);
		}

		private void HandleStartRequestEvent(object payload, int sender)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				int ascent;
				try
				{
					ascent = Convert.ToInt32(payload);
				}
				catch
				{
					ascent = Ascents.currentAscent;
				}
				HandleMasterStartRequest(ascent);
			}
		}

		private void HandleStartConfirmedEvent(object payload)
		{
			if (payload is object[] array && array.Length >= 2)
			{
				string text = array[0] as string;
				int ascent;
				try
				{
					ascent = Convert.ToInt32(array[1]);
				}
				catch
				{
					ascent = Ascents.currentAscent;
				}
				if (string.IsNullOrEmpty(text))
				{
					text = ChallengeKiosk.DetermineSceneName();
				}
				ChallengeKiosk.BeginIslandLoad(text, ascent);
			}
		}
	}

	private const byte SelectionEventCode = 101;

	private const byte StartRequestEventCode = 102;

	private const byte StartConfirmedEventCode = 103;

	private const string SelectedChallengeProp = "challenge.selected";

	private const string SelectedAscentProp = "challenge.ascent";

	private static bool _initialized;

	private static CallbackTarget _callbackTarget;

	public static void Initialize()
	{
		if (!_initialized)
		{
			_callbackTarget = new CallbackTarget();
			PhotonNetwork.AddCallbackTarget((object)_callbackTarget);
			_initialized = true;
			if (PhotonNetwork.CurrentRoom != null)
			{
				_callbackTarget.ApplySelectionFromProperties(((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties);
			}
		}
	}

	public static void BroadcastSelection(Challenge challenge)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Expected O, but got Unknown
		Initialize();
		if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
		{
			string text = ((challenge != null) ? challenge.id : string.Empty);
			object obj = ((challenge != null) ? ((object)Ascents.currentAscent) : null);
			object[] array = new object[2] { text, obj };
			PhotonNetwork.RaiseEvent((byte)101, (object)array, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			}, SendOptions.SendReliable);
			Hashtable val = new Hashtable
			{
				[(object)"challenge.selected"] = (string.IsNullOrEmpty(text) ? null : text),
				[(object)"challenge.ascent"] = obj
			};
			PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
	}

	public static void NotifyAirportLoaded()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		Initialize();
		if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && PhotonNetwork.IsMasterClient)
		{
			Hashtable val = new Hashtable
			{
				[(object)"challenge.selected"] = null,
				[(object)"challenge.ascent"] = null
			};
			PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
	}

	public static void RequestChallengeStart(int ascent)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		Initialize();
		if (!PhotonNetwork.InRoom)
		{
			ChallengeKiosk.BeginIslandLoad(ChallengeKiosk.DetermineSceneName(), ascent);
			return;
		}
		if (PhotonNetwork.IsMasterClient)
		{
			HandleMasterStartRequest(ascent);
			return;
		}
		PhotonNetwork.RaiseEvent((byte)102, (object)ascent, new RaiseEventOptions
		{
			Receivers = (ReceiverGroup)2
		}, SendOptions.SendReliable);
	}

	internal static void HandleMasterStartRequest(int ascent)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		string text = ChallengeKiosk.DetermineSceneName();
		object[] array = new object[2] { text, ascent };
		PhotonNetwork.RaiseEvent((byte)103, (object)array, new RaiseEventOptions
		{
			Receivers = (ReceiverGroup)1
		}, SendOptions.SendReliable);
	}
}
public enum ChallengeDifficulty
{
	LIGHT,
	EASY,
	MEDIUM,
	MEDIUMCORE,
	HARD,
	HARDCORE
}
public class Challenge
{
	public string title;

	public string description;

	public ChallengeDifficulty difficulty;

	public bool enabled;

	public string id { get; }

	public int? ascentOverride { get; }

	public Challenge(string id, string title = "My Challenge", string description = "Custom Challenge for PEAK", ChallengeDifficulty difficulty = ChallengeDifficulty.MEDIUM, int? ascentOverride = null)
	{
		this.id = id;
		this.title = title;
		this.description = description;
		this.difficulty = difficulty;
		this.ascentOverride = ascentOverride;
	}
}
public static class ChallengesAPI
{
	public static bool IsHell = false;

	public const string HellChallengeId = "hell";

	public static Dictionary<string, Challenge> challenges = new Dictionary<string, Challenge>();

	private static readonly List<Challenge> _registeredChallenges = new List<Challenge>();

	private static bool _sceneHooked;

	public static event Action ChallengeListChanged;

	private static event Action<Scene, LoadSceneMode> _sceneLoaded;

	public static event Action<Scene, LoadSceneMode> SceneLoaded
	{
		add
		{
			_sceneLoaded += value;
			UpdateSceneSubscription();
		}
		remove
		{
			_sceneLoaded -= value;
			UpdateSceneSubscription();
		}
	}

	public static void RegisterChallenge(Challenge challenge)
	{
		if (challenge != null && !string.IsNullOrEmpty(challenge.id))
		{
			EnsureChallengeDictionary();
			if (challenges != null && challenges.TryGetValue(challenge.id, out var value))
			{
				challenge.enabled = value.enabled;
			}
			int num = _registeredChallenges.FindIndex((Challenge c) => c != null && c.id == challenge.id);
			if (num >= 0)
			{
				_registeredChallenges[num] = challenge;
			}
			else
			{
				_registeredChallenges.Add(challenge);
			}
			challenges[challenge.id] = challenge;
			ChallengesAPI.ChallengeListChanged?.Invoke();
			UpdateSceneSubscription();
		}
	}

	public static bool IsChallengeEnabled(string id)
	{
		EnsureChallengeDictionary();
		if (IsHell)
		{
			return true;
		}
		if (challenges == null)
		{
			return false;
		}
		if (challenges.TryGetValue(id, out var value))
		{
			return value.enabled;
		}
		return false;
	}

	public static void SetSingularChallengeEnabled(string id)
	{
		EnsureChallengeDictionary();
		if (challenges == null || challenges.Count == 0)
		{
			return;
		}
		bool flag = false;
		bool flag2 = !string.IsNullOrEmpty(id) && id == "hell";
		if (IsHell != flag2)
		{
			IsHell = flag2;
			flag = true;
		}
		foreach (Challenge value in challenges.Values)
		{
			bool flag3 = flag2 || value.id == id;
			if (value.enabled != flag3)
			{
				value.enabled = flag3;
				flag = true;
			}
		}
		if (flag)
		{
			ChallengesAPI.ChallengeListChanged?.Invoke();
			UpdateSceneSubscription();
		}
	}

	public static bool IsOneOfTheseChallengesEnabled(string[] challengeList)
	{
		for (int i = 0; i < challengeList.Length; i++)
		{
			if (IsChallengeEnabled(challengeList[i]))
			{
				return true;
			}
		}
		return false;
	}

	public static void DisableAllChallenges()
	{
		EnsureChallengeDictionary();
		if (challenges == null || challenges.Count == 0)
		{
			return;
		}
		bool flag = false;
		foreach (Challenge value in challenges.Values)
		{
			if (value.enabled)
			{
				value.enabled = false;
				flag = true;
			}
		}
		if (flag)
		{
			ChallengesAPI.ChallengeListChanged?.Invoke();
			UpdateSceneSubscription();
		}
	}

	private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		//IL_000b: 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)
		ChallengesAPI._sceneLoaded?.Invoke(scene, mode);
		if (!AnyChallengeActive())
		{
			UpdateSceneSubscription();
		}
	}

	private static bool AnyChallengeActive()
	{
		EnsureChallengeDictionary();
		if (IsHell)
		{
			return true;
		}
		if (challenges == null || challenges.Count == 0)
		{
			return false;
		}
		foreach (Challenge value in challenges.Values)
		{
			if (value.enabled)
			{
				return true;
			}
		}
		return false;
	}

	private static void UpdateSceneSubscription()
	{
		bool flag = ChallengesAPI._sceneLoaded != null && AnyChallengeActive();
		if (flag && !_sceneHooked)
		{
			SceneManager.sceneLoaded += HandleSceneLoaded;
			_sceneHooked = true;
		}
		else if (!flag && _sceneHooked)
		{
			SceneManager.sceneLoaded -= HandleSceneLoaded;
			_sceneHooked = false;
		}
	}

	internal static void EnsureChallengesRegistered()
	{
		EnsureChallengeDictionary();
	}

	private static void EnsureChallengeDictionary()
	{
		if (challenges == null)
		{
			challenges = new Dictionary<string, Challenge>();
		}
		if (challenges.Count > 0 || _registeredChallenges.Count == 0)
		{
			return;
		}
		for (int i = 0; i < _registeredChallenges.Count; i++)
		{
			Challenge challenge = _registeredChallenges[i];
			if (challenge != null && !string.IsNullOrEmpty(challenge.id))
			{
				challenges[challenge.id] = challenge;
			}
		}
	}
}
public static class ChallengesGUILoader
{
	private class LoaderHost : MonoBehaviour
	{
		public void Boot(Action onReady)
		{
			((MonoBehaviour)this).StartCoroutine(BootNextFrame(onReady));
		}

		private IEnumerator BootNextFrame(Action onReady)
		{
			yield return null;
			onReady?.Invoke();
		}

		public IEnumerator RetryUntil(Func<bool> condition, int attempts, float delaySeconds, Action onTick)
		{
			for (int i = 1; i <= attempts; i++)
			{
				yield return (object)new WaitForSeconds(delaySeconds);
				Log($"Retry {i}/{attempts} – challenges={((ChallengesAPI.challenges != null) ? ChallengesAPI.challenges.Count : 0)}");
				onTick?.Invoke();
				if (condition())
				{
					yield break;
				}
			}
			Log("Retries exhausted.");
		}
	}

	private static GameObject _menuPrefab;

	private static GameObject _fallbackButtonPrefab;

	private static GameObject _menuInstance;

	private static Transform _listRoot;

	private static GameObject _buttonTemplate;

	private static GameObject _selectedPanel;

	private static Button _backButton;

	private static Button _goButton;

	private static MenuWindow _menuWindow;

	private static Challenge _selectedChallenge;

	private static readonly List<ChallengeKiosk> _linkedKiosks = new List<ChallengeKiosk>();

	private static bool _suppressSelectionBroadcast;

	private static string _pendingSelectedChallengeId;

	private static int _page = 0;

	private static int _perPage = 5;

	private static LoaderHost _host;

	private static bool _pendingRefresh;

	public static void Load(GameObject challengesGUINew, GameObject challengeButtonNew)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		_menuPrefab = challengesGUINew;
		_fallbackButtonPrefab = challengeButtonNew;
		ChallengesAPI.ChallengeListChanged -= OnChallengeListChanged;
		ChallengesAPI.ChallengeListChanged += OnChallengeListChanged;
		ChallengeMultiplayerSync.Initialize();
		SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "Airport")
			{
				ChallengesAPI.DisableAllChallenges();
				ClearSelection(broadcast: false);
				ChallengeMultiplayerSync.NotifyAirportLoaded();
				CreateKiosk();
			}
		};
		Scene activeScene = SceneManager.GetActiveScene();
		if (((Scene)(ref activeScene)).isLoaded && ((Scene)(ref activeScene)).name == "Airport")
		{
			ChallengesAPI.DisableAllChallenges();
			ClearSelection(broadcast: false);
			ChallengeMultiplayerSync.NotifyAirportLoaded();
			CreateKiosk();
		}
	}

	public static int AssignMasterClientViewID(GameObject go)
	{
		int num = PhotonNetwork.AllocateViewID(false);
		go.GetComponent<PhotonView>().ViewID = num;
		return num;
	}

	private static void Log(string msg)
	{
		Debug.Log((object)("[ChallengesGUI] " + msg));
	}

	private static void CreateKiosk()
	{
		if ((Object)(object)_menuInstance == (Object)null)
		{
			ResetCachedReferences();
		}
		if ((Object)(object)_menuInstance != (Object)null)
		{
			if (EnsureMenuStructure())
			{
				EnsureHost();
				LinkKiosksToMenu();
				if (_pendingRefresh && (Object)(object)_listRoot != (Object)null)
				{
					_pendingRefresh = false;
					FillButtons();
				}
				else if ((Object)(object)_listRoot != (Object)null)
				{
					ChallengesAPI.EnsureChallengesRegistered();
					FillButtons();
				}
				return;
			}
			Log("Cached menu references missing; rebuilding GUI instance.");
			Object.Destroy((Object)(object)_menuInstance);
			ResetCachedReferences();
		}
		if ((Object)(object)_menuPrefab == (Object)null)
		{
			Log("Menu prefab is null.");
			return;
		}
		_menuInstance = Object.Instantiate<GameObject>(_menuPrefab);
		((Object)_menuInstance).name = "ChallengesGUI";
		_menuInstance.SetActive(false);
		_menuWindow = (MenuWindow)(object)_menuInstance.AddComponent<ChallengeMenuWindow>();
		EnsureHost();
		EnsureMenuStructure();
		LinkKiosksToMenu();
		_host.Boot(delegate
		{
			TryFillOrRetry();
			if (_pendingRefresh && (Object)(object)_listRoot != (Object)null)
			{
				_pendingRefresh = false;
				FillButtons();
			}
		});
	}

	internal static void EnsureMenuReady()
	{
		if ((Object)(object)_menuInstance == (Object)null)
		{
			CreateKiosk();
			return;
		}
		if (!EnsureMenuStructure())
		{
			Log("Menu structure invalid when ensuring readiness; rebuilding.");
			Object.Destroy((Object)(object)_menuInstance);
			ResetCachedReferences();
			CreateKiosk();
			return;
		}
		if ((Object)(object)_listRoot == (Object)null)
		{
			Log("EnsureMenuReady aborted: list root missing after rebuild.");
			return;
		}
		ChallengesAPI.EnsureChallengesRegistered();
		if (_pendingRefresh)
		{
			_pendingRefresh = false;
			FillButtons();
		}
		else
		{
			FillButtons();
		}
	}

	private static void EnsureHost()
	{
		if (!((Object)(object)_menuInstance == (Object)null) && !((Object)(object)_host != (Object)null))
		{
			_host = _menuInstance.GetComponent<LoaderHost>() ?? _menuInstance.AddComponent<LoaderHost>();
		}
	}

	private static bool EnsureMenuStructure()
	{
		if ((Object)(object)_menuInstance == (Object)null)
		{
			return false;
		}
		if ((Object)(object)_listRoot == (Object)null)
		{
			Transform val = _menuInstance.transform.FindChildRecursive("Content");
			Transform val2 = (Object.op_Implicit((Object)(object)val) ? val.Find("Main") : null);
			Transform val3 = (Object.op_Implicit((Object)(object)val2) ? val2.Find("ChallengeList") : null);
			_listRoot = (Object.op_Implicit((Object)(object)val3) ? val3.Find("Contents") : null);
			if ((Object)(object)_listRoot == (Object)null)
			{
				_listRoot = _menuInstance.transform.FindChildRecursive("Contents");
			}
			Log("List root: " + (Object.op_Implicit((Object)(object)_listRoot) ? _listRoot.GetHierarchyPath() : "null"));
		}
		if ((Object)(object)_listRoot != (Object)null && (Object)(object)_buttonTemplate == (Object)null)
		{
			Transform obj = _listRoot.Find("Challenge");
			_buttonTemplate = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)_buttonTemplate != (Object)null)
			{
				Log("Button template: " + _buttonTemplate.transform.GetHierarchyPath());
				_buttonTemplate.SetActive(false);
			}
			else
			{
				Log("Button template not found. Using fallback prefab.");
			}
		}
		if ((Object)(object)_selectedPanel == (Object)null)
		{
			Transform obj2 = _menuInstance.transform.FindChildRecursive("SelectedChallenge");
			_selectedPanel = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			Log("Selected panel: " + (Object.op_Implicit((Object)(object)_selectedPanel) ? _selectedPanel.transform.GetHierarchyPath() : "null"));
			if (Object.op_Implicit((Object)(object)_selectedPanel))
			{
				if (_selectedChallenge == null)
				{
					_selectedPanel.SetActive(false);
				}
				else
				{
					RenderSelectedChallenge();
				}
			}
		}
		WireNavigationButtons();
		UpdateGoButtonState();
		ApplyPendingSelectionIfNeeded();
		return (Object)(object)_listRoot != (Object)null;
	}

	private static void ResetCachedReferences()
	{
		_menuInstance = null;
		_listRoot = null;
		_buttonTemplate = null;
		_selectedPanel = null;
		_backButton = null;
		_goButton = null;
		_menuWindow = null;
		_host = null;
		_selectedChallenge = null;
		_pendingRefresh = false;
	}

	private static void LinkKiosksToMenu()
	{
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_menuInstance == (Object)null)
		{
			return;
		}
		PruneKioskList();
		ChallengeKiosk[] array = Object.FindObjectsByType<ChallengeKiosk>((FindObjectsSortMode)0);
		if (array != null && array.Length != 0)
		{
			for (int i = 0; i < array.Length; i++)
			{
				array[i].challengesGUI = _menuInstance;
				TrackKiosk(array[i]);
			}
			Log($"Linked GUI to {array.Length} existing ChallengeKiosk instance(s).");
		}
		else
		{
			AirportCheckInKiosk obj = Object.FindFirstObjectByType<AirportCheckInKiosk>();
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val != (Object)null)
			{
				bool activeSelf = val.activeSelf;
				val.SetActive(false);
				GameObject obj2 = Object.Instantiate<GameObject>(val, val.transform.position, val.transform.rotation, val.transform.parent);
				Transform transform = obj2.transform;
				transform.position -= new Vector3(0f, 0f, 0.7f);
				((Object)obj2).name = "ChallengesKiosk";
				PhotonView component = obj2.GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null)
				{
					PhotonNetwork.AllocateViewID(component);
				}
				AirportCheckInKiosk component2 = obj2.GetComponent<AirportCheckInKiosk>();
				if ((Object)(object)component2 != (Object)null)
				{
					Object.Destroy((Object)(object)component2);
				}
				ChallengeKiosk challengeKiosk = obj2.AddComponent<ChallengeKiosk>();
				challengeKiosk.challengesGUI = _menuInstance;
				TrackKiosk(challengeKiosk);
				obj2.SetActive(true);
				val.SetActive(activeSelf);
				Log("Spawned ChallengesKiosk clone and linked GUI.");
			}
			else
			{
				Log("Base AirportCheckInKiosk not found; could not spawn kiosk.");
			}
		}
		if ((Object)(object)_host == (Object)null)
		{
			_host = _menuInstance.AddComponent<LoaderHost>();
		}
		if (_pendingRefresh && (Object)(object)_listRoot != (Object)null)
		{
			_pendingRefresh = false;
			FillButtons();
		}
	}

	private static void TryFillOrRetry()
	{
		ChallengesAPI.EnsureChallengesRegistered();
		Log($"Initial challenges count: {ChallengesAPI.challenges.Count}");
		FillButtons();
		if (ChallengesAPI.challenges.Count == 0)
		{
			((MonoBehaviour)_host).StartCoroutine(_host.RetryUntil(() => ChallengesAPI.challenges.Count > 0, 8, 0.5f, FillButtons));
		}
	}

	private static void OnChallengeListChanged()
	{
		if ((Object)(object)_menuInstance == (Object)null || (Object)(object)_listRoot == (Object)null)
		{
			_pendingRefresh = true;
			return;
		}
		_pendingRefresh = false;
		FillButtons();
	}

	private static void FillButtons()
	{
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		if ((Object)(object)_listRoot == (Object)null)
		{
			Log("FillButtons aborted: list root is null.");
			return;
		}
		ClearListKeepTemplate();
		int num = ((ChallengesAPI.challenges != null) ? ChallengesAPI.challenges.Count : 0);
		Log($"Render page={_page} perPage={_perPage} total={num}");
		if (num == 0)
		{
			RebuildLayout();
			return;
		}
		List<Challenge> list = ChallengesAPI.challenges.Values.ToList();
		int num2 = _page * _perPage;
		if (num2 >= num)
		{
			_page = (num - 1) / _perPage;
			num2 = _page * _perPage;
		}
		int num3 = Mathf.Min(num2 + _perPage, num);
		Log($"Slice [{num2}..{num3})");
		for (int i = num2; i < num3; i++)
		{
			Challenge challenge = list[i];
			Button val = SpawnButton(challenge.title);
			if (!((Object)(object)val == (Object)null))
			{
				WireChallengeButton(val, challenge);
				Log("Spawned button: " + challenge.title);
			}
		}
		bool num4 = _page > 0;
		bool flag = num3 < num;
		if (num4)
		{
			Button val2 = SpawnButton("Previous");
			if ((Object)(object)val2 != (Object)null)
			{
				((UnityEvent)val2.onClick).AddListener(new UnityAction(PrevPage));
			}
		}
		if (flag)
		{
			Button val3 = SpawnButton("Next");
			if ((Object)(object)val3 != (Object)null)
			{
				((UnityEvent)val3.onClick).AddListener(new UnityAction(NextPage));
			}
		}
		RebuildLayout();
		if ((Object)(object)_selectedPanel != (Object)null && _selectedChallenge == null)
		{
			_selectedPanel.SetActive(false);
		}
	}

	private static void ClearListKeepTemplate()
	{
		for (int num = _listRoot.childCount - 1; num >= 0; num--)
		{
			GameObject gameObject = ((Component)_listRoot.GetChild(num)).gameObject;
			if (!((Object)(object)_buttonTemplate != (Object)null) || gameObject != _buttonTemplate)
			{
				Object.Destroy((Object)(object)gameObject);
			}
		}
	}

	private static Button SpawnButton(string label)
	{
		GameObject val = _buttonTemplate ?? _fallbackButtonPrefab;
		if ((Object)(object)val == (Object)null)
		{
			Log("No button prefab available.");
			return null;
		}
		GameObject val2 = Object.Instantiate<GameObject>(val, _listRoot, false);
		((Object)val2).name = ((Object)val).name + "_Clone";
		val2.SetActive(true);
		Button obj = val2.GetComponent<Button>() ?? val2.AddComponent<Button>();
		Image component = val2.GetComponent<Image>();
		if ((Object)(object)component != (Object)null)
		{
			((Graphic)component).raycastTarget = true;
		}
		TMP_Text val3 = null;
		Transform val4 = val2.transform.Find("Text");
		if (Object.op_Implicit((Object)(object)val4))
		{
			val3 = ((Component)val4).GetComponent<TMP_Text>();
		}
		if ((Object)(object)val3 == (Object)null)
		{
			val3 = val2.GetComponentInChildren<TMP_Text>(true);
		}
		if ((Object)(object)val3 != (Object)null)
		{
			val3.text = label;
		}
		((UnityEventBase)obj.onClick).RemoveAllListeners();
		return obj;
	}

	private static void WireChallengeButton(Button btn, Challenge c)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		((UnityEventBase)btn.onClick).RemoveAllListeners();
		((UnityEvent)btn.onClick).AddListener((UnityAction)delegate
		{
			SelectChallenge(c);
		});
		if (c.enabled && (_selectedChallenge == null || _selectedChallenge.id != c.id))
		{
			SelectChallenge(c, broadcast: false);
		}
	}

	private static void SelectChallenge(Challenge challenge, bool broadcast = true)
	{
		if (challenge == null)
		{
			ClearSelection(broadcast);
			return;
		}
		string a = ((_selectedChallenge != null) ? _selectedChallenge.id : null);
		_selectedChallenge = challenge;
		_pendingSelectedChallengeId = challenge.id;
		if (challenge.ascentOverride.HasValue)
		{
			Ascents.currentAscent = challenge.ascentOverride.Value;
		}
		RenderSelectedChallenge();
		UpdateGoButtonState();
		Log($"Selected: {challenge.title} ({challenge.difficulty})");
		if (broadcast && !_suppressSelectionBroadcast && !string.Equals(a, challenge.id, StringComparison.Ordinal))
		{
			ChallengeMultiplayerSync.BroadcastSelection(challenge);
		}
	}

	private static void WireNavigationButtons()
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Expected O, but got Unknown
		if (!((Object)(object)_menuInstance == (Object)null))
		{
			Transform val = _menuInstance.transform.FindChildRecursive("BACK");
			if ((Object)(object)val != (Object)null)
			{
				_backButton = ((Component)val).GetComponent<Button>() ?? ((Component)val).gameObject.AddComponent<Button>();
				((UnityEventBase)_backButton.onClick).RemoveAllListeners();
				((UnityEvent)_backButton.onClick).AddListener(new UnityAction(HandleBackPressed));
			}
			Transform val2 = _menuInstance.transform.FindChildRecursive("Go");
			if ((Object)(object)val2 == (Object)null && (Object)(object)_selectedPanel != (Object)null)
			{
				val2 = _selectedPanel.transform.FindChildRecursive("Go");
			}
			if ((Object)(object)val2 != (Object)null)
			{
				_goButton = ((Component)val2).GetComponent<Button>() ?? ((Component)val2).gameObject.AddComponent<Button>();
				((UnityEventBase)_goButton.onClick).RemoveAllListeners();
				((UnityEvent)_goButton.onClick).AddListener(new UnityAction(HandleGoPressed));
			}
		}
	}

	private static void HandleBackPressed()
	{
		MenuWindow.CloseAllWindows();
		if ((Object)(object)_menuInstance != (Object)null)
		{
			_menuInstance.SetActive(false);
		}
		ClearSelection(broadcast: false);
	}

	private static void HandleGoPressed()
	{
		if (_selectedChallenge != null)
		{
			ChallengesAPI.SetSingularChallengeEnabled(_selectedChallenge.id);
			ChallengeKiosk anyKiosk = GetAnyKiosk();
			if ((Object)(object)anyKiosk != (Object)null)
			{
				int currentAscent = Ascents.currentAscent;
				anyKiosk.StartGame(currentAscent);
			}
			else
			{
				Log("No ChallengeKiosk available to start the run.");
			}
		}
	}

	private static void UpdateGoButtonState()
	{
		if (!((Object)(object)_goButton == (Object)null))
		{
			((Selectable)_goButton).interactable = _selectedChallenge != null;
		}
	}

	private static void RenderSelectedChallenge()
	{
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_selectedPanel == (Object)null)
		{
			return;
		}
		if (_selectedChallenge == null)
		{
			_selectedPanel.SetActive(false);
			return;
		}
		_selectedPanel.SetActive(true);
		Transform val = _selectedPanel.transform.Find("Title");
		Transform val2 = _selectedPanel.transform.Find("Subtext");
		Transform obj = _selectedPanel.transform.Find("Description");
		Transform val3 = ((obj != null) ? obj.Find("Body") : null);
		TMP_Text val4 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<TMP_Text>() : null);
		TMP_Text val5 = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).GetComponent<TMP_Text>() : null);
		TMP_Text val6 = (Object.op_Implicit((Object)(object)val3) ? ((Component)val3).GetComponent<TMP_Text>() : null);
		if ((Object)(object)val4 != (Object)null)
		{
			val4.text = _selectedChallenge.title;
		}
		if ((Object)(object)val5 != (Object)null)
		{
			((Graphic)val5).color = DifficultyColour(_selectedChallenge.difficulty);
			val5.text = _selectedChallenge.difficulty.ToString();
		}
		if ((Object)(object)val6 != (Object)null)
		{
			val6.text = _selectedChallenge.description;
		}
	}

	private static void ClearSelection(bool broadcast)
	{
		bool num = _selectedChallenge != null;
		_selectedChallenge = null;
		_pendingSelectedChallengeId = null;
		if ((Object)(object)_selectedPanel != (Object)null)
		{
			_selectedPanel.SetActive(false);
		}
		UpdateGoButtonState();
		if (num && broadcast && !_suppressSelectionBroadcast)
		{
			ChallengeMultiplayerSync.BroadcastSelection(null);
		}
	}

	private static void ApplyPendingSelectionIfNeeded()
	{
		if (!string.IsNullOrEmpty(_pendingSelectedChallengeId) && !((Object)(object)_selectedPanel == (Object)null))
		{
			ChallengesAPI.EnsureChallengesRegistered();
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.TryGetValue(_pendingSelectedChallengeId, out var value))
			{
				ChallengesAPI.SetSingularChallengeEnabled(_pendingSelectedChallengeId);
				SelectChallenge(value, broadcast: false);
				_pendingSelectedChallengeId = null;
			}
		}
	}

	private static void TrackKiosk(ChallengeKiosk kiosk)
	{
		if (!((Object)(object)kiosk == (Object)null) && !_linkedKiosks.Contains(kiosk))
		{
			_linkedKiosks.Add(kiosk);
		}
	}

	private static void PruneKioskList()
	{
		for (int num = _linkedKiosks.Count - 1; num >= 0; num--)
		{
			if ((Object)(object)_linkedKiosks[num] == (Object)null)
			{
				_linkedKiosks.RemoveAt(num);
			}
		}
	}

	private static ChallengeKiosk GetAnyKiosk()
	{
		PruneKioskList();
		if (_linkedKiosks.Count > 0)
		{
			return _linkedKiosks[0];
		}
		ChallengeKiosk challengeKiosk = Object.FindFirstObjectByType<ChallengeKiosk>();
		TrackKiosk(challengeKiosk);
		return challengeKiosk;
	}

	public static void NextPage()
	{
		int num = ((ChallengesAPI.challenges != null) ? ChallengesAPI.challenges.Count : 0);
		if ((_page + 1) * _perPage < num)
		{
			_page++;
			FillButtons();
		}
	}

	public static void PrevPage()
	{
		if (_page != 0)
		{
			_page--;
			FillButtons();
		}
	}

	private static void RebuildLayout()
	{
		Transform listRoot = _listRoot;
		RectTransform val = (RectTransform)(object)((listRoot is RectTransform) ? listRoot : null);
		if ((Object)(object)val != (Object)null)
		{
			LayoutRebuilder.ForceRebuildLayoutImmediate(val);
		}
	}

	internal static void ApplyNetworkSelection(string challengeId, int? ascent)
	{
		bool suppressSelectionBroadcast = _suppressSelectionBroadcast;
		_suppressSelectionBroadcast = true;
		try
		{
			if (ascent.HasValue)
			{
				Ascents.currentAscent = ascent.Value;
			}
			string a = ((_selectedChallenge != null) ? _selectedChallenge.id : null);
			if (string.IsNullOrEmpty(challengeId))
			{
				ChallengesAPI.DisableAllChallenges();
				ClearSelection(broadcast: false);
				return;
			}
			ChallengesAPI.EnsureChallengesRegistered();
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.TryGetValue(challengeId, out var value))
			{
				ChallengesAPI.SetSingularChallengeEnabled(challengeId);
				if (!string.Equals(a, challengeId, StringComparison.Ordinal) || (Object)(object)_selectedPanel == (Object)null)
				{
					SelectChallenge(value, broadcast: false);
				}
			}
			else
			{
				_pendingSelectedChallengeId = challengeId;
			}
		}
		finally
		{
			_suppressSelectionBroadcast = suppressSelectionBroadcast;
		}
	}

	private static Color DifficultyColour(ChallengeDifficulty d)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		return (Color)(d switch
		{
			ChallengeDifficulty.LIGHT => new Color(0.6f, 1f, 0.6f), 
			ChallengeDifficulty.EASY => new Color(0.1f, 0.9f, 0.1f), 
			ChallengeDifficulty.MEDIUM => new Color(1f, 0.85f, 0.1f), 
			ChallengeDifficulty.MEDIUMCORE => new Color(1f, 0.55f, 0f), 
			ChallengeDifficulty.HARD => new Color(0.9f, 0.1f, 0.1f), 
			ChallengeDifficulty.HARDCORE => new Color(0.5f, 0f, 0f), 
			_ => Color.white, 
		});
	}
}
public static class TransformFindExtensions
{
	public static Transform FindChildRecursive(this Transform parent, string name)
	{
		if ((Object)(object)parent == (Object)null)
		{
			return null;
		}
		for (int i = 0; i < parent.childCount; i++)
		{
			Transform child = parent.GetChild(i);
			if (((Object)child).name == name)
			{
				return child;
			}
			Transform val = child.FindChildRecursive(name);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
		}
		return null;
	}

	public static string GetHierarchyPath(this Transform t)
	{
		if ((Object)(object)t == (Object)null)
		{
			return "null";
		}
		Stack<string> stack = new Stack<string>();
		Transform val = t;
		while ((Object)(object)val != (Object)null)
		{
			stack.Push(((Object)val).name);
			val = val.parent;
		}
		return string.Join("/", stack);
	}
}
[BepInPlugin("com.khakixd.challenges", "Challenges", "1.0.0")]
public class ChallengesPlugin : BaseUnityPlugin
{
	private void Awake()
	{
		Harmony.CreateAndPatchAll(typeof(ChallengesPlugin).Assembly, "com.khakixd.challenges");
		BundleLoader.LoadBundleAndContentsWithName((BaseUnityPlugin)(object)this, "peakchallenges.peakbundle", (Action<PeakBundle>)delegate(PeakBundle bundle)
		{
			GameObject challengesGUINew = bundle.LoadAsset<GameObject>("Challenges");
			GameObject challengeButtonNew = bundle.LoadAsset<GameObject>("Challenge");
			ChallengesGUILoader.Load(challengesGUINew, challengeButtonNew);
			BuiltinChallenges.RegisterAll();
		});
	}
}
namespace Challenges
{
	public static class BuiltinChallenges
	{
		public static int highestAscent = 7;

		public static void RegisterAll()
		{
			ChallengesAPI.RegisterChallenge(new Challenge("permasnow", "Frostbite", " - Ascent 5\n - It is always storming in The Alpines\n - It is always raining in The Tropics\n - The Alpines is forced\nPLEASE USE THE FAIR SNOWSTORMS MOD.", ChallengeDifficulty.MEDIUMCORE, 5));
			ChallengesAPI.RegisterChallenge(new Challenge("instagib", "Instagib", " - Ascent 7\n - Going unconcious instantly kills you.\n", ChallengeDifficulty.HARD, 7));
			ChallengesAPI.RegisterChallenge(new Challenge("cappedluggage", "Baggage Allowance", " - Ascent 1\n - Only one item in luggage\n", ChallengeDifficulty.EASY, 1));
			ChallengesAPI.RegisterChallenge(new Challenge("hunger", "The Hunger", " - Ascent 3\n - Stamina only recovers after eating\n", ChallengeDifficulty.HARDCORE, 3));
			ChallengesAPI.RegisterChallenge(new Challenge("inversion", "Inversion", " - Ascent 4\n - Natural affliction recovery is reversed\n", ChallengeDifficulty.HARD, 4));
			ChallengesAPI.RegisterChallenge(new Challenge("narcolepsy", "Narcolepsy", " - Ascent 4\n - Knocked out by drowsiness every 1-3 minutes\n", ChallengeDifficulty.MEDIUM, 4));
			ChallengesAPI.RegisterChallenge(new Challenge("afflictionrandomizer", "Affliction Randomizer", " - Ascent 5\n - Added statuses become random afflictions\n", ChallengeDifficulty.HARD, 5));
			ChallengesAPI.RegisterChallenge(new Challenge("scoutmasterlurks", "Scoutmaster Lurks", " - Ascent Tenderfoot (-1)\n - Scoutmaster only hunts at night\n - He always goes for the closest camper\n", ChallengeDifficulty.MEDIUM, -1));
			ChallengesAPI.RegisterChallenge(new Challenge("planecrash", "Plane Crash", " - Ascent Tenderfoot (-1)\n - Start with 90% injury\n", ChallengeDifficulty.LIGHT, -1));
			ChallengesAPI.RegisterChallenge(new Challenge("hell", "Hell", $" - Ascent {highestAscent}\n" + " - All other challenges are enabled\n", ChallengeDifficulty.HARDCORE, highestAscent));
			ChooseBiome.Init();
			SnowPatch.Init();
		}
	}
	public class ChallengeMenuWindow : MenuWindow
	{
		public override bool openOnStart => false;

		public override bool selectOnOpen => true;

		public override bool closeOnPause => false;

		public override bool closeOnUICancel => true;

		public override bool autoHideOnClose => false;
	}
}
namespace Challenges.ChallengeScripts
{
	internal static class AfflictionRandomizerPatch
	{
		[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
		private static class CharacterAfflictionsAddStatusRandomizer
		{
			[HarmonyPrefix]
			private static void Prefix(ref STATUSTYPE statusType)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Expected I4, but got Unknown
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				if (IsRandomizerEnabled() && (int)statusType != 6 && StatusTypes != null && StatusTypes.Length != 0)
				{
					STATUSTYPE val = statusType;
					int num = Random.Range(0, StatusTypes.Length);
					STATUSTYPE val2 = StatusTypes[num];
					if (StatusTypes.Length > 1 && val2 == val)
					{
						num = (num + 1) % StatusTypes.Length;
						val2 = StatusTypes[num];
					}
					statusType = (STATUSTYPE)(int)val2;
				}
			}
		}

		private const string ChallengeId = "afflictionrandomizer";

		private static readonly STATUSTYPE[] StatusTypes = Enum.GetValues(typeof(STATUSTYPE)).Cast<STATUSTYPE>().ToArray();

		private static bool IsRandomizerEnabled()
		{
			return ChallengesAPI.IsChallengeEnabled("afflictionrandomizer");
		}
	}
	[HarmonyPatch(typeof(Luggage), "OpenLuggageRPC")]
	internal static class CappedLuggagePatch
	{
		private const string ChallengeId = "cappedluggage";

		private static void Prefix(ref bool spawnItems, ref bool __state)
		{
			if (__state = spawnItems && ShouldCap())
			{
				spawnItems = false;
			}
		}

		private static void Postfix(Luggage __instance, bool __state)
		{
			if (__state && !((Object)(object)__instance == (Object)null))
			{
				((MonoBehaviour)__instance).StartCoroutine(SpawnSingleItem(__instance));
			}
		}

		private static IEnumerator SpawnSingleItem(Luggage luggage)
		{
			if ((Object)(object)luggage == (Object)null)
			{
				yield break;
			}
			yield return (object)new WaitForSeconds(0.1f);
			Traverse val = Traverse.Create((object)luggage);
			IList value = val.Method("GetSpawnSpots", Array.Empty<object>()).GetValue<IList>();
			if (value == null || value.Count <= 0)
			{
				yield break;
			}
			IList list;
			try
			{
				list = Activator.CreateInstance(value.GetType()) as IList;
			}
			catch
			{
				list = null;
			}
			if (list == null)
			{
				list = value;
				if (list.IsFixedSize || list.IsReadOnly)
				{
					yield break;
				}
				for (int num = list.Count - 1; num >= 1; num--)
				{
					list.RemoveAt(num);
				}
			}
			else
			{
				list.Add(value[0]);
			}
			val.Method("SpawnItems", new object[1] { list }).GetValue();
		}

		private static bool ShouldCap()
		{
			Dictionary<string, Challenge> challenges = ChallengesAPI.challenges;
			if (challenges == null)
			{
				return false;
			}
			if (!challenges.ContainsKey("cappedluggage"))
			{
				return false;
			}
			return ChallengesAPI.IsChallengeEnabled("cappedluggage");
		}
	}
	public static class ChooseBiome
	{
		private const string FrostbiteId = "permasnow";

		private static bool _initialized;

		public static void Init()
		{
			if (!_initialized)
			{
				_initialized = true;
				ChallengesAPI.SceneLoaded += HandleSceneLoaded;
			}
		}

		public static void SetMesa()
		{
			//IL_0000: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).isLoaded)
			{
				ToggleSceneObject(activeScene, "Map/Biome_3/Desert", enable: true);
				ToggleSceneObject(activeScene, "Map/Biome_3/Snow", enable: false);
			}
		}

		public static void SetAlpines()
		{
			//IL_0000: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).isLoaded)
			{
				ToggleSceneObject(activeScene, "Map/Biome_3/Desert", enable: false);
				ToggleSceneObject(activeScene, "Map/Biome_3/Snow", enable: true);
			}
		}

		private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (IsGameplayScene(scene) && IsFrostbiteEnabled())
			{
				SetAlpines();
			}
		}

		private static bool IsGameplayScene(Scene scene)
		{
			if (!((Scene)(ref scene)).IsValid())
			{
				return false;
			}
			string text = ((Scene)(ref scene)).name ?? string.Empty;
			if (!(text == "WilIsland"))
			{
				return text.StartsWith("level_", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool IsFrostbiteEnabled()
		{
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("permasnow"))
			{
				return ChallengesAPI.IsChallengeEnabled("permasnow");
			}
			return false;
		}

		private static void ToggleSceneObject(Scene scene, string hierarchyPath, bool enable)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindSceneObject(scene, hierarchyPath);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)("[ChooseBiome] Could not find object '" + hierarchyPath + "' in scene '" + ((Scene)(ref scene)).name + "'."));
			}
			else if (val.activeSelf != enable)
			{
				val.SetActive(enable);
			}
		}

		private static GameObject FindSceneObject(Scene scene, string hierarchyPath)
		{
			if (!((Scene)(ref scene)).isLoaded || string.IsNullOrEmpty(hierarchyPath))
			{
				return null;
			}
			string[] array = hierarchyPath.Split(new char[1] { '/' });
			if (array.Length == 0)
			{
				return null;
			}
			GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
			for (int i = 0; i < rootGameObjects.Length; i++)
			{
				Transform val = FindByPathRecursive(rootGameObjects[i].transform, array, 0);
				if ((Object)(object)val != (Object)null)
				{
					return ((Component)val).gameObject;
				}
			}
			return null;
		}

		private static Transform FindByPathRecursive(Transform current, string[] segments, int index)
		{
			if ((Object)(object)current == (Object)null || segments == null || index >= segments.Length)
			{
				return null;
			}
			if (!string.Equals(((Object)current).name, segments[index], StringComparison.Ordinal))
			{
				if (index == 0)
				{
					for (int i = 0; i < current.childCount; i++)
					{
						Transform val = FindByPathRecursive(current.GetChild(i), segments, index);
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
				return null;
			}
			if (index == segments.Length - 1)
			{
				return current;
			}
			for (int j = 0; j < current.childCount; j++)
			{
				Transform val2 = FindByPathRecursive(current.GetChild(j), segments, index + 1);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}
	}
	internal static class HungerPatch
	{
		[HarmonyPatch(typeof(Character), "CanRegenStamina")]
		private static class DisableNaturalStaminaRegen
		{
			[HarmonyPostfix]
			private static void Postfix(Character __instance, ref bool __result)
			{
				if (__result && IsHungerEnabled() && (!((Object)(object)__instance != (Object)null) || !__instance.infiniteStam))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Action_RestoreHunger), "RunAction")]
		private static class RestoreStaminaWhenFed
		{
			[HarmonyPostfix]
			private static void Postfix(Action_RestoreHunger __instance)
			{
				if (!IsHungerEnabled())
				{
					return;
				}
				Character character = GetCharacter(__instance);
				if ((Object)(object)character == (Object)null)
				{
					return;
				}
				CharacterData data = character.data;
				if (!((Object)(object)data == (Object)null))
				{
					float num = character.GetMaxStamina();
					if (num < 0f)
					{
						num = 0f;
					}
					float num2 = num - data.currentStamina;
					if (num2 > 0f)
					{
						character.AddStamina(num2);
					}
					data.currentStamina = num;
					character.ClampStamina();
				}
			}
		}

		private const string HungerChallengeId = "hunger";

		private static bool IsHungerEnabled()
		{
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("hunger") && ChallengesAPI.IsChallengeEnabled("hunger"))
			{
				return IsInGameplayScene();
			}
			return false;
		}

		private static bool IsInGameplayScene()
		{
			//IL_0000: 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)
			Scene activeScene = SceneManager.GetActiveScene();
			if (!((Scene)(ref activeScene)).IsValid())
			{
				return false;
			}
			string text = ((Scene)(ref activeScene)).name ?? string.Empty;
			if (string.Equals(text, "WilIsland", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return text.StartsWith("level_", StringComparison.OrdinalIgnoreCase);
		}

		private static Character GetCharacter(Action_RestoreHunger instance)
		{
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			Traverse val = Traverse.Create((object)instance);
			Character value = val.Field("character").GetValue<Character>();
			if ((Object)(object)value != (Object)null)
			{
				return value;
			}
			return val.Property("character", (object[])null).GetValue<Character>();
		}
	}
	[HarmonyPatch(typeof(Character), "RPCA_PassOut")]
	internal static class InstagibPassOutPatch
	{
		private const string InstagibChallengeId = "instagib";

		private const string DieInstantlyMethodName = "DieInstantly";

		private static void Postfix(Character __instance)
		{
			if ((Object)(object)__instance == (Object)null || !ShouldInstagib() || NarcolepsyPatch.ShouldPreventInstagib(__instance))
			{
				return;
			}
			CharacterAfflictions val = __instance.refs?.afflictions;
			if ((Object)(object)val != (Object)null)
			{
				float currentStatus = val.GetCurrentStatus((STATUSTYPE)6);
				if (currentStatus > 0f && val.GetCurrentStatus((STATUSTYPE)0) - currentStatus < 1f)
				{
					return;
				}
			}
			PhotonView photonView = ((MonoBehaviourPun)__instance).photonView;
			if (!((Object)(object)photonView == (Object)null) && photonView.IsMine)
			{
				((MonoBehaviour)__instance).Invoke("DieInstantly", 0.02f);
			}
		}

		private static bool ShouldInstagib()
		{
			Dictionary<string, Challenge> challenges = ChallengesAPI.challenges;
			if (challenges == null)
			{
				return false;
			}
			if (!challenges.ContainsKey("instagib"))
			{
				return false;
			}
			return ChallengesAPI.IsChallengeEnabled("instagib");
		}
	}
	internal static class InversionAfflictionsPatch
	{
		[HarmonyPatch(typeof(CharacterAfflictions), "UpdateNormalStatuses")]
		private static class UpdateNormalStatusesInversion
		{
			[HarmonyPrefix]
			private static bool Prefix(CharacterAfflictions __instance)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return true;
				}
				if (!IsInversionEnabled())
				{
					return true;
				}
				Character character = __instance.character;
				if ((Object)(object)character == (Object)null)
				{
					return true;
				}
				if (!character.IsLocal)
				{
					return false;
				}
				if (Ascents.isNightCold && Object.op_Implicit((Object)(object)Singleton<MountainProgressHandler>.Instance) && Singleton<MountainProgressHandler>.Instance.maxProgressPointReached < 3 && (Object)(object)DayNightManager.instance != (Object)null && DayNightManager.instance.isDay < 0.5f)
				{
					__instance.AddStatus((STATUSTYPE)2, Time.deltaTime * (1f - DayNightManager.instance.isDay) * Ascents.nightColdRate, false);
				}
				if ((Object)(object)character.data != (Object)null && character.data.fullyConscious)
				{
					__instance.AddStatus((STATUSTYPE)1, Time.deltaTime * __instance.hungerPerSecond * Ascents.hungerRateMultiplier, false);
				}
				if (__instance.GetCurrentStatus((STATUSTYPE)3) > 0f && Time.time - __instance.LastAddedStatus((STATUSTYPE)3) > __instance.poisonReductionCooldown)
				{
					__instance.AddStatus((STATUSTYPE)3, __instance.poisonReductionPerSecond * Time.deltaTime, false);
				}
				if (__instance.GetCurrentStatus((STATUSTYPE)6) > 0f && Time.time - __instance.LastAddedStatus((STATUSTYPE)6) > __instance.drowsyReductionCooldown)
				{
					float num = __instance.drowsyReductionPerSecond * Time.deltaTime;
					if (ShouldInvertDrowsy())
					{
						__instance.AddStatus((STATUSTYPE)6, num, false);
					}
					else
					{
						__instance.SubtractStatus((STATUSTYPE)6, num, false);
					}
				}
				if (__instance.GetCurrentStatus((STATUSTYPE)8) > 0f && Time.time - __instance.LastAddedStatus((STATUSTYPE)8) > __instance.hotReductionCooldown)
				{
					__instance.AddStatus((STATUSTYPE)8, __instance.hotReductionPerSecond * Time.deltaTime, false);
				}
				return false;
			}
		}

		private const string InversionChallengeId = "inversion";

		private const string NarcolepsyChallengeId = "narcolepsy";

		private static bool IsInversionEnabled()
		{
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("inversion"))
			{
				return ChallengesAPI.IsChallengeEnabled("inversion");
			}
			return false;
		}

		private static bool ShouldInvertDrowsy()
		{
			if (!ChallengesAPI.IsHell)
			{
				return true;
			}
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("narcolepsy"))
			{
				return !ChallengesAPI.IsChallengeEnabled("narcolepsy");
			}
			return true;
		}
	}
	internal static class NarcolepsyPatch
	{
		[HarmonyPatch(typeof(CharacterAfflictions))]
		[HarmonyPatch("Update")]
		private static class CharacterAfflictionsUpdateNarcolepsy
		{
			[HarmonyPostfix]
			private static void Postfix(CharacterAfflictions __instance)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				if (!IsNarcolepsyEnabled())
				{
					States.Clear();
					return;
				}
				Character character = __instance.character;
				if ((Object)(object)character == (Object)null || character.isBot || !character.IsLocal)
				{
					return;
				}
				PhotonView photonView = ((MonoBehaviourPun)character).photonView;
				if ((Object)(object)photonView == (Object)null || !photonView.IsMine)
				{
					return;
				}
				CharacterData data = character.data;
				bool flag = (Object)(object)data != (Object)null && data.fullyConscious;
				NarcolepsyState orCreateState = GetOrCreateState(((Object)character).GetInstanceID(), flag);
				if (!flag)
				{
					if (orCreateState.WasConscious)
					{
						orCreateState.NextTrigger = Time.time + GetNextIntervalSeconds();
					}
					orCreateState.WasConscious = false;
					return;
				}
				orCreateState.WasConscious = true;
				float time = Time.time;
				if (!(time < orCreateState.NextTrigger))
				{
					float currentStatus = __instance.GetCurrentStatus((STATUSTYPE)0);
					float num = Mathf.Max(0f, 1f - currentStatus);
					float currentStatus2 = __instance.GetCurrentStatus((STATUSTYPE)7);
					float num2 = num + currentStatus2 + 0.1f;
					if (num2 > 0f)
					{
						__instance.AddStatus((STATUSTYPE)6, num2, false);
					}
					photonView.RPC("RPCA_PassOut", (RpcTarget)0, Array.Empty<object>());
					orCreateState.InstagibGraceUntil = time + 1f;
					orCreateState.NextTrigger = time + GetNextIntervalSeconds();
				}
			}
		}

		private sealed class NarcolepsyState
		{
			public float NextTrigger;

			public bool WasConscious;

			public float InstagibGraceUntil;
		}

		private const string NarcolepsyChallengeId = "narcolepsy";

		private const float MinIntervalSeconds = 60f;

		private const float MaxIntervalSeconds = 180f;

		private const float InstagibGracePeriod = 1f;

		private static readonly Dictionary<int, NarcolepsyState> States = new Dictionary<int, NarcolepsyState>();

		private static bool IsNarcolepsyEnabled()
		{
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("narcolepsy"))
			{
				return ChallengesAPI.IsChallengeEnabled("narcolepsy");
			}
			return false;
		}

		private static float GetNextIntervalSeconds()
		{
			return Random.Range(60f, 180f);
		}

		private static NarcolepsyState GetOrCreateState(int key, bool isConscious)
		{
			if (!States.TryGetValue(key, out var value))
			{
				value = new NarcolepsyState
				{
					NextTrigger = Time.time + GetNextIntervalSeconds(),
					WasConscious = isConscious
				};
				States[key] = value;
			}
			return value;
		}

		internal static bool ShouldPreventInstagib(Character character)
		{
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			if (!IsNarcolepsyEnabled())
			{
				return false;
			}
			int instanceID = ((Object)character).GetInstanceID();
			if (!States.TryGetValue(instanceID, out var value))
			{
				return false;
			}
			return Time.time <= value.InstagibGraceUntil;
		}
	}
	internal static class PlaneCrashPatch
	{
		[HarmonyPatch(typeof(CharacterAfflictions))]
		[HarmonyPatch("Update")]
		private static class CharacterAfflictionsUpdatePlaneCrash
		{
			[HarmonyPostfix]
			private static void Postfix(CharacterAfflictions __instance)
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				EnsureInitialized();
				if (!IsPlaneCrashEnabled())
				{
					AppliedCharacters.Clear();
					return;
				}
				Character character = __instance.character;
				if ((Object)(object)character == (Object)null || character.isBot || !character.IsLocal)
				{
					return;
				}
				PhotonView photonView = ((MonoBehaviourPun)character).photonView;
				if ((Object)(object)photonView == (Object)null || !photonView.IsMine)
				{
					return;
				}
				Scene activeScene = SceneManager.GetActiveScene();
				if (!((Scene)(ref activeScene)).IsValid() || !string.Equals(((Scene)(ref activeScene)).name ?? string.Empty, "Airport", StringComparison.OrdinalIgnoreCase))
				{
					int instanceID = ((Object)character).GetInstanceID();
					if (!AppliedCharacters.Contains(instanceID))
					{
						__instance.SetStatus((STATUSTYPE)0, 0.9f);
						AppliedCharacters.Add(instanceID);
					}
				}
			}
		}

		private const string PlaneCrashChallengeId = "planecrash";

		private const float InjuryAmount = 0.9f;

		private static readonly HashSet<int> AppliedCharacters = new HashSet<int>();

		private static bool _initialized;

		private static bool IsPlaneCrashEnabled()
		{
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("planecrash"))
			{
				return ChallengesAPI.IsChallengeEnabled("planecrash");
			}
			return false;
		}

		private static void EnsureInitialized()
		{
			if (!_initialized)
			{
				ChallengesAPI.SceneLoaded += HandleSceneLoaded;
				_initialized = true;
			}
		}

		private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			AppliedCharacters.Clear();
		}
	}
	internal static class ScoutmasterLurksPatch
	{
		[HarmonyPatch(typeof(Scoutmaster), "LookForTarget")]
		private static class ScoutmasterLookForTarget
		{
			[HarmonyPrefix]
			private static bool Prefix(Scoutmaster __instance)
			{
				if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
				{
					return true;
				}
				if (SinceLookForTargetField == null || CharacterField == null)
				{
					return true;
				}
				if (!(SinceLookForTargetField.GetValue(__instance) is float num))
				{
					return true;
				}
				bool flag = IsNight();
				if (!flag && num < 30f)
				{
					return false;
				}
				SinceLookForTargetField.SetValue(__instance, 0f);
				if (!flag)
				{
					SetCurrentTarget(__instance, null, 0f);
					return false;
				}
				Character scoutmasterCharacter = GetScoutmasterCharacter(__instance);
				if ((Object)(object)scoutmasterCharacter == (Object)null)
				{
					SetCurrentTarget(__instance, null, 0f);
					return false;
				}
				Character closestLivingPlayer = GetClosestLivingPlayer(scoutmasterCharacter);
				if (!IsValidTarget(closestLivingPlayer))
				{
					SetCurrentTarget(__instance, null, 0f);
					return false;
				}
				SetCurrentTarget(__instance, closestLivingPlayer, 0f);
				return false;
			}
		}

		[HarmonyPatch(typeof(Scoutmaster), "VerifyTarget")]
		private static class ScoutmasterVerifyTarget
		{
			[HarmonyPrefix]
			private static bool Prefix(Scoutmaster __instance)
			{
				if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
				{
					return true;
				}
				Character scoutmasterCharacter = GetScoutmasterCharacter(__instance);
				if ((Object)(object)scoutmasterCharacter == (Object)null)
				{
					return true;
				}
				Character val = __instance.currentTarget;
				if (!IsValidTarget(val))
				{
					val = null;
				}
				Character closestLivingPlayer = GetClosestLivingPlayer(scoutmasterCharacter);
				if (!IsValidTarget(closestLivingPlayer))
				{
					if ((Object)(object)val != (Object)null)
					{
						SetCurrentTarget(__instance, null, 0f);
					}
					return false;
				}
				if ((Object)(object)val != (Object)(object)closestLivingPlayer)
				{
					SetCurrentTarget(__instance, closestLivingPlayer, 0f);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Scoutmaster), "Update")]
		private static class ScoutmasterUpdate
		{
			[HarmonyPostfix]
			private static void Postfix(Scoutmaster __instance)
			{
				if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				if (!((Object)(object)component != (Object)null) || component.IsMine)
				{
					int instanceID = ((Object)__instance).GetInstanceID();
					if (IsNight())
					{
						LeftForDay.Remove(instanceID);
					}
					else if (LeftForDay.Add(instanceID))
					{
						SetCurrentTarget(__instance, null, 0f);
						ForceTeleportAway(__instance);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Scoutmaster), "Chase")]
		private static class ScoutmasterChase
		{
			[HarmonyPostfix]
			private static void Postfix(Scoutmaster __instance)
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && !component.IsMine)
				{
					return;
				}
				Character scoutmasterCharacter = GetScoutmasterCharacter(__instance);
				Character currentTarget = __instance.currentTarget;
				if (!IsValidTarget(currentTarget) || (Object)(object)scoutmasterCharacter == (Object)null)
				{
					return;
				}
				float num = Vector3.Distance(scoutmasterCharacter.Center, currentTarget.Center);
				float num2 = 0f;
				if (TargetHasSeenCounterField != null)
				{
					num2 = (float)TargetHasSeenCounterField.GetValue(__instance);
				}
				if (!(num2 >= 0.5f) && !(num < 18f))
				{
					float num3 = Mathf.Clamp((num - 4f) / 12f, 0f, 1f);
					if (num < 12f)
					{
						num3 = Mathf.Clamp((num - 10f) / 8f, -0.2f, 0.25f);
					}
					scoutmasterCharacter.input.movementInput = new Vector2(0f, num3);
					bool useSecondaryIsPressed = num < 3.5f && num2 > 0.2f;
					scoutmasterCharacter.input.useSecondaryIsPressed = useSecondaryIsPressed;
					if (num < 8f && ChillForSecondsField != null && (float)ChillForSecondsField.GetValue(__instance) < 0.75f)
					{
						ChillForSecondsField.SetValue(__instance, 0.75f);
					}
				}
			}
		}

		private const string ChallengeId = "scoutmasterlurks";

		private static readonly FieldInfo SinceLookForTargetField = AccessTools.Field(typeof(Scoutmaster), "sinceLookForTarget");

		private static readonly FieldInfo CharacterField = AccessTools.Field(typeof(Scoutmaster), "character");

		private static readonly MethodInfo SetCurrentTargetMethod = AccessTools.Method(typeof(Scoutmaster), "SetCurrentTarget", (Type[])null, (Type[])null);

		private static readonly FieldInfo ChillForSecondsField = AccessTools.Field(typeof(Scoutmaster), "chillForSeconds");

		private static readonly FieldInfo TpCounterField = AccessTools.Field(typeof(Scoutmaster), "tpCounter");

		private static readonly FieldInfo TargetHasSeenCounterField = AccessTools.Field(typeof(Scoutmaster), "targetHasSeenMeCounter");

		private static readonly HashSet<int> LeftForDay = new HashSet<int>();

		private static bool IsChallengeEnabled()
		{
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("scoutmasterlurks"))
			{
				return ChallengesAPI.IsChallengeEnabled("scoutmasterlurks");
			}
			return false;
		}

		private static Character GetScoutmasterCharacter(Scoutmaster scoutmaster)
		{
			if ((Object)(object)scoutmaster == (Object)null)
			{
				return null;
			}
			object? obj = CharacterField?.GetValue(scoutmaster);
			Character val = (Character)((obj is Character) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			return ((Component)scoutmaster).GetComponent<Character>();
		}

		private static bool IsNight()
		{
			if ((Object)(object)DayNightManager.instance != (Object)null)
			{
				return DayNightManager.instance.isDay < 0.5f;
			}
			return false;
		}

		private static bool IsValidTarget(Character character)
		{
			if ((Object)(object)character == (Object)null || character.isBot)
			{
				return false;
			}
			CharacterData data = character.data;
			if ((Object)(object)data == (Object)null || data.dead || data.fullyPassedOut)
			{
				return false;
			}
			return true;
		}

		private static Character GetClosestLivingPlayer(Character scoutmasterCharacter)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			if ((Object)(object)scoutmasterCharacter == (Object)null)
			{
				return null;
			}
			Character result = null;
			float num = float.MaxValue;
			Vector3 center = scoutmasterCharacter.Center;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (IsValidTarget(allCharacter) && !((Object)(object)allCharacter == (Object)(object)scoutmasterCharacter))
				{
					float num2 = Vector3.Distance(center, allCharacter.Center);
					if (num2 < num)
					{
						num = num2;
						result = allCharacter;
					}
				}
			}
			return result;
		}

		private static void SetCurrentTarget(Scoutmaster scoutmaster, Character target, float force)
		{
			if (!((Object)(object)scoutmaster == (Object)null) && !(SetCurrentTargetMethod == null))
			{
				SetCurrentTargetMethod.Invoke(scoutmaster, new object[2] { target, force });
			}
		}

		private static void ForceTeleportAway(Scoutmaster scoutmaster)
		{
			//IL_0020: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)scoutmaster == (Object)null)
			{
				return;
			}
			Character scoutmasterCharacter = GetScoutmasterCharacter(scoutmaster);
			if ((Object)(object)scoutmasterCharacter != (Object)null)
			{
				Vector3 position = ((Component)scoutmasterCharacter).transform.position;
				if (position.z > 4900f && Mathf.Abs(position.x) < 20f && Mathf.Abs(position.y) < 20f)
				{
					return;
				}
			}
			if (TpCounterField != null)
			{
				TpCounterField.SetValue(scoutmaster, 0f);
			}
			if (ChillForSecondsField != null)
			{
				ChillForSecondsField.SetValue(scoutmaster, 5f);
			}
			scoutmaster.TeleportFarAway();
		}
	}
	public static class SnowPatch
	{
		private class FrostbiteWindController : MonoBehaviour
		{
			private static readonly Vector2 ForcedOnRange = new Vector2(999999f, 999999f);

			private static readonly Vector2 ForcedOffRange = Vector2.zero;

			private static readonly MethodInfo ToggleWind = typeof(WindChillZone).GetMethod("RPCA_ToggleWind", BindingFlags.Instance | BindingFlags.NonPublic);

			private static readonly MethodInfo RandomWind = typeof(WindChillZone).GetMethod("RandomWindDirection", BindingFlags.Instance | BindingFlags.NonPublic);

			private WindChillZone _zone;

			private PhotonView _view;

			private float _retryTimer;

			private void Awake()
			{
				_zone = ((Component)this).GetComponent<WindChillZone>();
				_view = ((Component)this).GetComponent<PhotonView>();
			}

			private void OnEnable()
			{
				EnsureStorm(forceRpc: true);
			}

			private void Update()
			{
				EnsureStorm();
			}

			private void EnsureStorm(bool forceRpc = false)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_zone == (Object)null)
				{
					((Behaviour)this).enabled = false;
					return;
				}
				_zone.windTimeRangeOn = ForcedOnRange;
				_zone.windTimeRangeOff = ForcedOffRange;
				if (_zone.windActive && !forceRpc)
				{
					MaintainSwitchTimer();
				}
				else
				{
					TryActivateStorm();
				}
			}

			private void MaintainSwitchTimer()
			{
				if (PhotonNetwork.IsMasterClient)
				{
					_retryTimer -= Time.deltaTime;
					if (!(_retryTimer > 0f))
					{
						_retryTimer = 30f;
						TryActivateStorm();
					}
				}
			}

			private void TryActivateStorm()
			{
				//IL_0000: 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_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = Vector3.forward;
				if (RandomWind != null)
				{
					try
					{
						val = (Vector3)RandomWind.Invoke(_zone, null);
					}
					catch
					{
					}
				}
				if (PhotonNetwork.IsMasterClient && (Object)(object)_view != (Object)null)
				{
					_view.RPC("RPCA_ToggleWind", (RpcTarget)0, new object[2] { true, val });
				}
				else
				{
					ToggleWind?.Invoke(_zone, new object[2] { true, val });
				}
			}
		}

		private const string FrostbiteId = "permasnow";

		private const float ForcedStormDuration = 999999f;

		private static bool _initialized;

		public static void Init()
		{
			if (!_initialized)
			{
				_initialized = true;
				ChallengesAPI.SceneLoaded += HandleSceneLoaded;
			}
		}

		private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (IsFrostbiteEnabled() && IsGameplayScene(scene))
			{
				ApplyStorm(scene);
			}
		}

		private static bool IsGameplayScene(Scene scene)
		{
			if (!((Scene)(ref scene)).IsValid())
			{
				return false;
			}
			string text = ((Scene)(ref scene)).name ?? string.Empty;
			if (!(text == "WilIsland"))
			{
				return text.StartsWith("level_", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool IsFrostbiteEnabled()
		{
			if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("permasnow"))
			{
				return ChallengesAPI.IsChallengeEnabled("permasnow");
			}
			return false;
		}

		private static void ApplyStorm(Scene scene)
		{
			//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)
			WindChillZone[] array = FindWindChillZones();
			if (array == null || array.Length == 0)
			{
				return;
			}
			foreach (WindChillZone val in array)
			{
				if (!((Object)(object)val == (Object)null) && !(((Component)val).gameObject.scene != scene))
				{
					AttachController(val);
				}
			}
		}

		private static WindChillZone[] FindWindChillZones()
		{
			try
			{
				return Object.FindObjectsOfType<WindChillZone>(true);
			}
			catch
			{
				return Object.FindObjectsOfType<WindChillZone>();
			}
		}

		private static void AttachController(WindChillZone zone)
		{
			if (!((Object)(object)((Component)zone).gameObject.GetComponent<FrostbiteWindController>() != (Object)null))
			{
				((Component)zone).gameObject.AddComponent<FrostbiteWindController>();
			}
		}
	}
}