Decompiled source of Lopis Parkour v1.0.5

LopisParkour.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using InControl;
using MapsExt;
using MapsExt.Compatibility;
using MapsExt.Editor.MapObjects;
using MapsExt.Editor.Properties;
using MapsExt.Editor.UI;
using MapsExt.MapObjects;
using MapsExt.Properties;
using Microsoft.CodeAnalysis;
using On;
using Photon.Pun;
using Sirenix.Serialization;
using Sonigon;
using SoundImplementation;
using Steamworks;
using TMPro;
using UnboundLib;
using UnboundLib.GameModes;
using UnboundLib.Utils;
using UnboundLib.Utils.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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-CSharp")]
[assembly: IgnoresAccessChecksTo("MapsExtended")]
[assembly: IgnoresAccessChecksTo("UnboundLib")]
[assembly: AssemblyCompany("LopisParkour")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LopisParkour")]
[assembly: AssemblyTitle("LopisParkour")]
[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.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;
		}
	}
	[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 LopisParkourNS
{
	public class GM_Parkour : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<string, bool> <>9__30_0;

			public static Func<KeyValuePair<string, CustomMap>, int> <>9__30_2;

			public static Comparison<int> <>9__30_3;

			public static Predicate<KeyValuePair<string, CustomMap>> <>9__30_4;

			public static Func<MapObjectData, bool> <>9__34_0;

			public static Func<MapObjectData, bool> <>9__35_0;

			public static UnityAction <>9__37_0;

			public static Func<MapObjectData, bool> <>9__38_0;

			internal bool <getNextMap>b__30_0(string directory)
			{
				return instance._selectedMap.id.Contains(directory);
			}

			internal int <getNextMap>b__30_2(KeyValuePair<string, CustomMap> f)
			{
				if (int.TryParse(Regex.Split(f.Value._name.Remove(0, 4), "_")[0], out var result))
				{
					return result;
				}
				return f.Value._name.Remove(0, 4)[0];
			}

			internal int <getNextMap>b__30_3(int x, int y)
			{
				return (x > y) ? 1 : ((x < y) ? (-1) : 0);
			}

			internal bool <getNextMap>b__30_4(KeyValuePair<string, CustomMap> p)
			{
				return p.Value == instance._selectedMap;
			}

			internal bool <WhatMedalIsIt>b__34_0(MapObjectData mod)
			{
				return (ValueProperty<float>)mod.GetProperty<GoldMedalProperty>() != (ValueProperty<float>)null;
			}

			internal bool <TimeFromMedal>b__35_0(MapObjectData mod)
			{
				return (ValueProperty<float>)mod.GetProperty<GoldMedalProperty>() != (ValueProperty<float>)null;
			}

			internal void <OpenParkourWinMenu>b__37_0()
			{
				TimeHandler.instance.gameOverTime = 1f;
				MainMenuHandler.instance.Close();
				GM_Parkour gM_Parkour = (GM_Parkour)(object)GameModeManager.CurrentHandler.GameMode;
				gM_Parkour.reloadMap();
			}

			internal bool <WinMenuShowLeaderboard>b__38_0(MapObjectData mod)
			{
				return (ValueProperty<float>)mod.GetProperty<GoldMedalProperty>() != (ValueProperty<float>)null;
			}
		}

		public static GM_Parkour instance;

		public CustomMap _selectedMap;

		public bool isTransitioning = false;

		public static GhostReplayRecorder ghostRecorder = null;

		public static GhostReplayPlayer ghostPlayer = null;

		public bool isEnding = false;

		public static float timePassed = 0f;

		public static bool timerStop = false;

		public static GameObject pauseNextMapButton;

		public static GameObject pauseGhostEnabledButton;

		public static bool ghostEnabled = true;

		public static TextMeshProUGUI LeaderboardText;

		public static TextMeshProUGUI pauseLeaderboardText;

		public static TextMeshProUGUI pauseTimeText;

		public static TextMeshProUGUI pauseCurrentMapText;

		public CustomMap selectedMap
		{
			get
			{
				return _selectedMap;
			}
			set
			{
				if (_selectedMap != value)
				{
					_selectedMap = value;
					if (GameManager.instance.isPlaying)
					{
						reloadMap();
					}
				}
			}
		}

		private void Awake()
		{
			instance = this;
		}

		private void Start()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			LopisParkour.Log("Start");
			((Component)((Component)this).transform.root).GetComponent<SetOfflineMode>().SetOffline();
			instance.isEnding = false;
			pauseGhostEnabledButton = MenuHandler.CreateButton("GhostToggle", LopisParkour.pauseMenu, new UnityAction(pauseGhostToggle), 60, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			pauseGhostEnabledButton.transform.SetAsFirstSibling();
			GameObject obj = pauseGhostEnabledButton;
			TextMeshProUGUI val = ((obj != null) ? obj.GetComponentInChildren<TextMeshProUGUI>() : null);
			if ((Object)(object)val != (Object)null)
			{
				((TMP_Text)val).text = "Ghost: " + (ghostEnabled ? "On" : "Off");
			}
			if ((Object)(object)ghostPlayer != (Object)null)
			{
				((Behaviour)ghostPlayer).enabled = ghostEnabled;
			}
			MenuHandler.CreateButton("Reload map [R]", LopisParkour.pauseMenu, new UnityAction(reloadMap), 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null).transform.SetAsFirstSibling();
			pauseNextMapButton = MenuHandler.CreateButton("Next map", LopisParkour.pauseMenu, new UnityAction(pauseNextMapAction), 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			pauseNextMapButton.transform.SetAsFirstSibling();
			MenuHandler.CreateText("", LopisParkour.pauseMenu, ref pauseTimeText, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null).transform.SetAsFirstSibling();
			MenuHandler.CreateText("", LopisParkour.pauseMenu, ref pauseCurrentMapText, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null).transform.SetAsFirstSibling();
			LoadSelectedMap();
			PlayerAssigner.instance.SetPlayersCanJoin(true);
			TimeHandler.instance.StartGame();
			PlayerManager val2 = PlayerManager.instance;
			val2.PlayerJoinedAction = (Action<Player>)Delegate.Combine(val2.PlayerJoinedAction, new Action<Player>(PlayerWasAdded));
			PlayerManager.instance.AddPlayerDiedAction((Action<Player, int>)PlayerDied);
			GameManager.instance.isPlaying = true;
			GameManager.instance.battleOngoing = true;
			CameraHandler component = ((Component)((Component)MainCam.instance.cam).GetComponentInParent<CameraZoomHandler>()).gameObject.GetComponent<CameraHandler>();
			component._playersHaveSpawned = true;
			ghostRecorder = ExtensionMethods.GetOrAddComponent<GhostReplayRecorder>(((Component)this).gameObject, false);
			GlobalLeaderboard.onLeaderboardFinishedDownload = (Action)Delegate.Combine(GlobalLeaderboard.onLeaderboardFinishedDownload, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardStartedDownload = (Action)Delegate.Combine(GlobalLeaderboard.onLeaderboardStartedDownload, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardSubmittionStart = (Action)Delegate.Combine(GlobalLeaderboard.onLeaderboardSubmittionStart, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardFail = (Action)Delegate.Combine(GlobalLeaderboard.onLeaderboardFail, new Action(FailedToLoadLeaderboard));
		}

		public static void FailedToLoadLeaderboard()
		{
			if ((Object)(object)LeaderboardText != (Object)null)
			{
				((TMP_Text)LeaderboardText).text = "Leaderboard\nfailed to load";
			}
		}

		public static IEnumerator EndCoroutine()
		{
			if (instance.isEnding)
			{
				yield return null;
			}
			instance.isEnding = true;
			GlobalLeaderboard.onLeaderboardFinishedDownload = (Action)Delegate.Remove(GlobalLeaderboard.onLeaderboardFinishedDownload, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardStartedDownload = (Action)Delegate.Remove(GlobalLeaderboard.onLeaderboardStartedDownload, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardSubmittionStart = (Action)Delegate.Remove(GlobalLeaderboard.onLeaderboardSubmittionStart, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardFail = (Action)Delegate.Remove(GlobalLeaderboard.onLeaderboardFail, new Action(FailedToLoadLeaderboard));
			CameraHandler camera = ((Component)((Component)MainCam.instance.cam).GetComponentInParent<CameraZoomHandler>()).gameObject.GetComponent<CameraHandler>();
			camera._playersHaveSpawned = false;
			GameManager.instance.isPlaying = false;
			GameManager.instance.battleOngoing = false;
			AsyncOperation op = SceneManager.UnloadSceneAsync("MapsExtended:" + instance.selectedMap._id);
			MapManager.instance.currentMap = null;
			CameraHandler.Mode = (CameraMode)1;
			while (!op.isDone)
			{
				yield return null;
			}
			PlayerAssigner.instance.SetPlayersCanJoin(false);
			GameObject.Find("Game/UI/UI_MainMenu").gameObject.SetActive(true);
			GameObject.Find("Game").GetComponent<SetOfflineMode>().SetOnline();
			LopisParkour.Log("End");
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)114) && !DevConsole.isTyping)
			{
				TimeHandler.instance.gameOverTime = 1f;
				reloadMap();
				if (MainMenuHandler.instance.isOpen)
				{
					MainMenuHandler.instance.Close();
				}
			}
			if (PlayerManager.instance.players.Count != 0)
			{
				if (!timerStop && !EscapeMenuHandler.isEscMenu)
				{
					timePassed += Time.deltaTime;
				}
			}
			else
			{
				timePassed = 0f;
			}
			pauseMenuUpdate();
		}

		public void OnDestroy()
		{
			GlobalLeaderboard.onLeaderboardFinishedDownload = (Action)Delegate.Remove(GlobalLeaderboard.onLeaderboardFinishedDownload, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardStartedDownload = (Action)Delegate.Remove(GlobalLeaderboard.onLeaderboardStartedDownload, new Action(WinMenuShowLeaderboard));
			GlobalLeaderboard.onLeaderboardSubmittionStart = (Action)Delegate.Remove(GlobalLeaderboard.onLeaderboardSubmittionStart, new Action(WinMenuShowLeaderboard));
		}

		public void reloadMap()
		{
			if (isTransitioning)
			{
				return;
			}
			MapTransition.isTransitioning = true;
			foreach (GameObject spawnedCard in CardChoice.instance.spawnedCards)
			{
				Object.Destroy((Object)(object)spawnedCard);
			}
			CardChoice.instance.spawnedCards.Clear();
			LoadSelectedMap();
			PlayerManager.instance.RemovePlayers();
			timerStop = false;
			TimeHandler.instance.gameOverTime = 1f;
			ghostRecorder?.Reset();
			ghostPlayer?.RepaintTheGhost();
			MapTransition.isTransitioning = true;
		}

		public void MapWon()
		{
			timerStop = true;
			GlobalLeaderboard.RequestUpdate();
			if (!instance._selectedMap.id.StartsWith(Paths.GameRootPath))
			{
				GlobalLeaderboard.AddRecord(LopisParkour.pathToId(selectedMap.id), timePassed);
				WinMenuShowLeaderboard();
				CheckPBGhost();
			}
			((MonoBehaviour)this).StartCoroutine(MapWonCorutine());
		}

		public void CheckPBGhost()
		{
			ParkourProgressEntry parkourProgressEntry = LopisParkour.GetRecord(instance.selectedMap.id) ?? new ParkourProgressEntry();
			if (timePassed != 0f && (!(parkourProgressEntry.time > 0f) || !(parkourProgressEntry.time <= timePassed)))
			{
				ghostRecorder.SaveReplay(LopisParkour.pathToId(instance._selectedMap.id).Replace('\\', '_') + "PB");
			}
		}

		public void pauseMenuUpdate()
		{
			if ((Object)(object)pauseTimeText != (Object)null)
			{
				((TMP_Text)pauseTimeText).text = ((timePassed == 0f) ? "Jump to spawn in" : TimeSpan.FromSeconds(timePassed).ToString("mm\\:ss\\.fff"));
			}
		}

		public void pauseNextMapButtonUpdate()
		{
			CustomMap nextMap = getNextMap();
			GameObject obj = pauseNextMapButton;
			TextMeshProUGUI val = ((obj != null) ? obj.GetComponentInChildren<TextMeshProUGUI>() : null);
			if ((Object)(object)val != (Object)null)
			{
				((TMP_Text)val).text = ((nextMap == null) ? "No next map" : ("Next map (" + mapToName(nextMap) + ")"));
			}
			if ((Object)(object)pauseCurrentMapText != (Object)null)
			{
				((TMP_Text)pauseCurrentMapText).text = "Current map: " + mapToName(_selectedMap);
			}
		}

		public static string mapToName(CustomMap map)
		{
			return map._name.Remove(0, 4).Replace("_", " ");
		}

		public static CustomMap? getNextMap()
		{
			string directory2 = LopisParkour.mapsHierarchy.FirstOrDefault((string directory) => instance._selectedMap.id.Contains(directory));
			LopisParkour.Log(directory2);
			LopisParkour.Log(instance._selectedMap.id);
			int result;
			List<KeyValuePair<string, CustomMap>> list = (from map in LopisParkour.maps.AsEnumerable()
				where directory2 == null || map.Key.Contains(directory2)
				select map).OrderBy((KeyValuePair<string, CustomMap> f) => int.TryParse(Regex.Split(f.Value._name.Remove(0, 4), "_")[0], out result) ? result : f.Value._name.Remove(0, 4)[0], Comparer<int>.Create((int x, int y) => (x > y) ? 1 : ((x < y) ? (-1) : 0))).ToList();
			int num = list.FindIndex((KeyValuePair<string, CustomMap> p) => p.Value == instance._selectedMap);
			if (num != -1 && num < list.Count - 1)
			{
				return list[num + 1].Value;
			}
			return null;
		}

		public void pauseGhostToggle()
		{
			ghostEnabled = !ghostEnabled;
			GameObject obj = pauseGhostEnabledButton;
			TextMeshProUGUI val = ((obj != null) ? obj.GetComponentInChildren<TextMeshProUGUI>() : null);
			if ((Object)(object)val != (Object)null)
			{
				((TMP_Text)val).text = "Ghost: " + (ghostEnabled ? "On" : "Off");
			}
			((Behaviour)ghostPlayer).enabled = ghostEnabled;
		}

		public void pauseNextMapAction()
		{
			CustomMap nextMap = getNextMap();
			if (nextMap != null)
			{
				TimeHandler.instance.gameOverTime = 1f;
				MainMenuHandler.instance.Close();
				instance.selectedMap = nextMap;
			}
		}

		public IEnumerator MapWonCorutine()
		{
			isTransitioning = true;
			TimeHandler.instance.DoSlowDown();
			yield return (object)new WaitForSecondsRealtime(0.25f);
			isTransitioning = false;
			OpenParkourWinMenu();
			MapTransition.instance.Exit(MapManager.instance.currentMap.Map);
			PlayerManager.instance.RemovePlayers();
			PlayerManager.instance.ResetCharacters();
		}

		public static MedalType WhatMedalIsIt(float time)
		{
			MapObjectData val = ((IEnumerable<MapObjectData>)instance.selectedMap.MapObjects).FirstOrDefault((Func<MapObjectData, bool>)((MapObjectData mod) => (ValueProperty<float>)mod.GetProperty<GoldMedalProperty>() != (ValueProperty<float>)null));
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			if (val != null)
			{
				num = ((ValueProperty<float>)val.GetProperty<BronzeMedalProperty>())?.Value ?? 0f;
				num2 = ((ValueProperty<float>)val.GetProperty<SilverMedalProperty>())?.Value ?? 0f;
				num3 = ((ValueProperty<float>)val.GetProperty<GoldMedalProperty>())?.Value ?? 0f;
				num4 = ((ValueProperty<float>)val.GetProperty<ShinyMedalProperty>())?.Value ?? 0f;
			}
			return (!(time >= num)) ? ((time >= num2) ? MedalType.Bronze : ((time >= num3) ? MedalType.Silver : ((time >= num4) ? MedalType.Golden : MedalType.Shiny))) : MedalType.None;
		}

		public static float TimeFromMedal(MedalType medal)
		{
			MapObjectData val = ((IEnumerable<MapObjectData>)instance.selectedMap.MapObjects).FirstOrDefault((Func<MapObjectData, bool>)((MapObjectData mod) => (ValueProperty<float>)mod.GetProperty<GoldMedalProperty>() != (ValueProperty<float>)null));
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			if (val != null)
			{
				num = ((ValueProperty<float>)val.GetProperty<BronzeMedalProperty>())?.Value ?? 0f;
				num2 = ((ValueProperty<float>)val.GetProperty<SilverMedalProperty>())?.Value ?? 0f;
				num3 = ((ValueProperty<float>)val.GetProperty<GoldMedalProperty>())?.Value ?? 0f;
				num4 = ((ValueProperty<float>)val.GetProperty<ShinyMedalProperty>())?.Value ?? 0f;
			}
			return medal switch
			{
				MedalType.None => float.PositiveInfinity, 
				MedalType.Bronze => num, 
				MedalType.Silver => num2, 
				MedalType.Golden => num3, 
				MedalType.Shiny => num4, 
				_ => 0f, 
			};
		}

		public static string RichTextMedalColor(MedalType medal, string text)
		{
			return medal switch
			{
				MedalType.None => text, 
				MedalType.Bronze => "<color=#950f>" + text + "</color>", 
				MedalType.Silver => "<color=#99Cf>" + text + "</color>", 
				MedalType.Golden => "<color=#DFDF00ff>" + text + "</color>", 
				MedalType.Shiny => "<color=#FFFF00ff>" + text + "</color>", 
				_ => text, 
			};
		}

		public static void OpenParkourWinMenu()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bd: Expected O, but got Unknown
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Expected O, but got Unknown
			GameObject val = GameObject.Find("/Game/UI/UI_MainMenu/Canvas/ListSelector/Main/Group");
			val.transform.position = new Vector3(0f, 0f, 0f);
			if ((Object)(object)LopisParkour.parkourWinMenu == (Object)null)
			{
				return;
			}
			MainMenuHandler.instance.Open();
			LopisParkour.parkourWinMenu.GetComponent<ListMenuPage>().Open();
			LopisParkour.parkourWinMenu.GetComponentInChildren<ScrollRect>().verticalNormalizedPosition = 1f;
			Transform val2 = LopisParkour.parkourWinMenu.transform.Find("Group/Grid/Scroll View/Viewport/Content");
			if (Object.op_Implicit((Object)(object)val2))
			{
				foreach (Transform item in val2)
				{
					Transform val3 = item;
					Object.Destroy((Object)(object)((Component)val3).gameObject);
				}
			}
			ParkourProgressEntry parkourProgressEntry = LopisParkour.GetRecord(instance.selectedMap.id) ?? new ParkourProgressEntry();
			MedalType medalType = WhatMedalIsIt(timePassed);
			TextMeshProUGUI val4 = default(TextMeshProUGUI);
			MenuHandler.CreateText(mapToName(instance.selectedMap), LopisParkour.parkourWinMenu, ref val4, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			if ((parkourProgressEntry.time == -1f || parkourProgressEntry.time > timePassed) && timePassed != 0f)
			{
				if (parkourProgressEntry.medal < medalType)
				{
					MenuHandler.CreateText(RichTextMedalColor(medalType, medalType.ToString() + " Medal!"), LopisParkour.parkourWinMenu, ref val4, 100, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				}
				else
				{
					MenuHandler.CreateText(RichTextMedalColor(medalType, "Personal Best!"), LopisParkour.parkourWinMenu, ref val4, 100, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
				}
				SoundPlayerStatic.Instance.PlayMatchFound();
				LopisParkour.AddRecord(instance.selectedMap.id, timePassed, medalType);
			}
			else
			{
				MenuHandler.CreateText(" ", LopisParkour.parkourWinMenu, ref val4, 100, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			TextMeshProUGUI val5 = default(TextMeshProUGUI);
			if (timePassed != 0f)
			{
				MenuHandler.CreateText(RichTextMedalColor(medalType, TimeSpan.FromSeconds(timePassed).ToString("mm\\:ss\\.fff")), LopisParkour.parkourWinMenu, ref val5, 80, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			else
			{
				MenuHandler.CreateText(TimeSpan.FromSeconds(timePassed).ToString("mm\\:ss\\.fff") + "(sorry, timer broke, it's a bug)", LopisParkour.parkourWinMenu, ref val5, 80, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			TextMeshProUGUI val6 = default(TextMeshProUGUI);
			if (parkourProgressEntry.time == -1f)
			{
				MenuHandler.CreateText(" ", LopisParkour.parkourWinMenu, ref val6, 40, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			else
			{
				MenuHandler.CreateText((((parkourProgressEntry.time == -1f || parkourProgressEntry.time > timePassed) && timePassed != 0f) ? "previously: " : "pb: ") + TimeSpan.FromSeconds(parkourProgressEntry.time).ToString("mm\\:ss\\.fff") + " (" + ((timePassed < parkourProgressEntry.time) ? "-" : "+") + TimeSpan.FromSeconds(timePassed - parkourProgressEntry.time).ToString("mm\\:ss\\.fff") + ")", LopisParkour.parkourWinMenu, ref val6, 40, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			float num = ((parkourProgressEntry.time == -1f) ? timePassed : Mathf.Min(timePassed, parkourProgressEntry.time));
			MedalType medalType2 = (MedalType)((int)(medalType + 1) % Enum.GetValues(typeof(MedalType)).Length);
			float num2 = TimeFromMedal(medalType2);
			TextMeshProUGUI val7 = default(TextMeshProUGUI);
			if (medalType2 != 0 && medalType2 != MedalType.Shiny)
			{
				MenuHandler.CreateText("next medal: " + medalType2.ToString() + " " + TimeSpan.FromSeconds(num2).ToString("mm\\:ss\\.fff") + " (" + ((timePassed < num2) ? "-" : "+") + TimeSpan.FromSeconds(timePassed - num2).ToString("mm\\:ss\\.fff") + ")", LopisParkour.parkourWinMenu, ref val7, 40, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			else if (medalType2 == MedalType.None)
			{
				MenuHandler.CreateText("No medals left to get", LopisParkour.parkourWinMenu, ref val7, 40, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			else
			{
				MenuHandler.CreateText(" ", LopisParkour.parkourWinMenu, ref val7, 40, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			}
			GameObject parkourWinMenu = LopisParkour.parkourWinMenu;
			object obj = <>c.<>9__37_0;
			if (obj == null)
			{
				UnityAction val8 = delegate
				{
					TimeHandler.instance.gameOverTime = 1f;
					MainMenuHandler.instance.Close();
					GM_Parkour gM_Parkour = (GM_Parkour)(object)GameModeManager.CurrentHandler.GameMode;
					gM_Parkour.reloadMap();
				};
				<>c.<>9__37_0 = val8;
				obj = (object)val8;
			}
			MenuHandler.CreateButton("Improve [R]", parkourWinMenu, (UnityAction)obj, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			CustomMap targetMap = getNextMap();
			GameObject val9 = MenuHandler.CreateButton((targetMap == null) ? "Get more maps" : ("Next map: " + mapToName(targetMap)), LopisParkour.parkourWinMenu, (UnityAction)delegate
			{
				TimeHandler.instance.gameOverTime = 1f;
				MainMenuHandler.instance.Close();
				if (targetMap != null)
				{
					instance.selectedMap = targetMap;
				}
				else
				{
					Application.OpenURL("https://thunderstore.io/c/rounds/p/lopidav/Lopis_Parkour/dependants/?q=&ordering=top-rated&section=mods&included_categories=131");
					MainMenuHandler.instance.Open();
					LopisParkour.ExitParkourGamemode();
				}
			}, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		public static void WinMenuShowLeaderboard()
		{
			//IL_0023: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LeaderboardText == (Object)null)
			{
				LeaderboardText = MenuHandler.CreateTextAt("", default(Vector2));
				((TMP_Text)LeaderboardText).transform.SetParent(LopisParkour.parkourWinMenu.transform.Find("Group"));
				((Component)LeaderboardText).gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
				((Transform)((TMP_Text)LeaderboardText).rectTransform).localScale = new Vector3(1f, 1f, 1f);
				((TMP_Text)LeaderboardText).transform.position = new Vector3(-30f, 15f, 0f);
				((TMP_Text)LeaderboardText).fontSize = 20f;
				((Graphic)LeaderboardText).color = new Color(255f, 255f, 255f, 200f);
				((TMP_Text)LeaderboardText).alignment = (TextAlignmentOptions)257;
			}
			if ((Object)(object)pauseLeaderboardText == (Object)null)
			{
				pauseLeaderboardText = MenuHandler.CreateTextAt("", default(Vector2));
				((TMP_Text)pauseLeaderboardText).transform.SetParent(LopisParkour.pauseMenu.transform);
				((Component)pauseLeaderboardText).gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
				((Transform)((TMP_Text)pauseLeaderboardText).rectTransform).localScale = new Vector3(1f, 1f, 1f);
				((TMP_Text)pauseLeaderboardText).transform.position = new Vector3(-30f, 15f, 0f);
				((TMP_Text)pauseLeaderboardText).fontSize = 20f;
				((Graphic)pauseLeaderboardText).color = new Color(255f, 255f, 255f, 200f);
				((TMP_Text)pauseLeaderboardText).alignment = (TextAlignmentOptions)257;
			}
			if ((Object)(object)LeaderboardText == (Object)null || (Object)(object)pauseLeaderboardText == (Object)null)
			{
				LopisParkour.Log("failed to create leaderboard object");
				return;
			}
			LopisParkour.Log(instance._selectedMap.id);
			if (instance._selectedMap.id.StartsWith(Paths.GameRootPath))
			{
				((TMP_Text)LeaderboardText).text = "";
				return;
			}
			LeaderboardRecord myRecordForMap = GlobalLeaderboard.GetMyRecordForMap(LopisParkour.pathToId(instance._selectedMap.id));
			MapObjectData val = ((IEnumerable<MapObjectData>)instance.selectedMap.MapObjects).FirstOrDefault((Func<MapObjectData, bool>)((MapObjectData mod) => (ValueProperty<float>)mod.GetProperty<GoldMedalProperty>() != (ValueProperty<float>)null));
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			if (val != null)
			{
				num = ((ValueProperty<float>)val.GetProperty<BronzeMedalProperty>())?.Value ?? 0f;
				num2 = ((ValueProperty<float>)val.GetProperty<SilverMedalProperty>())?.Value ?? 0f;
				num3 = ((ValueProperty<float>)val.GetProperty<GoldMedalProperty>())?.Value ?? 0f;
				num4 = ((ValueProperty<float>)val.GetProperty<ShinyMedalProperty>())?.Value ?? 0f;
			}
			if (num3 + num4 <= 0f || myRecordForMap == null || myRecordForMap.time > num3)
			{
				((TMP_Text)LeaderboardText).text = "Get gold to unlock Leaderboards for this map";
				((TMP_Text)pauseLeaderboardText).text = "Get gold to unlock Leaderboards for this map";
				return;
			}
			if (GlobalLeaderboard.isUpdating)
			{
				((TMP_Text)LeaderboardText).text = "Leaderboard (loading...)\n";
				((TMP_Text)pauseLeaderboardText).text = "Leaderboard (loading...)\n";
			}
			else
			{
				((TMP_Text)LeaderboardText).text = "Leaderboard\n";
				((TMP_Text)pauseLeaderboardText).text = "Leaderboard\n";
			}
			List<LeaderboardRecord> leaderboardForMap = GlobalLeaderboard.GetLeaderboardForMap(LopisParkour.pathToId(instance.selectedMap.id));
			CSteamID steamID = SteamUser.GetSteamID();
			string myId = ((object)(CSteamID)(ref steamID)).ToString();
			string recordString = "";
			int i = 0;
			int myPos = leaderboardForMap.FindIndex((LeaderboardRecord x) => x.id == myId);
			int cutoff = 15;
			int halo = 2;
			string tempString = "";
			leaderboardForMap.ForEach(delegate(LeaderboardRecord x)
			{
				i++;
				if (i <= cutoff || Math.Abs(myPos - i) <= halo)
				{
					if (i % 2 != 0)
					{
						recordString += "<mark=#FFFFFF05>";
					}
					tempString = i + " " + Regex.Replace(x.name, "<.+?>", "", RegexOptions.Multiline);
					if (tempString.Length > 30)
					{
						tempString = tempString.Substring(0, 30) + "...";
					}
					tempString = tempString + "\t" + TimeSpan.FromSeconds(x.time).ToString("mm\\:ss\\.fff");
					recordString += ((x.id != myId) ? tempString : ("<color=orange>" + tempString + "</color>"));
					recordString += "\n";
					if (i % 2 != 0)
					{
						recordString += "</mark>";
					}
				}
				else if (i == cutoff + 1)
				{
					recordString += "...";
					recordString += "\n";
				}
				else if (i == myPos + halo + 1)
				{
					recordString += "...";
					recordString += "\n";
				}
			});
			TextMeshProUGUI leaderboardText = LeaderboardText;
			((TMP_Text)leaderboardText).text = ((TMP_Text)leaderboardText).text + recordString;
			TextMeshProUGUI obj = pauseLeaderboardText;
			((TMP_Text)obj).text = ((TMP_Text)obj).text + recordString;
		}

		public void LoadSelectedMap()
		{
			if (selectedMap != null)
			{
				SceneManager.sceneLoaded += OnLevelFinishedLoading;
				MapManager.instance.RPCA_SetCallInNextMap(true);
				MapManager.instance.view.RPC("RPCA_LoadLevel", (RpcTarget)0, new object[1] { "MapsExtended:" + selectedMap._id });
				PlayerAssigner.instance.SetPlayersCanJoin(true);
				timerStop = false;
				if (EscapeMenuHandler.isEscMenu)
				{
					LopisParkour.pauseMenu.GetComponentInParent<EscapeMenuHandler>().ToggleEsc();
				}
				pauseNextMapButtonUpdate();
				WinMenuShowLeaderboard();
				string path = Path.Combine(Paths.GameRootPath, "ParkourReplays", LopisParkour.pathToId(_selectedMap.id).Replace('\\', '_') + "PB.prkr");
				if (File.Exists(path))
				{
					GhostReplayRecord replayRecord = SerializationUtility.DeserializeValue<GhostReplayRecord>(File.ReadAllBytes(path), (DataFormat)0, (DeserializationContext)null);
					ghostPlayer = ExtensionMethods.GetOrAddComponent<GhostReplayPlayer>(((Component)this).gameObject, false);
					ghostPlayer.Reset();
					ghostPlayer.replayRecord = replayRecord;
					((Behaviour)ghostPlayer).enabled = ghostEnabled;
				}
			}
		}

		public void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			PlayerManager.instance.RemovePlayers();
			PlayerManager.instance.ResetCharacters();
			if (MapManager.instance.currentMap != null)
			{
				_ = MapManager.instance.currentMap.Scene;
				if (true)
				{
					try
					{
						SceneManager.UnloadSceneAsync(MapManager.instance.currentMap.Scene);
					}
					catch (Exception s)
					{
						LopisParkour.Log(s);
					}
				}
			}
			SceneManager.sceneLoaded -= OnLevelFinishedLoading;
		}

		private void PlayerWasAdded(Player player)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			LopisParkour.Log("PlayerWasAdded");
			if (MapTransition.isTransitioning)
			{
				PlayerManager.instance.RemovePlayers();
				PlayerManager.instance.ResetCharacters();
				return;
			}
			PlayerManager.instance.SetPlayersSimulated(true);
			((Component)player.data).GetComponent<PlayerCollision>().IgnoreWallForFrames(2);
			((Component)player).transform.position = MapManager.instance.currentMap.Map.GetRandomSpawnPos();
			PlayerManager.instance.SetPlayersPlaying(true);
			PlayerAssigner.instance.SetPlayersCanJoin(false);
			player.GetFaceOffline();
		}

		private void PlayerDied(Player player, int unused)
		{
			LopisParkour.Log("PlayerDied");
			if (!MapTransition.isTransitioning)
			{
				reloadMap();
			}
		}

		private IEnumerator DelayRevive(Player player)
		{
			yield return (object)new WaitForSecondsRealtime(0.5f);
			PlayerWasAdded(player);
			player.data.healthHandler.Revive(true);
		}
	}
	public class GlobalLeaderboard
	{
		public static List<LeaderboardRecord> records = new List<LeaderboardRecord>();

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

		public static string saveFileName = "parkourLeaderboardData.sav";

		public static Action? onLeaderboardStartedDownload;

		public static Action? onLeaderboardSubmittionStart;

		public static Action? onLeaderboardFinishedDownload;

		public static Action? onLeaderboardFail;

		public static int processesUpdating = 0;

		public static bool filled = false;

		public static float lastRequestTime = -1f;

		public static float requestCooldown = 20f;

		public static bool wasQueued = false;

		public static bool isUpdating => processesUpdating > 0;

		public static void saveUrls()
		{
			if (mapIdToEditURL != null && mapIdToEditURL.Count != 0)
			{
				File.WriteAllBytes(Path.Combine(Paths.GameRootPath, saveFileName), SerializationUtility.SerializeValue<Dictionary<string, string>>(mapIdToEditURL, (DataFormat)0, (SerializationContext)null));
			}
		}

		public static void readUrls()
		{
			mapIdToEditURL = (File.Exists(Path.Combine(Paths.GameRootPath, saveFileName)) ? SerializationUtility.DeserializeValue<Dictionary<string, string>>(File.ReadAllBytes(Path.Combine(Paths.GameRootPath, saveFileName)), (DataFormat)0, (DeserializationContext)null) : new Dictionary<string, string>());
		}

		public static void QueueUpdate()
		{
			if (!wasQueued)
			{
				wasQueued = true;
				ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)LopisParkour.instance, requestCooldown - Time.time + lastRequestTime + 0.1f, (Action)delegate
				{
					wasQueued = false;
					RequestUpdate();
				});
			}
		}

		public static async void RequestUpdate()
		{
			if (Time.time - lastRequestTime < requestCooldown && lastRequestTime != -1f)
			{
				QueueUpdate();
				return;
			}
			lastRequestTime = Time.time;
			if (isUpdating)
			{
				return;
			}
			string sheetUrl = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTwPlhqxhy5MsAAMs38LOe1jMcayb4VpZkIYKZ1sdltek4PnbEWT7r5AsbuzLZYb0Wd4iXd1_gnEALf/pub?gid=1664204216&single=true&output=tsv";
			GoogleSheetsDownloadService downloadService = new GoogleSheetsDownloadService(sheetUrl);
			processesUpdating++;
			string response = "";
			if (onLeaderboardStartedDownload != null)
			{
				onLeaderboardStartedDownload();
			}
			try
			{
				response = await downloadService.DownloadAsync();
			}
			catch (Exception ex)
			{
				if (onLeaderboardFail != null)
				{
					onLeaderboardFail();
				}
				LopisParkour.Log("failed to download leaderboard" + ex.Message);
			}
			processesUpdating--;
			lastRequestTime = Time.time;
			if (processesUpdating < 0)
			{
				processesUpdating = 0;
			}
			if (string.IsNullOrEmpty(response))
			{
				return;
			}
			List<string> rows = response.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(1).ToList();
			rows.ForEach(delegate(string s)
			{
				LeaderboardRecord raw = new LeaderboardRecord(s);
				if (raw.time != -1f)
				{
					int num = records.FindIndex((LeaderboardRecord lr) => lr.id == raw.id && lr.mapId == raw.mapId);
					if (num == -1)
					{
						records.Add(raw);
					}
					else if (records[num].time > raw.time)
					{
						records[num].time = raw.time;
					}
				}
			});
			filled = true;
			if (onLeaderboardFinishedDownload != null)
			{
				onLeaderboardFinishedDownload();
			}
			LopisParkour.Log("leaderboard downloaded");
			LopisParkour.Log(records.Count + " records");
			List<string> keys = mapIdToEditURL.Keys.Select((string x) => x).ToList();
			CSteamID steamID = SteamUser.GetSteamID();
			((object)(CSteamID)(ref steamID)).ToString();
			foreach (string mapId in keys)
			{
				if (GetMyRecordForMap(mapId) == null)
				{
					mapIdToEditURL.Remove(mapId);
				}
			}
		}

		public static List<LeaderboardRecord> GetLeaderboardForMap(string mapId)
		{
			string mapId2 = mapId;
			return (from x in records.FindAll((LeaderboardRecord lr) => lr.mapId == mapId2)
				orderby x.time
				select x).ToList();
		}

		public static LeaderboardRecord? GetMyRecordForMap(string mapId)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			string mapId2 = mapId;
			CSteamID steamID = SteamUser.GetSteamID();
			string id = ((object)(CSteamID)(ref steamID)).ToString();
			return records.FirstOrDefault((LeaderboardRecord lr) => lr.mapId == mapId2 && lr.id == id);
		}

		public static void AddLocalRecord(LeaderboardRecord record)
		{
			LeaderboardRecord record2 = record;
			if (record2.time != -1f)
			{
				int num = records.FindIndex((LeaderboardRecord lr) => lr.id == record2.id && lr.mapId == record2.mapId);
				if (num == -1)
				{
					record2.isLocal = true;
					records.Add(record2);
				}
				else if (records[num].time > record2.time)
				{
					records[num].isLocal = true;
					records[num].time = record2.time;
				}
				if (onLeaderboardFinishedDownload != null)
				{
					onLeaderboardFinishedDownload();
				}
			}
		}

		public static async void AddRecord(string mapId, float time)
		{
			LopisParkour.Log("sending time");
			LeaderboardRecord prevOnlineRecord = GetMyRecordForMap(mapId);
			MapObjectData finish = ((IEnumerable<MapObjectData>)GM_Parkour.instance.selectedMap.MapObjects).FirstOrDefault((Func<MapObjectData, bool>)((MapObjectData mod) => (ValueProperty<float>)mod.GetProperty<GoldMedalProperty>() != (ValueProperty<float>)null));
			float bronzeTime = 0f;
			float silverTime = 0f;
			float goldTime = 0f;
			float shinyTime = 0f;
			if (finish != null)
			{
				bronzeTime = ((ValueProperty<float>)finish.GetProperty<BronzeMedalProperty>())?.Value ?? 0f;
				silverTime = ((ValueProperty<float>)finish.GetProperty<SilverMedalProperty>())?.Value ?? 0f;
				goldTime = ((ValueProperty<float>)finish.GetProperty<GoldMedalProperty>())?.Value ?? 0f;
				shinyTime = ((ValueProperty<float>)finish.GetProperty<ShinyMedalProperty>())?.Value ?? 0f;
			}
			if (time >= bronzeTime || time >= silverTime || time >= goldTime || !(time >= shinyTime))
			{
			}
			if ((prevOnlineRecord != null && prevOnlineRecord.time >= 0f && prevOnlineRecord.time <= time) || time <= 0f || goldTime + silverTime + bronzeTime == 0f || time > goldTime || GM_Parkour.instance._selectedMap.id.StartsWith(Paths.GameRootPath))
			{
				LopisParkour.Log("time doesn't count");
				return;
			}
			if (onLeaderboardSubmittionStart != null)
			{
				onLeaderboardSubmittionStart();
			}
			Dictionary<string, string> obj = new Dictionary<string, string> { { "usp", "pp_url" } };
			CSteamID steamID = SteamUser.GetSteamID();
			obj.Add("entry.947442791", ((object)(CSteamID)(ref steamID)).ToString());
			obj.Add("entry.230836744", SteamFriends.GetPersonaName());
			obj.Add("entry.728914614", mapId);
			obj.Add("entry.849905133", Math.Round(GM_Parkour.timePassed * 1000f).ToString());
			obj.Add("entry.558170443", string.Join(",", from x in Chainloader.PluginInfos
				select x.Key into x
				where !LopisParkour.modWhitelist.Contains(x)
				select x));
			Dictionary<string, string> fields = obj;
			string formUrl = "https://docs.google.com/forms/u/3/d/e/1FAIpQLSctn-4nrblqszIcZisvSfXQd72erl1tpDHlgrVpS_4Q2qra6Q/formResponse";
			if (mapIdToEditURL.ContainsKey(mapId) && filled)
			{
				LopisParkour.Log("found eligable leaderboards record edit id " + mapIdToEditURL[mapId]);
				fields.Remove("usp");
				fields["edit2"] = mapIdToEditURL[mapId];
			}
			GoogleFormsSubmissionService submissionService = new GoogleFormsSubmissionService(formUrl);
			submissionService.SetFieldValues(fields);
			HttpResponseMessage response = await submissionService.SubmitAsync();
			if (!response.IsSuccessStatusCode && mapIdToEditURL.ContainsKey(mapId))
			{
				mapIdToEditURL.Remove(mapId);
				AddRecord(mapId, time);
				return;
			}
			Match editUrl = Regex.Match(await response.Content.ReadAsStringAsync(), "https:\\/\\/docs\\.google\\.com\\/forms\\/u\\/3\\/d\\/e\\/1FAIpQLSctn-4nrblqszIcZisvSfXQd72erl1tpDHlgrVpS_4Q2qra6Q\\/viewform\\?usp=form_confirm&amp;edit2=(.*?)\"");
			if (editUrl.Groups[1].Success)
			{
				mapIdToEditURL[mapId] = editUrl.Groups[1].Value;
				saveUrls();
			}
			if (response.IsSuccessStatusCode)
			{
				steamID = SteamUser.GetSteamID();
				AddLocalRecord(new LeaderboardRecord(((object)(CSteamID)(ref steamID)).ToString(), SteamFriends.GetPersonaName(), mapId, time));
			}
			RequestUpdate();
		}
	}
	public class GoogleFormsSubmissionService
	{
		private string _baseUrl;

		private Dictionary<string, string> _field;

		private Dictionary<string, string[]> _checkbox;

		private HttpClient _client;

		public GoogleFormsSubmissionService(string formUrl)
		{
			if (string.IsNullOrEmpty(formUrl))
			{
				throw new ArgumentNullException("formUrl");
			}
			_baseUrl = formUrl;
			_field = new Dictionary<string, string>();
			_checkbox = new Dictionary<string, string[]>();
			_client = new HttpClient();
		}

		public void SetFieldValues(Dictionary<string, string> data)
		{
			if (data == null)
			{
				throw new ArgumentNullException("data");
			}
			if (data.Keys.Any((string value) => string.IsNullOrWhiteSpace(value)))
			{
				throw new ArgumentNullException("data", "Empty keys are invalid");
			}
			IEnumerable<KeyValuePair<string, string>> enumerable = data.Where<KeyValuePair<string, string>>((KeyValuePair<string, string> kvp) => !string.IsNullOrWhiteSpace(kvp.Value));
			foreach (KeyValuePair<string, string> item in enumerable)
			{
				_field[item.Key] = item.Value;
			}
		}

		public void SetCheckboxValues(string key, params string[] values)
		{
			if (string.IsNullOrWhiteSpace(key))
			{
				throw new ArgumentNullException("key");
			}
			string[] value2 = values.Where((string value) => !string.IsNullOrWhiteSpace(value)).ToArray();
			_checkbox[key] = value2;
		}

		public async Task<HttpResponseMessage> SubmitAsync()
		{
			if (!_field.Any() && !_checkbox.Any())
			{
				throw new InvalidOperationException("No data has been set to submit");
			}
			FormUrlEncodedContent content = new FormUrlEncodedContent(_field);
			string url = _baseUrl;
			if (_checkbox.Any())
			{
				string queryParams = string.Join("&", _checkbox.Keys.SelectMany((string key) => _checkbox[key].Select((string value) => key + "=" + value.Replace(' ', '+'))));
				url = url + "?" + queryParams;
			}
			HttpResponseMessage response = await _client.PostAsync(url, content);
			if (response.IsSuccessStatusCode)
			{
				Console.Write("Google form data was submitted sucessfully");
			}
			else
			{
				string fieldText = string.Join(Environment.NewLine, _field.Keys.Select((string key) => key + "=" + string.Join(",", _field[key])));
				Console.Write($"Failed to submit Google form\n{response.StatusCode}: {response.ReasonPhrase}\n{url}\n{fieldText}");
			}
			return response;
		}
	}
	public class GoogleSheetsDownloadService
	{
		private Uri _baseUrl;

		private WebClient _client;

		public GoogleSheetsDownloadService(string formUrl)
		{
			if (string.IsNullOrEmpty(formUrl))
			{
				throw new ArgumentNullException("formUrl");
			}
			_baseUrl = new Uri(formUrl);
			_client = new WebClient();
		}

		public async Task<string> DownloadAsync()
		{
			LopisParkour.Log("downloading leaderboard");
			return await _client.DownloadStringTaskAsync(_baseUrl);
		}
	}
	public class LeaderboardRecord
	{
		public string id = "";

		public string name = "";

		public string mapId = "";

		public float time = -1f;

		public bool isLocal = false;

		public LeaderboardRecord()
		{
		}

		public LeaderboardRecord(string id, string name, string mapId, float time)
		{
			this.id = id;
			this.name = name;
			this.mapId = mapId;
			this.time = (float)Math.Round(time * 1000f) / 1000f;
		}

		public LeaderboardRecord(string row)
		{
			List<string> list = row.Split(new char[1] { '\t' }).Skip(1).ToList();
			if (list.Count != 0)
			{
				id = list[0];
				name = list[1];
				mapId = list[2] ?? "";
				time = float.Parse(list[3].Replace(".", "").Replace(",", "") ?? "-1");
				if (time != -1f)
				{
					time /= 1000f;
				}
			}
		}

		public override string ToString()
		{
			return name + "\t" + TimeSpan.FromSeconds(time).ToString("mm\\:ss\\.fff");
		}
	}
	public class BackgroundGroundData : SpatialMapObjectData
	{
	}
	[MapObject(typeof(BackgroundGroundData))]
	public class BackgroundGround : IMapObject
	{
		public virtual GameObject Prefab => MapObjectManager.LoadCustomAsset<GameObject>("Ground Circle");

		public virtual void OnInstantiate(GameObject instance)
		{
			instance.layer = LayerMask.NameToLayer("BackgroundObject");
		}
	}
	public class DamageRectData : SpatialMapObjectData
	{
	}
	[MapObject(typeof(DamageRectData))]
	public class DamageRect : IMapObject
	{
		public virtual GameObject Prefab => MapObjectManager.LoadCustomAsset<GameObject>("Ground");

		public virtual void OnInstantiate(GameObject instance)
		{
			DamageRectMono orAddComponent = ExtensionMethods.GetOrAddComponent<DamageRectMono>(instance, false);
		}
	}
	public class DamageRectMono : MonoBehaviour
	{
		public float shake = 2f;

		public float counter = 0f;

		public virtual Color DamageRectColor => new Color(0.8f, 0.3f, 0.2f, 0.2f);

		public virtual void Start()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).gameObject.layer = LayerMask.NameToLayer("BackgroundObject");
			BoxCollider2D orAddComponent = ExtensionMethods.GetOrAddComponent<BoxCollider2D>(((Component)this).gameObject, false);
			((Collider2D)orAddComponent).isTrigger = true;
			ExtensionMethods.GetOrAddComponent<RectTransform>(((Component)this).gameObject, false);
			Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
			((Renderer)ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false)).material = LopisParkour.defaultMaterial;
			ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false).color = DamageRectColor;
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)LopisParkour.instance, 1, (Action)delegate
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
				SpriteRenderer orAddComponent3 = ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false);
				((Renderer)orAddComponent3).material = LopisParkour.defaultMaterial;
				orAddComponent3.color = DamageRectColor;
			});
			Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)LopisParkour.instance, 5, (Action)delegate
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
				SpriteRenderer orAddComponent2 = ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false);
				((Renderer)orAddComponent2).material = LopisParkour.defaultMaterial;
				orAddComponent2.color = DamageRectColor;
			});
		}

		private void FixedUpdate()
		{
			//IL_0066: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)((Component)this).gameObject.GetComponent<Renderer>()) && PlayerManager.instance.players.Count != 0)
			{
				counter += TimeHandler.fixedDeltaTime;
				if (counter > 1f)
				{
					counter = 1f;
				}
				Vector2 val = Vector2.op_Implicit(((Component)this).transform.position);
				Vector2 val2 = Vector2.op_Implicit(((Transform)((Component)this).gameObject.GetComponent<RectTransform>()).lossyScale);
				Vector2 up = Vector2.up;
				Vector3 up2 = ((Component)this).transform.up;
				Collider2D[] array = Physics2D.OverlapBoxAll(val, val2, Vector2.SignedAngle(up, Vector2.op_Implicit(((Vector3)(ref up2)).normalized)));
				Collider2D[] array2 = array;
				foreach (Collider2D collider in array2)
				{
					HandleCollision(collider);
				}
			}
		}

		public virtual void HandleCollision(Collider2D collider)
		{
			if (!((Object)(object)((Component)collider).gameObject == (Object)(object)((Component)this).gameObject) && Object.op_Implicit((Object)(object)((Component)collider).GetComponent<Player>()))
			{
				HandlePlayer(((Component)collider).GetComponent<Player>());
			}
		}

		public virtual void HandlePlayer(Player player)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0038: 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_0093: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).gameObject.transform.position;
			position.z = 0f;
			Vector3 val = ((Component)player).transform.position - position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			player.data.sinceGrounded = 0f;
			float num = 57.29578f * Mathf.Atan(((Component)this).gameObject.transform.localScale.x / ((Component)this).gameObject.transform.localScale.y);
			float num2 = 90f - num;
			float num3 = Vector3.SignedAngle(((Component)this).gameObject.transform.up, normalized, new Vector3(0f, 0f, 1f));
			if (1 == 0)
			{
			}
			if (num3 <= 0f - (num + num2 * 2f))
			{
				val = -((Component)this).gameObject.transform.up;
			}
			else
			{
				float num4 = num3;
				if (num4 > 0f - (num + num2 * 2f) && num4 <= 0f - num)
				{
					val = ((Component)this).gameObject.transform.right;
				}
				else
				{
					float num5 = num3;
					if (num5 > 0f - num && num5 <= num)
					{
						val = ((Component)this).gameObject.transform.up;
					}
					else
					{
						float num6 = num3;
						if (num6 > num && num6 <= num + num2 * 2f)
						{
							val = -((Component)this).gameObject.transform.right;
						}
						else
						{
							float num7 = num3;
							val = ((!(num7 > num + num2 * 2f)) ? ((Component)this).gameObject.transform.up : (-((Component)this).gameObject.transform.up));
						}
					}
				}
			}
			if (1 == 0)
			{
			}
			Vector3 val2 = val;
			if (counter > 0.1f && player.data.view.IsMine)
			{
				counter = 0f;
				if (player.data.block.IsBlocking())
				{
					PlayerVelocity playerVel = player.data.playerVel;
					playerVel.velocity *= 0f;
					player.data.healthHandler.CallTakeForce(Vector2.op_Implicit(val2 * 400f * player.data.playerVel.mass), (ForceMode2D)1, false, true, 0f);
				}
				else
				{
					player.data.healthHandler.CallTakeForce(Vector2.op_Implicit(val2 * 200f * player.data.playerVel.mass), (ForceMode2D)1, false, true, 0f);
					((Damagable)player.data.healthHandler).CallTakeDamage(Vector2.op_Implicit(51f * val2), Vector2.op_Implicit(((Component)player.data).transform.position), (GameObject)null, (Player)null, true);
				}
				SoundManager.Instance.Play(player.data.playerSounds.soundCharacterDamageScreenEdge, ((Component)player.data).transform);
			}
			val = normalized + Random.onUnitSphere;
			GamefeelManager.GameFeel(Vector2.op_Implicit(((Vector3)(ref val)).normalized * shake * TimeHandler.deltaTime * 20f));
		}
	}
	[EditorMapObject(typeof(DamageRectData), "Damage box (Saw but rect)", Category = "Parkur")]
	public sealed class EditorDamageRect : DamageRect
	{
	}
	[EditorMapObject(typeof(FinishData), "Finish", Category = "Parkur")]
	public sealed class EditorFinish : Finish
	{
	}
	[EditorMapObject(typeof(RectFinishData), "Finish (Rectangular)", Category = "Parkur")]
	public sealed class EditorRectFinish : RectFinish
	{
	}
	[EditorMapObject(typeof(StarterCardData), "Starter Card", Category = "Parkur")]
	public class EditorStarterCard : StarterCard
	{
		public override void OnInstantiate(GameObject instance)
		{
			((Behaviour)ExtensionMethods.GetOrAddComponent<StarterCardMono>(instance, false)).enabled = false;
		}
	}
	[EditorPropertySerializer(typeof(CardNameProperty))]
	public class EditorCardNamePropertySerializer : CardNamePropertySerializer, IPropertyReader<CardNameProperty>
	{
		public virtual CardNameProperty ReadProperty(GameObject instance)
		{
			return new CardNameProperty
			{
				cardName = instance.GetComponent<StarterCardMono>().GetStarterCard()
			};
		}
	}
	[InspectorElement(typeof(CardNameProperty))]
	public class CardNameElement : IInspectorElement
	{
		private InspectorContext context;

		private InputField input;

		public string Value
		{
			get
			{
				return PropertyExtensions.ReadProperty<CardNameProperty>(context.InspectorTarget).cardName;
			}
			set
			{
				OnChanged(value);
			}
		}

		public GameObject Instantiate(InspectorContext context)
		{
			this.context = context;
			GameObject val = Object.Instantiate<GameObject>(Assets.InspectorVector2InputPrefab);
			Transform child = val.transform.GetChild(1);
			Transform child2 = child.GetChild(0);
			Transform child3 = val.transform.GetChild(0);
			Object.Destroy((Object)(object)val.GetComponent<Vector2Input>());
			Object.Destroy((Object)(object)val.GetComponent<InspectorVector2Input>());
			Object.Destroy((Object)(object)((Component)child.GetChild(1)).gameObject);
			Object.Destroy((Object)(object)((Component)child2.GetChild(0)).gameObject);
			((Component)child2.GetChild(1).GetChild(0)).GetComponent<Text>().text = "Name";
			((Component)child3).gameObject.GetComponent<Text>().text = "Name";
			input = val.GetComponentInChildren<InputField>();
			((UnityEvent<string>)(object)input.onValueChanged).AddListener((UnityAction<string>)OnChanged);
			((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)onEndEdit);
			return val;
		}

		public void OnUpdate()
		{
			input.text = Value;
		}

		private void OnChanged(string str)
		{
			CardNameProperty cardNameProperty = new CardNameProperty();
			cardNameProperty.cardName = str;
			PropertyExtensions.WriteProperty<CardNameProperty>(context.InspectorTarget, cardNameProperty);
			context.Editor.TakeSnaphot();
		}

		private void onEndEdit(string str)
		{
			CardNameProperty cardNameProperty = new CardNameProperty();
			CardInfo val = null;
			val = CardManager.GetCardInfoWithName(str);
			if ((Object)(object)val == (Object)null)
			{
				CardInfo[] allCards = CardManager.allCards;
				int num = -1;
				float num2 = 0f;
				for (int i = 0; i < allCards.Length; i++)
				{
					string text = ((Component)allCards[i]).GetComponent<CardInfo>().cardName.ToUpper();
					text = text.Replace(" ", "");
					string text2 = str.ToUpper();
					text2 = text2.Replace(" ", "");
					float num3 = 0f;
					for (int j = 0; j < text2.Length; j++)
					{
						if (text.Length > j && text2[j] == text[j])
						{
							num3 += 1f / (float)text2.Length;
						}
					}
					num3 -= (float)Mathf.Abs(text2.Length - text.Length) * 0.001f;
					if (num3 > 0.1f && num3 > num2)
					{
						num2 = num3;
						num = i;
					}
				}
				if (num != -1)
				{
					val = allCards[num];
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				cardNameProperty.cardName = ((Object)((Component)val).gameObject).name;
				PropertyExtensions.WriteProperty<CardNameProperty>(context.InspectorTarget, cardNameProperty);
				context.Editor.TakeSnaphot();
			}
		}
	}
	public class FinishData : SpatialMapObjectData
	{
		[SerializeField]
		private GoldMedalProperty _gold = 0f;

		[SerializeField]
		private SilverMedalProperty _silver = 0f;

		[SerializeField]
		private BronzeMedalProperty _bronze = 0f;

		[SerializeField]
		private ShinyMedalProperty _shiny = 0f;

		public GoldMedalProperty GoldMedal
		{
			get
			{
				return _gold;
			}
			set
			{
				_gold = value;
			}
		}

		public SilverMedalProperty SilverMedal
		{
			get
			{
				return _silver;
			}
			set
			{
				_silver = value;
			}
		}

		public BronzeMedalProperty BronzeMedal
		{
			get
			{
				return _bronze;
			}
			set
			{
				_bronze = value;
			}
		}

		public ShinyMedalProperty ShinyMedal
		{
			get
			{
				return _shiny;
			}
			set
			{
				_shiny = value;
			}
		}
	}
	[MapObject(typeof(FinishData))]
	public class Finish : IMapObject
	{
		public virtual GameObject Prefab => MapObjectManager.LoadCustomAsset<GameObject>("Ground Circle");

		public virtual void OnInstantiate(GameObject instance)
		{
			ExtensionMethods.GetOrAddComponent<FinishMono>(instance, false);
		}
	}
	public class FinishMono : MonoBehaviour
	{
		public RaycastHit2D[] hits;

		public float timePassed = 0f;

		public bool completed = false;

		public virtual Color finishColor => new Color(0.215f, 0.215f, 0.8f, 0.25f);

		public virtual Color completedFinishColor => new Color(0.4f, 0.4f, 0.4f, 0.25f);

		public virtual void Start()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).gameObject.layer = LayerMask.NameToLayer("BackgroundObject");
			PolygonCollider2D orAddComponent = ExtensionMethods.GetOrAddComponent<PolygonCollider2D>(((Component)this).gameObject, false);
			((Collider2D)orAddComponent).isTrigger = true;
			ExtensionMethods.GetOrAddComponent<RectTransform>(((Component)this).gameObject, false);
			Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
			((Renderer)ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false)).material = LopisParkour.defaultMaterial;
			ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false).color = finishColor;
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)LopisParkour.instance, 1, (Action)delegate
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
				SpriteRenderer orAddComponent3 = ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false);
				((Renderer)orAddComponent3).material = LopisParkour.defaultMaterial;
				orAddComponent3.color = finishColor;
			});
			Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)LopisParkour.instance, 5, (Action)delegate
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<SpriteMask>());
				SpriteRenderer orAddComponent2 = ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false);
				((Renderer)orAddComponent2).material = LopisParkour.defaultMaterial;
				orAddComponent2.color = finishColor;
			});
		}

		private void FixedUpdate()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)((Component)this).gameObject.GetComponent<Renderer>()) && !completed && PlayerManager.instance.players.Count != 0)
			{
				timePassed += Time.fixedDeltaTime;
				Vector2 val = Vector2.op_Implicit(((Component)this).transform.position);
				Vector2 val2 = Vector2.op_Implicit(((Transform)((Component)this).gameObject.GetComponent<RectTransform>()).lossyScale);
				Vector2 up = Vector2.up;
				Vector3 up2 = ((Component)this).transform.up;
				Collider2D[] array = Physics2D.OverlapBoxAll(val, val2, Vector2.SignedAngle(up, Vector2.op_Implicit(((Vector3)(ref up2)).normalized)));
				Collider2D[] array2 = array;
				foreach (Collider2D collider in array2)
				{
					HandleCollision(collider);
				}
			}
		}

		public virtual void HandleCollision(Collider2D collider)
		{
			if (!((Object)(object)((Component)collider).gameObject == (Object)(object)((Component)this).gameObject) && Object.op_Implicit((Object)(object)((Component)collider).GetComponent<Player>()))
			{
				HandlePlayer(((Component)collider).GetComponent<Player>());
			}
		}

		public virtual void HandlePlayer(Player player)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (GameModeManager.CurrentHandler.GameMode is GM_Parkour gM_Parkour)
			{
				gM_Parkour.MapWon();
			}
			else
			{
				Unbound.BuildInfoPopup(timePassed.ToString());
			}
			ExtensionMethods.GetOrAddComponent<SpriteRenderer>(((Component)this).gameObject, false).color = completedFinishColor;
			completed = true;
		}
	}
	public class BronzeMedalProperty : ValueProperty<float>
	{
		[SerializeField]
		private readonly float _BronzeMedalTime;

		public override float Value => _BronzeMedalTime;

		public BronzeMedalProperty()
		{
		}

		public BronzeMedalProperty(float BronzeMedalTime)
		{
			_BronzeMedalTime = BronzeMedalTime;
		}

		public override bool Equals(ValueProperty<float> other)
		{
			return ((ValueProperty<float>)this).Value == other.Value;
		}

		public IProperty Lerp(IProperty end, float t)
		{
			return Lerp((IProperty)(object)(BronzeMedalProperty)(object)end, t);
		}

		public static implicit operator BronzeMedalProperty(float angle)
		{
			return new BronzeMedalProperty(angle);
		}

		public static implicit operator float(BronzeMedalProperty prop)
		{
			return ((ValueProperty<float>)prop).Value;
		}

		public static BronzeMedalProperty operator +(BronzeMedalProperty a, BronzeMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value + ((ValueProperty<float>)b).Value;
		}

		public static BronzeMedalProperty operator -(BronzeMedalProperty a, BronzeMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value - ((ValueProperty<float>)b).Value;
		}

		public static Vector3 operator *(BronzeMedalProperty a, Vector2 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}

		public static Vector3 operator *(BronzeMedalProperty a, Vector3 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}
	}
	[PropertySerializer(typeof(BronzeMedalProperty))]
	public class BronzeMedalPropertySerializer : IPropertyWriter<BronzeMedalProperty>
	{
		public virtual void WriteProperty(BronzeMedalProperty property, GameObject target)
		{
			ExtensionMethods.GetOrAddComponent<BronzeMedalPropertyInstance>(target, false).BronzeTime = property;
		}
	}
	[EditorPropertySerializer(typeof(BronzeMedalProperty))]
	public class EditorBronzeMedalPropertySerializer : BronzeMedalPropertySerializer, IPropertyReader<BronzeMedalProperty>
	{
		public override void WriteProperty(BronzeMedalProperty property, GameObject target)
		{
			base.WriteProperty(property, target);
		}

		public virtual BronzeMedalProperty ReadProperty(GameObject instance)
		{
			return instance.GetComponent<BronzeMedalPropertyInstance>().BronzeTime;
		}
	}
	public class BronzeMedalPropertyInstance : MonoBehaviour
	{
		public BronzeMedalProperty BronzeTime { get; set; } = new BronzeMedalProperty();

	}
	[InspectorElement(typeof(BronzeMedalProperty))]
	public class BronzeMedalElement : FloatElement
	{
		public BronzeMedalElement()
			: base("Bronze Time (s)", 0f, float.MaxValue)
		{
		}

		protected override float GetValue()
		{
			return PropertyExtensions.ReadProperty<BronzeMedalProperty>(((InspectorElement)this).Context.InspectorTarget);
		}

		protected override void OnChange(float value, ChangeType changeType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((int)changeType == 1 || (int)changeType == 2)
			{
				PropertyExtensions.WriteProperty<BronzeMedalProperty>(((InspectorElement)this).Context.InspectorTarget, (BronzeMedalProperty)value);
			}
			if ((int)changeType == 2)
			{
				((InspectorElement)this).Context.Editor.TakeSnaphot();
			}
		}
	}
	public class GoldMedalProperty : ValueProperty<float>
	{
		[SerializeField]
		private readonly float _goldMedalTime;

		public override float Value => _goldMedalTime;

		public GoldMedalProperty()
		{
		}

		public GoldMedalProperty(float goldMedalTime)
		{
			_goldMedalTime = goldMedalTime;
		}

		public override bool Equals(ValueProperty<float> other)
		{
			return ((ValueProperty<float>)this).Value == other.Value;
		}

		public IProperty Lerp(IProperty end, float t)
		{
			return Lerp((IProperty)(object)(GoldMedalProperty)(object)end, t);
		}

		public static implicit operator GoldMedalProperty(float angle)
		{
			return new GoldMedalProperty(angle);
		}

		public static implicit operator float(GoldMedalProperty prop)
		{
			return ((ValueProperty<float>)prop).Value;
		}

		public static GoldMedalProperty operator +(GoldMedalProperty a, GoldMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value + ((ValueProperty<float>)b).Value;
		}

		public static GoldMedalProperty operator -(GoldMedalProperty a, GoldMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value - ((ValueProperty<float>)b).Value;
		}

		public static Vector3 operator *(GoldMedalProperty a, Vector2 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}

		public static Vector3 operator *(GoldMedalProperty a, Vector3 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}
	}
	[PropertySerializer(typeof(GoldMedalProperty))]
	public class GoldMedalPropertySerializer : IPropertyWriter<GoldMedalProperty>
	{
		public virtual void WriteProperty(GoldMedalProperty property, GameObject target)
		{
			ExtensionMethods.GetOrAddComponent<GoldMedalPropertyInstance>(target, false).GoldTime = property;
		}
	}
	[EditorPropertySerializer(typeof(GoldMedalProperty))]
	public class EditorGoldMedalPropertySerializer : GoldMedalPropertySerializer, IPropertyReader<GoldMedalProperty>
	{
		public override void WriteProperty(GoldMedalProperty property, GameObject target)
		{
			base.WriteProperty(property, target);
		}

		public virtual GoldMedalProperty ReadProperty(GameObject instance)
		{
			return instance.GetComponent<GoldMedalPropertyInstance>().GoldTime;
		}
	}
	public class GoldMedalPropertyInstance : MonoBehaviour
	{
		public GoldMedalProperty GoldTime { get; set; } = new GoldMedalProperty();

	}
	[InspectorElement(typeof(GoldMedalProperty))]
	public class GoldMedalElement : FloatElement
	{
		public GoldMedalElement()
			: base("Gold Time (s)", 0f, float.MaxValue)
		{
		}

		protected override float GetValue()
		{
			return PropertyExtensions.ReadProperty<GoldMedalProperty>(((InspectorElement)this).Context.InspectorTarget);
		}

		protected override void OnChange(float value, ChangeType changeType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((int)changeType == 1 || (int)changeType == 2)
			{
				PropertyExtensions.WriteProperty<GoldMedalProperty>(((InspectorElement)this).Context.InspectorTarget, (GoldMedalProperty)value);
			}
			if ((int)changeType == 2)
			{
				((InspectorElement)this).Context.Editor.TakeSnaphot();
			}
		}
	}
	public class ShinyMedalProperty : ValueProperty<float>
	{
		[SerializeField]
		private readonly float _ShinyMedalTime;

		public override float Value => _ShinyMedalTime;

		public ShinyMedalProperty()
		{
		}

		public ShinyMedalProperty(float ShinyMedalTime)
		{
			_ShinyMedalTime = ShinyMedalTime;
		}

		public override bool Equals(ValueProperty<float> other)
		{
			return ((ValueProperty<float>)this).Value == other.Value;
		}

		public ShinyMedalProperty Lerp(ShinyMedalProperty end, float t)
		{
			return new ShinyMedalProperty(Mathf.LerpAngle(((ValueProperty<float>)this).Value, ((ValueProperty<float>)end).Value, t));
		}

		public IProperty Lerp(IProperty end, float t)
		{
			return (IProperty)(object)Lerp((ShinyMedalProperty)(object)end, t);
		}

		public static implicit operator ShinyMedalProperty(float angle)
		{
			return new ShinyMedalProperty(angle);
		}

		public static implicit operator float(ShinyMedalProperty prop)
		{
			return ((ValueProperty<float>)prop).Value;
		}

		public static ShinyMedalProperty operator +(ShinyMedalProperty a, ShinyMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value + ((ValueProperty<float>)b).Value;
		}

		public static ShinyMedalProperty operator -(ShinyMedalProperty a, ShinyMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value - ((ValueProperty<float>)b).Value;
		}

		public static Vector3 operator *(ShinyMedalProperty a, Vector2 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}

		public static Vector3 operator *(ShinyMedalProperty a, Vector3 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}
	}
	[PropertySerializer(typeof(ShinyMedalProperty))]
	public class ShinyMedalPropertySerializer : IPropertyWriter<ShinyMedalProperty>
	{
		public virtual void WriteProperty(ShinyMedalProperty property, GameObject target)
		{
			ExtensionMethods.GetOrAddComponent<ShinyMedalPropertyInstance>(target, false).ShinyTime = property;
		}
	}
	[EditorPropertySerializer(typeof(ShinyMedalProperty))]
	public class EditorShinyMedalPropertySerializer : ShinyMedalPropertySerializer, IPropertyReader<ShinyMedalProperty>
	{
		public override void WriteProperty(ShinyMedalProperty property, GameObject target)
		{
			base.WriteProperty(property, target);
		}

		public virtual ShinyMedalProperty ReadProperty(GameObject instance)
		{
			return instance.GetComponent<ShinyMedalPropertyInstance>().ShinyTime;
		}
	}
	public class ShinyMedalPropertyInstance : MonoBehaviour
	{
		public ShinyMedalProperty ShinyTime { get; set; } = new ShinyMedalProperty();

	}
	[InspectorElement(typeof(ShinyMedalProperty))]
	public class ShinyMedalElement : FloatElement
	{
		public ShinyMedalElement()
			: base("Shiny Time (s)", 0f, float.MaxValue)
		{
		}

		protected override float GetValue()
		{
			return PropertyExtensions.ReadProperty<ShinyMedalProperty>(((InspectorElement)this).Context.InspectorTarget);
		}

		protected override void OnChange(float value, ChangeType changeType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((int)changeType == 1 || (int)changeType == 2)
			{
				PropertyExtensions.WriteProperty<ShinyMedalProperty>(((InspectorElement)this).Context.InspectorTarget, (ShinyMedalProperty)value);
			}
			if ((int)changeType == 2)
			{
				((InspectorElement)this).Context.Editor.TakeSnaphot();
			}
		}
	}
	public class SilverMedalProperty : ValueProperty<float>
	{
		[SerializeField]
		private readonly float _SilverMedalTime;

		public override float Value => _SilverMedalTime;

		public SilverMedalProperty()
		{
		}

		public SilverMedalProperty(float SilverMedalTime)
		{
			_SilverMedalTime = SilverMedalTime;
		}

		public override bool Equals(ValueProperty<float> other)
		{
			return ((ValueProperty<float>)this).Value == other.Value;
		}

		public SilverMedalProperty Lerp(SilverMedalProperty end, float t)
		{
			return new SilverMedalProperty(Mathf.LerpAngle(((ValueProperty<float>)this).Value, ((ValueProperty<float>)end).Value, t));
		}

		public IProperty Lerp(IProperty end, float t)
		{
			return (IProperty)(object)Lerp((SilverMedalProperty)(object)end, t);
		}

		public static implicit operator SilverMedalProperty(float angle)
		{
			return new SilverMedalProperty(angle);
		}

		public static implicit operator float(SilverMedalProperty prop)
		{
			return ((ValueProperty<float>)prop).Value;
		}

		public static SilverMedalProperty operator +(SilverMedalProperty a, SilverMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value + ((ValueProperty<float>)b).Value;
		}

		public static SilverMedalProperty operator -(SilverMedalProperty a, SilverMedalProperty b)
		{
			return ((ValueProperty<float>)a).Value - ((ValueProperty<float>)b).Value;
		}

		public static Vector3 operator *(SilverMedalProperty a, Vector2 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}

		public static Vector3 operator *(SilverMedalProperty a, Vector3 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return a * b;
		}
	}
	[PropertySerializer(typeof(SilverMedalProperty))]
	public class SilverMedalPropertySerializer : IPropertyWriter<SilverMedalProperty>
	{
		public virtual void WriteProperty(SilverMedalProperty property, GameObject target)
		{
			ExtensionMethods.GetOrAddComponent<SilverMedalPropertyInstance>(target, false).SilverTime = property;
		}
	}
	[EditorPropertySerializer(typeof(SilverMedalProperty))]
	public class EditorSilverMedalPropertySerializer : SilverMedalPropertySerializer, IPropertyReader<SilverMedalProperty>
	{
		public override void WriteProperty(SilverMedalProperty property, GameObject target)
		{
			base.WriteProperty(property, target);
		}

		public virtual SilverMedalProperty ReadProperty(GameObject instance)
		{
			return instance.GetComponent<SilverMedalPropertyInstance>().SilverTime;
		}
	}
	public class SilverMedalPropertyInstance : MonoBehaviour
	{
		public SilverMedalProperty SilverTime { get; set; } = new SilverMedalProperty();

	}
	[InspectorElement(typeof(SilverMedalProperty))]
	public class SilverMedalElement : FloatElement
	{
		public SilverMedalElement()
			: base("Silver Time (s)", 0f, float.MaxValue)
		{
		}

		protected override float GetValue()
		{
			return PropertyExtensions.ReadProperty<SilverMedalProperty>(((InspectorElement)this).Context.InspectorTarget);
		}

		protected override void OnChange(float value, ChangeType changeType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((int)changeType == 1 || (int)changeType == 2)
			{
				PropertyExtensions.WriteProperty<SilverMedalProperty>(((InspectorElement)this).Context.InspectorTarget, (SilverMedalProperty)value);
			}
			if ((int)changeType == 2)
			{
				((InspectorElement)this).Context.Editor.TakeSnaphot();
			}
		}
	}
	public class RectFinishData : SpatialMapObjectData
	{
		[SerializeField]
		private GoldMedalProperty _gold = 0f;

		[SerializeField]
		private SilverMedalProperty _silver = 0f;

		[SerializeField]
		private BronzeMedalProperty _bronze = 0f;

		[SerializeField]
		private ShinyMedalProperty _shiny = 0f;

		public GoldMedalProperty GoldMedal
		{
			get
			{
				return _gold;
			}
			set
			{
				_gold = value;
			}
		}

		public SilverMedalProperty SilverMedal
		{
			get
			{
				return _silver;
			}
			set
			{
				_silver = value;
			}
		}

		public BronzeMedalProperty BronzeMedal
		{
			get
			{
				return _bronze;
			}
			set
			{
				_bronze = value;
			}
		}

		public ShinyMedalProperty ShinyMedal
		{
			get
			{
				return _shiny;
			}
			set
			{
				_shiny = value;
			}
		}
	}
	[MapObject(typeof(RectFinishData))]
	public class RectFinish : IMapObject
	{
		public virtual GameObject Prefab => MapObjectManager.LoadCustomAsset<GameObject>("Ground");

		public virtual void OnInstantiate(GameObject instance)
		{
			ExtensionMethods.GetOrAddComponent<FinishMono>(instance, false);
		}
	}
	public class StarterCardMono : MonoBehaviour
	{
		private string starterCard = "";

		private List<GameObject> pendingCardObjects = new List<GameObject>();

		private bool enabled = true;

		private List<Player> effectedPlayers = new List<Player>();

		private Vector3 DesieredPreviewPosition = Vector3.zero;

		public virtual void Update()
		{
			if (!enabled)
			{
				return;
			}
			PlayerManager.instance.players.ForEach(delegate(Player player)
			{
				if (!effectedPlayers.Contains(player))
				{
					PlayerWasAdded(player);
				}
			});
		}

		public string GetStarterCard()
		{
			return starterCard;
		}

		public void SetStarterCard(string starterCard)
		{
			this.starterCard = starterCard;
		}

		private void PlayerWasAdded(Player player)
		{
			Player player2 = player;
			effectedPlayers.Add(player2);
			pendingCardObjects.ForEach(delegate(GameObject obj)
			{
				DelayedPick(obj, player2.playerID);
			});
		}

		public async void DelayedPick(GameObject cardObject, int playerID)
		{
			await Task.Delay(22);
			((Component)cardObject.transform.root).GetComponentInChildren<ApplyCardStats>().Pick(playerID, false, (PickerType)1);
			pendingCardObjects.Remove(cardObject);
			CardChoice.instance.spawnedCards.Remove(cardObject);
			Object.Destroy((Object)(object)cardObject);
		}

		public virtual void Start()
		{
			if (enabled)
			{
				ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)LopisParkour.instance, 5, (Action)delegate
				{
					addTheCard();
				});
			}
		}

		public void addTheCard()
		{
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			if (!enabled)
			{
				return;
			}
			CardInfo val = null;
			val = CardManager.GetCardInfoWithName(starterCard);
			if ((Object)(object)val == (Object)null)
			{
				CardInfo[] cards = CardChoice.instance.cards;
				int num = -1;
				float num2 = 0f;
				for (int i = 0; i < cards.Length; i++)
				{
					string text = ((Component)cards[i]).GetComponent<CardInfo>().cardName.ToUpper();
					text = text.Replace(" ", "");
					string text2 = starterCard.ToUpper();
					text2 = text2.Replace(" ", "");
					float num3 = 0f;
					for (int j = 0; j < text2.Length; j++)
					{
						if (text.Length > j && text2[j] == text[j])
						{
							num3 += 1f / (float)text2.Length;
						}
					}
					num3 -= (float)Mathf.Abs(text2.Length - text.Length) * 0.001f;
					if (num3 > 0.1f && num3 > num2)
					{
						num2 = num3;
						num = i;
					}
				}
				if (num != -1)
				{
					val = cards[num];
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				LopisParkour.Log("starter card not found:" + starterCard);
				return;
			}
			GameObject val2 = CardChoice.instance.AddCard(val);
			val2.GetComponentInChildren<CardVisuals>().firstValueToSet = true;
			val2.transform.localScale = new Vector3(0.7f, 0.7f, 0.7f);
			val2.transform.GetChild(0).localScale = new Vector3(9.5536f, 9.5536f, 9.5536f);
			val2.transform.position = (LopisParkour.cameraHandlerInstance?._targetSize ?? 20f) * (28.5f * Vector3.right + 11f * Vector3.up + 9.5f * Vector3.left * (float)CardChoice.instance.spawnedCards.IndexOf(val2)) / 20f;
			pendingCardObjects.Add(val2);
			LopisParkour.Log("found starter card: " + val.cardName);
		}

		public void setCardPositions()
		{
			pendingCardObjects.ForEach(delegate(GameObject obj)
			{
				//IL_0026: 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_0056: 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)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: 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_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)obj == (Object)null))
				{
					obj.transform.localScale = new Vector3(0.7f, 0.7f, 0.7f);
					obj.transform.position = (LopisParkour.cameraHandlerInstance?._targetSize ?? 20f) * (28.5f * Vector3.right + 11f * Vector3.up + 9.5f * Vector3.left * (float)CardChoice.instance.spawnedCards.IndexOf(obj)) / 20f;
				}
			});
		}

		public virtual void onDisable()
		{
			pendingCardObjects.ForEach(delegate(GameObject cardObject)
			{
				CardChoice.instance.spawnedCards.Remove(cardObject);
				Object.Destroy((Object)(object)cardObject);
			});
			pendingCardObjects.ForEach(delegate(GameObject cardObject)
			{
				Object.Destroy((Object)(object)cardObject);
			});
			PlayerManager instance = PlayerManager.instance;
			instance.PlayerJoinedAction = (Action<Player>)Delegate.Remove(instance.PlayerJoinedAction, new Action<Player>(PlayerWasAdded));
		}

		public virtual void OnDestroy()
		{
			pendingCardObjects.ForEach(delegate(GameObject cardObject)
			{
				CardChoice.instance.spawnedCards.Remove(cardObject);
				Object.Destroy((Object)(object)cardObject);
			});
			pendingCardObjects.ForEach(delegate(GameObject cardObject)
			{
				Object.Destroy((Object)(object)cardObject);
			});
			PlayerManager instance = PlayerManager.instance;
			instance.PlayerJoinedAction = (Action<Player>)Delegate.Remove(instance.PlayerJoinedAction, new Action<Player>(PlayerWasAdded));
		}
	}
	public class StarterCardData : SpatialMapObjectData
	{
		public CardNameProperty cardName = new CardNameProperty();
	}
	public class CardNameProperty : IProperty
	{
		public string cardName = "";
	}
	[PropertySerializer(typeof(CardNameProperty))]
	public class CardNamePropertySerializer : IPropertyWriter<CardNameProperty>
	{
		public virtual void WriteProperty(CardNameProperty property, GameObject target)
		{
			ExtensionMethods.GetOrAddComponent<StarterCardMono>(target, false).SetStarterCard(property.cardName);
		}
	}
	[MapObject(typeof(StarterCardData))]
	public class StarterCard : IMapObject
	{
		public virtual GameObject Prefab => MapObjectManager.LoadCustomAsset<GameObject>("Ground");

		public virtual void OnInstantiate(GameObject instance)
		{
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("lopi.rounds.plugins.lopisparkour", "Lopis Parkour", "1.0.5")]
	[BepInProcess("Rounds.exe")]
	public class LopisParkour : BaseUnityPlugin
	{
		private class EmptyEnumerator : IEnumerator
		{
			public object? Current => null;

			public void Reset()
			{
				throw new NotImplementedException();
			}

			bool IEnumerator.MoveNext()
			{
				return false;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__ParkourMenu;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction<Scene, LoadSceneMode> <>9__27_0;

			public static Func<KeyValuePair<string, PluginInfo>, bool> <>9__28_0;

			public static Func<KeyValuePair<string, PluginInfo>, string> <>9__28_1;

			public static Action<GameObject> <>9__30_0;

			public static Func<string, bool> <>9__30_1;

			public static Action<string> <>9__30_2;

			public static Action<KeyValuePair<string, CustomMap>> <>9__30_3;

			public static Func<int, bool> <>9__30_19;

			public static Func<int, int, string> <>9__30_16;

			public static Func<string, bool> <>9__30_17;

			public static Func<KeyValuePair<string, CustomMap>, float> <>9__30_21;

			public static Comparison<float> <>9__30_22;

			public static Func<KeyValuePair<string, CustomMap>, float> <>9__30_5;

			public static Comparison<float> <>9__30_6;

			public static UnityAction <>9__30_8;

			public static UnityAction <>9__30_9;

			public static UnityAction <>9__30_10;

			public static UnityAction <>9__30_11;

			public static UnityAction <>9__30_12;

			public static Action<LayoutElement> <>9__38_0;

			internal void <Start>b__27_0(Scene scene, LoadSceneMode mode)
			{
				if (((Scene)(ref scene)).name == "Main")
				{
					AddTheButton();
				}
			}

			internal bool <CheckForExtraMods>b__28_0(KeyValuePair<string, PluginInfo> x)
			{
				return !modWhitelist.Contains(x.Key);
			}

			internal string <CheckForExtraMods>b__28_1(KeyValuePair<string, PluginInfo> x)
			{
				return x.Value.Metadata.Name;
			}

			internal void <ParkourMenu>b__30_0(GameObject x)
			{
				Object.Destroy((Object)(object)x);
			}

			internal bool <ParkourMenu>b__30_1(string s)
			{
				return s != "";
			}

			internal void <ParkourMenu>b__30_2(string f)
			{
				if (!maps.ContainsKey(f))
				{
					maps.Add(f, MapLoader.LoadPath(f, (DeserializationContext)null));
				}
				else
				{
					maps[f] = MapLoader.LoadPath(f, (DeserializationContext)null);
				}
				maps[f].id = f;
			}

			internal void <ParkourMenu>b__30_3(KeyValuePair<string, CustomMap> f)
			{
				string item = "";
				if (f.Key.StartsWith(Paths.PluginPath))
				{
					item = Path.Combine(Paths.PluginPath, GeneralExtensions.Join<char>(f.Key.Remove(0, Paths.PluginPath.Length + 1).Take(f.Key.Remove(0, Paths.PluginPath.Length + 1).IndexOf(Path.DirectorySeparatorChar)), (Func<char, string>)null, ""));
				}
				else if (f.Key.StartsWith(Paths.GameRootPath))
				{
					item = Path.Combine(Paths.GameRootPath, GeneralExtensions.Join<char>(f.Key.Remove(0, Paths.GameRootPath.Length + 1).Take(f.Key.Remove(0, Paths.GameRootPath.Length + 1).IndexOf(Path.DirectorySeparatorChar)), (Func<char, string>)null, ""));
				}
				if (!mapsHierarchy.Contains(item))
				{
					mapsHierarchy.Add(item);
				}
			}

			internal bool <ParkourMenu>b__30_19(int x)
			{
				return x > 0;
			}

			internal string <ParkourMenu>b__30_16(int medalCount, int i)
			{
				return (medalCount <= 0) ? "" : (medalCount + new ParkourProgressEntry
				{
					medal = (MedalType)i
				}.getMedalSymbol());
			}

			internal bool <ParkourMenu>b__30_17(string x)
			{
				return x != "";
			}

			internal float <ParkourMenu>b__30_21(KeyValuePair<string, CustomMap> f)
			{
				if (float.TryParse(Regex.Split(f.Value._name.Remove(0, 4), "_")[0].Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
				{
					return result;
				}
				return (int)f.Value._name.Remove(0, 4)[0];
			}

			internal int <ParkourMenu>b__30_22(float x, float y)
			{
				return (x > y) ? 1 : ((x < y) ? (-1) : 0);
			}

			internal float <ParkourMenu>b__30_5(KeyValuePair<string, CustomMap> f)
			{
				if (float.TryParse(Regex.Split(f.Value._name.Remove(0, 4), "_")[0].Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
				{
					return result;
				}
				return (int)f.Value._name.Remove(0, 4)[0];
			}

			internal int <ParkourMenu>b__30_6(float x, float y)
			{
				return (x > y) ? 1 : ((x < y) ? (-1) : 0);
			}

			internal void <ParkourMenu>b__30_8()
			{
				Application.OpenURL("https://thunderstore.io/c/rounds/p/lopidav/Lopis_Parkour/dependants/?q=&ordering=top-rated&section=mods&included_categories=131");
				ExitParkourGamemode();
			}

			internal void <ParkourMenu>b__30_9()
			{
				Application.OpenURL("https://docs.google.com/document/d/1kYegslKXzL2sf-BxvEWKecUuQ_RAQn5joaaG4d6Ur8E/edit?usp=sharing");
			}

			internal void <ParkourMenu>b__30_10()
			{
			}

			internal void <ParkourMenu>b__30_11()
			{
				TimeHandler.instance.gameOverTime = 1f;
			}

			internal void <ParkourMenu>b__30_12()
			{
				ExitParkourGamemode();
			}

			internal void <replaceTheTitleCard>b__38_0(LayoutElement x)
			{
				Object.DestroyImmediate((Object)(object)x);
			}
		}

		public const string ModId = "lopi.rounds.plugins.lopisparkour";

		public const string ModName = "Lopis Parkour";

		public const string Version = "1.0.5";

		public Harmony harmony;

		public static GameObject parkourMenu;

		public static bool openParkourMenuOnCreation = false;

		public static GameObject pauseMenu;

		public static GameObject parkourWinMenu = null;

		public static List<GameObject> parkourMenuDirectories = new List<GameObject>();

		internal static readonly Material defaultMaterial = new Material(Shader.Find("Sprites/Default"));

		public static Dictionary<string, CustomMap> maps = new Dictionary<string, CustomMap>();

		public static List<string> mapsHierarchy = new List<string>();

		public static string saveFileName = "parkour.sav";

		public static string urlYouTubeChannel = "https://www.youtube.com/@RoundsParkour";

		public static string urlBugSubmissionForm = "https://docs.google.com/forms/d/e/1FAIpQLSexyvrUEe0yg-lnIRBPXw0YY89d43rB_VfoLCJtXWQ3ibXyFg/viewform?usp=dialog";

		public static string urCompDiscord = "https://discord.gg/HQkaP2jupg";

		public static string[] modWhitelist = new string[7] { "com.willis.rounds.unbound", "io.olavim.rounds.mapsextended", "com.woukie.rounds.mapimageobjects", "io.olavim.rounds.mapsextended.editor", "com.woukie.rounds.mapimageobjectseditor", "lopi.rounds.plugins.lopisparkour", "pykess.rounds.plugins.performanceimprovements" };

		public static LopisParkour? instance;

		public static CameraHandler? cameraHandlerInstance;

		public static Sprite? parkourTitleCard;

		public static string CompatibilityModName => "Lopis Parkour".Replace(" ", "");

		public static string saveFilePath => Path.Combine(Paths.GameRootPath, saveFileName);

		public static void Log(object s)
		{
			if ((Object)(object)instance != (Object)null)
			{
				Debug.Log((object)string.Format("[{0} {1}] {2}", "Lopis Parkour", TimeSpan.FromSeconds(Time.time).ToString("hh\\:mm\\:ss\\.fff"), s));
			}
		}

		public static void LogError(object s)
		{
			if ((Object)(object)instance != (Object)null)
			{
				Debug.LogError((object)string.Format("[{0} {1}] {2}", "Lopis Parkour", TimeSpan.FromSeconds(Time.time).ToString("hh\\:mm\\:ss\\.fff"), s));
			}
		}

		public void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			instance = this;
			try
			{
				harmony = new Harmony("lopi.rounds.plugins.lopisparkour");
				harmony.PatchAll(typeof(LopisParkour));
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Unbound).GetNestedType("<AddTextWhenReady>d__39", BindingFlags.NonPublic), "MoveNext", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LopisParkour), "PushTheUnboundText", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception s)
			{
				LogError(s);
			}
			try
			{
				int num = 0;
				while (Random.value < 0.5f && num < 9)
				{
					num++;
				}
				if (num == 9 && Random.value < 2f / 3f)
				{
					num++;
					if (Random.value < 0.01f)
					{
						num++;
					}
				}
				parkourTitleCard = LoadTitleSpriteFromPath(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), "title" + num + ".png"));
			}
			catch (Exception s2)
			{
				Log("failed to load the title card");
				Log(s2);
			}
			Log("Loaded!");
		}

		public void Start()
		{
			GameModeManager.AddHandler<GM_Parkour>("Parkour", (IGameModeHandler)(object)new ParkourHandler());
			AddTheButton();
			SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
			{
				if (((Scene)(ref scene)).name == "Main")
				{
					AddTheButton();
				}
			};
			TMP_FontAsset defaultFontAsset = TMP_Settings.defaultFontAsset;
			defaultFontAsset.tabSize = 6;
			GlobalLeaderboard.readUrls();
			GlobalLeaderboard.RequestUpdate();
			CheckForExtraMods();
		}

		public static void CheckForExt