Decompiled source of Level Select Additions v1.1.5

Distance.LevelSelectAdditions.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Distance.LevelSelectAdditions.Events;
using Distance.LevelSelectAdditions.Extensions;
using Distance.LevelSelectAdditions.Helpers;
using Distance.LevelSelectAdditions.Scripts;
using Distance.LevelSelectAdditions.Scripts.Menus;
using Distance.LevelSelectAdditions.Sorting;
using DistanceModConfigurationManager.DistanceGUI.Menu;
using DistanceModConfigurationManager.Game;
using Events;
using HarmonyLib;
using JsonFx.Json;
using JsonFx.Model;
using JsonFx.Serialization;
using Serializers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Distance.LevelSelectAdditions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Distance.LevelSelectAdditions")]
[assembly: AssemblyCopyright("Copyright © Robert Jordan 2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7bcb2908-b003-45d9-be68-50cba5217603")]
[assembly: AssemblyFileVersion("1.1.4.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.4.2")]
[module: UnverifiableCode]
namespace Distance.LevelSelectAdditions
{
	[BepInPlugin("Distance.LevelSelectAdditions", "Level Select Additions", "1.1.5")]
	public sealed class Mod : BaseUnityPlugin
	{
		private const string modGUID = "Distance.LevelSelectAdditions";

		public const string modName = "Level Select Additions";

		private const string modVersion = "1.1.5";

		public static string HideWorkshopPlaylistsKey = "Hide Workshop Levels in Playlist";

		public static string WorkshopLimitKey = "Workshop Level Limit";

		public static string WorkshopSortingKey = "Workshop Sorting (1st)";

		public static string WorkshopSortingKey2 = "Workshop Sorting (2nd)";

		public static string WorkshopSortingKey3 = "Workshop Sorting (3rd)";

		public static string WorkshopReverseSortingKey = "Reverse Workshop Sorting (1st)";

		public static string WorkshopReverseSortingKey2 = "Reverse Workshop Sorting (2nd)";

		public static string WorkshopReverseSortingKey3 = "Reverse Workshop Sorting (3rd)";

		public static string EnableOtherCampaignKey = "Enable Extra Sprint Campaigns";

		public static string EnableLevelSetOptionsKey = "Enable Playlist Options Menu";

		public static string EnableQuickPlaylistKey = "Enable Playlist Mode for Main Menus";

		public static string EnableVisitWorkshopKey = "Enable Workshop Button for Main Menus";

		public static string EnableRateWorkshopKey = "Enable Rate Workshop Level Button";

		public static string HideUnusedButtonsKey = "Hide Unused Buttons for Main Menus";

		public static string RandomStartupKey = "Decide Menu on Startup";

		public const bool BasicLevelSetOptionsSupported = false;

		private static readonly Harmony harmony = new Harmony("Distance.LevelSelectAdditions");

		public static ManualLogSource Log = new ManualLogSource("Level Select Additions");

		public static Mod Instance;

		public static ConfigEntry<bool> HideWorkshopLevelsInPlaylists { get; set; }

		public static ConfigEntry<int> WorkshopLevelLimit { get; set; }

		public static ConfigEntry<SortingMethod> WorkshopSortingMethod { get; set; }

		public static ConfigEntry<SortingMethod> WorkshopSortingMethod2 { get; set; }

		public static ConfigEntry<SortingMethod> WorkshopSortingMethod3 { get; set; }

		public static ConfigEntry<bool> WorkshopReverseSortingMethod { get; set; }

		public static ConfigEntry<bool> WorkshopReverseSortingMethod2 { get; set; }

		public static ConfigEntry<bool> WorkshopReverseSortingMethod3 { get; set; }

		public static ConfigEntry<bool> EnableTheOtherSideSprintCampaign { get; set; }

		public static ConfigEntry<bool> EnableLevelSetOptionsMenu { get; set; }

		public static ConfigEntry<bool> EnableChooseMainMenuQuickPlaylist { get; set; }

		public static ConfigEntry<bool> EnableChooseMainMenuVisitWorkshopButton { get; set; }

		public static ConfigEntry<bool> EnableRateWorkshopLevelButton { get; set; }

		public static ConfigEntry<bool> HideChooseMainMenuUnusedButtons { get; set; }

		public static ConfigEntry<bool> RandomStartupMainMenu { get; set; }

		public Dictionary<LevelSetMenuType, Dictionary<bool, LevelSetOptionsMenu>> LevelSetOptionsMenus { get; } = new Dictionary<LevelSetMenuType, Dictionary<bool, LevelSetOptionsMenu>>();


		public Dictionary<DisplayType, Dictionary<GameModeID, string>> State_LastLevelSetIDs { get; set; } = new Dictionary<DisplayType, Dictionary<GameModeID, string>>();


		public Dictionary<string, string> ProfileMainMenuLevelSets { get; set; } = new Dictionary<string, string>();


		public Dictionary<string, string> State_LastProfileMainMenuLevels { get; set; } = new Dictionary<string, string>();


		public OptionsMenuLogic OptionsMenu { get; internal set; }

		public void Awake()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Expected O, but got Unknown
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Expected O, but got Unknown
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Expected O, but got Unknown
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Expected O, but got Unknown
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Expected O, but got Unknown
			Object.DontDestroyOnLoad((Object)(object)this);
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Log = Logger.CreateLogSource("Distance.LevelSelectAdditions");
			Dictionary<string, int> dictionary = LevelFilter.GetArbitraryLimitsList().ToDictionary((int l) => LevelFilter.GetLimitName(l));
			Dictionary<string, SortingMethod> dictionary2 = LevelSort.GetSupportedMethodsList().ToDictionary((SortingMethod s) => LevelSort.GetMethodName(s));
			HideWorkshopLevelsInPlaylists = ((BaseUnityPlugin)this).Config.Bind<bool>("General", HideWorkshopPlaylistsKey, false, new ConfigDescription("Exclude levels from the Workshop Level Set that appear in personal playlists.", (AcceptableValueBase)null, new object[0]));
			WorkshopLevelLimit = ((BaseUnityPlugin)this).Config.Bind<int>("General", WorkshopLimitKey, 1000, new ConfigDescription("Set maximum number of levels shown in Workshop Level Set.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 2000), new object[0]));
			WorkshopSortingMethod = ((BaseUnityPlugin)this).Config.Bind<SortingMethod>("General", WorkshopSortingKey, (SortingMethod)1, new ConfigDescription("Choose how Workshop Level Set levels are sorted.", (AcceptableValueBase)null, new object[0]));
			WorkshopReverseSortingMethod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", WorkshopReverseSortingKey, false, new ConfigDescription("Reverse the order of the first Workshop sorting method.", (AcceptableValueBase)null, new object[0]));
			WorkshopSortingMethod2 = ((BaseUnityPlugin)this).Config.Bind<SortingMethod>("General", WorkshopSortingKey2, (SortingMethod)1, new ConfigDescription("Second fallback method for how Workshop Level Set levels are sorted.", (AcceptableValueBase)null, new object[0]));
			WorkshopReverseSortingMethod2 = ((BaseUnityPlugin)this).Config.Bind<bool>("General", WorkshopReverseSortingKey2, false, new ConfigDescription("Reverse the order of the second Workshop sorting method.", (AcceptableValueBase)null, new object[0]));
			WorkshopSortingMethod3 = ((BaseUnityPlugin)this).Config.Bind<SortingMethod>("General", WorkshopSortingKey3, (SortingMethod)1, new ConfigDescription("Third fallback method for how Workshop Level Set levels are sorted.", (AcceptableValueBase)null, new object[0]));
			WorkshopReverseSortingMethod3 = ((BaseUnityPlugin)this).Config.Bind<bool>("General", WorkshopReverseSortingKey3, false, new ConfigDescription("Reverse the order of the third Workshop sorting method.", (AcceptableValueBase)null, new object[0]));
			EnableTheOtherSideSprintCampaign = ((BaseUnityPlugin)this).Config.Bind<bool>("General", EnableOtherCampaignKey, false, new ConfigDescription("Shows extra sprint campaign level sets that aren't normally available (requires unlock).", (AcceptableValueBase)null, new object[0]));
			EnableLevelSetOptionsMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("General", EnableLevelSetOptionsKey, true, new ConfigDescription("Enables the Options menu in the Level Set grid view for customizing personal playlists and choosing main menu collections.", (AcceptableValueBase)null, new object[0]));
			EnableChooseMainMenuQuickPlaylist = ((BaseUnityPlugin)this).Config.Bind<bool>("General", EnableQuickPlaylistKey, true, new ConfigDescription("Allows creating playlists when choosing a Main Menu level (does not allow selecting multiple levels).", (AcceptableValueBase)null, new object[0]));
			EnableChooseMainMenuVisitWorkshopButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", EnableVisitWorkshopKey, true, new ConfigDescription("Enables the 'Visit Workshop page' button in the Advanced level select menu when choosing a Main Menu level.", (AcceptableValueBase)null, new object[0]));
			EnableRateWorkshopLevelButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", EnableRateWorkshopKey, true, new ConfigDescription("Re-introduces the 'Rate this level' button in the Advanced level select menu.", (AcceptableValueBase)null, new object[0]));
			HideChooseMainMenuUnusedButtons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", HideUnusedButtonsKey, true, new ConfigDescription("Hides unused buttons in the Advanced level select menu when choosing a Main Menu level.", (AcceptableValueBase)null, new object[0]));
			RandomStartupMainMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("General", RandomStartupKey, false, new ConfigDescription("When using a playlist for the main menu, a random level will only be chosen when starting up the game. Otherwise a level will be chosen every time the main menu is loaded.", (AcceptableValueBase)null, new object[0]));
			try
			{
				SteamworksHelper.Init();
			}
			catch (Exception ex)
			{
				Log.LogError((object)"Level Select Additions: Error during SteamworksHelper.Init()");
				Log.LogError((object)ex);
				throw;
			}
			State_LastLevelSetIDs = LoadStateLastLevelSetIDs();
			ProfileMainMenuLevelSets = LoadProfileMainMenus("ProfileMainMenuLevelSets.json");
			State_LastProfileMainMenuLevels = LoadProfileMainMenus("State_LastProfileMainMenuLevels.json");
			StaticEvent<PlaylistFileRenamed.Data>.Subscribe((Delegate<PlaylistFileRenamed.Data>)OnPlaylistFileRenamed);
			StaticEvent<PlaylistFileDeleted.Data>.Subscribe((Delegate<PlaylistFileDeleted.Data>)OnPlaylistFileDeleted);
			Log.LogInfo((object)"Level Select Additions: Initializing...");
			harmony.PatchAll();
			Log.LogInfo((object)"Level Select Additions: Initialized!");
		}

		public void SaveDictionary(Dictionary<string, string> dic, string fileName)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			string directoryName = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			DataWriterSettings val = new DataWriterSettings
			{
				PrettyPrint = true
			};
			JsonWriter val2 = new JsonWriter(val);
			try
			{
				using StreamWriter streamWriter = new StreamWriter(Path.Combine(directoryName, fileName), append: false);
				streamWriter.WriteLine(((DataWriter<ModelTokenType>)(object)val2).Write((object)dic));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)ex);
			}
		}

		public void SaveDictionary(Dictionary<LevelSetMenuType, Dictionary<bool, LevelSetOptionsMenu>> dic)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			string path = "LevelSetOptionsMenus.json";
			string directoryName = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			DataWriterSettings val = new DataWriterSettings
			{
				PrettyPrint = true
			};
			JsonWriter val2 = new JsonWriter(val);
			try
			{
				using StreamWriter streamWriter = new StreamWriter(Path.Combine(directoryName, path), append: false);
				streamWriter.WriteLine(((DataWriter<ModelTokenType>)(object)val2).Write((object)dic));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)ex);
			}
		}

		public void SaveDictionary(Dictionary<DisplayType, Dictionary<GameModeID, string>> dic)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			string path = "State_LastLevelSetIDs.json";
			string directoryName = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			DataWriterSettings val = new DataWriterSettings
			{
				PrettyPrint = true
			};
			JsonWriter val2 = new JsonWriter(val);
			try
			{
				using StreamWriter streamWriter = new StreamWriter(Path.Combine(directoryName, path), append: false);
				streamWriter.WriteLine(((DataWriter<ModelTokenType>)(object)val2).Write((object)dic));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)ex);
			}
		}

		public Dictionary<string, string> LoadProfileMainMenus(string fileName)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			string directoryName = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			try
			{
				using StreamReader streamReader = new StreamReader(Path.Combine(directoryName, fileName));
				string text = streamReader.ReadToEnd();
				JsonReader val = new JsonReader();
				return ((DataReader<ModelTokenType>)(object)val).Read<Dictionary<string, string>>(text);
			}
			catch (DirectoryNotFoundException)
			{
				Log.LogWarning((object)"Failed to load car randomization weights due to the directory not existing. \nNew weights will be saved when necessary.");
				return new Dictionary<string, string>();
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)"Failed to load car randomization weights");
				Log.LogWarning((object)ex2);
				return new Dictionary<string, string>();
			}
		}

		public Dictionary<LevelSetMenuType, Dictionary<bool, LevelSetOptionsMenu>> LoadLevelSetOptions()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			string path = "LevelSetOptionsMenus.json";
			string directoryName = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			try
			{
				using StreamReader streamReader = new StreamReader(Path.Combine(directoryName, path));
				string text = streamReader.ReadToEnd();
				JsonReader val = new JsonReader();
				return ((DataReader<ModelTokenType>)(object)val).Read<Dictionary<LevelSetMenuType, Dictionary<bool, LevelSetOptionsMenu>>>(text);
			}
			catch (DirectoryNotFoundException)
			{
				Log.LogWarning((object)"Failed to load car randomization weights due to the directory not existing. \nNew weights will be saved when necessary.");
				return new Dictionary<LevelSetMenuType, Dictionary<bool, LevelSetOptionsMenu>>();
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)"Failed to load car randomization weights");
				Log.LogWarning((object)ex2);
				return new Dictionary<LevelSetMenuType, Dictionary<bool, LevelSetOptionsMenu>>();
			}
		}

		public Dictionary<DisplayType, Dictionary<GameModeID, string>> LoadStateLastLevelSetIDs()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			string path = "State_LastLevelSetIDs.json";
			string directoryName = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			try
			{
				using StreamReader streamReader = new StreamReader(Path.Combine(directoryName, path));
				string text = streamReader.ReadToEnd();
				JsonReader val = new JsonReader();
				return ((DataReader<ModelTokenType>)(object)val).Read<Dictionary<DisplayType, Dictionary<GameModeID, string>>>(text);
			}
			catch (DirectoryNotFoundException)
			{
				Log.LogWarning((object)"Failed to load car randomization weights due to the directory not existing. \nNew weights will be saved when necessary.");
				return new Dictionary<DisplayType, Dictionary<GameModeID, string>>();
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)"Failed to load car randomization weights");
				Log.LogWarning((object)ex2);
				return new Dictionary<DisplayType, Dictionary<GameModeID, string>>();
			}
		}

		public SortingMethod[] GetWorkshopSortingMethods()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected I4, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected I4, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected I4, but got Unknown
			return (SortingMethod[])(object)new SortingMethod[3]
			{
				(SortingMethod)(int)WorkshopSortingMethod.Value,
				(SortingMethod)(int)WorkshopSortingMethod2.Value,
				(SortingMethod)(int)WorkshopSortingMethod3.Value
			};
		}

		public bool[] GetWorkshopReverseSortingMethods()
		{
			return new bool[3] { WorkshopReverseSortingMethod.Value, WorkshopReverseSortingMethod2.Value, WorkshopReverseSortingMethod3.Value };
		}

		public string GetStateLastLevelSetID(DisplayType displayType, GameModeID modeID)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (State_LastLevelSetIDs.TryGetValue(displayType, out var value) && value.TryGetValue(modeID, out var value2))
			{
				return value2;
			}
			return null;
		}

		public void SetStateLastLevelSetID(DisplayType displayType, GameModeID modeID, string levelSetID)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			Dictionary<DisplayType, Dictionary<GameModeID, string>> state_LastLevelSetIDs = State_LastLevelSetIDs;
			if (!state_LastLevelSetIDs.TryGetValue(displayType, out var value))
			{
				value = new Dictionary<GameModeID, string>();
				value[modeID] = levelSetID;
				state_LastLevelSetIDs[displayType] = value;
			}
			SaveDictionary(state_LastLevelSetIDs);
		}

		public string GetProfileMainMenuRelativePathID(string profileName)
		{
			if (ProfileMainMenuLevelSets.TryGetValue(profileName, out var value))
			{
				return value;
			}
			return null;
		}

		public bool SetProfileMainMenuRelativePathID(string profileName, string relativePathID)
		{
			Dictionary<string, string> profileMainMenuLevelSets = ProfileMainMenuLevelSets;
			if (profileMainMenuLevelSets.TryGetValue(profileName, out var value) && relativePathID == value)
			{
				return false;
			}
			SetStateLastMainMenuLevelRelativePath(profileName, null);
			profileMainMenuLevelSets[profileName] = relativePathID;
			SaveDictionary(profileMainMenuLevelSets, "ProfileMainMenuLevelSets.json");
			return true;
		}

		public string GetStateLastMainMenuLevelRelativePath(string profileName)
		{
			if (State_LastProfileMainMenuLevels.TryGetValue(profileName, out var value))
			{
				return value;
			}
			return null;
		}

		public void SetStateLastMainMenuLevelRelativePath(string profileName, string relativeLevelPath)
		{
			State_LastProfileMainMenuLevels[profileName] = relativeLevelPath;
			SaveDictionary(State_LastProfileMainMenuLevels, "State_LastProfileMainMenuLevels.json");
		}

		private void OnPlaylistFileRenamed(PlaylistFileRenamed.Data data)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<DisplayType, Dictionary<GameModeID, string>> state_LastLevelSetIDs = State_LastLevelSetIDs;
			KeyValuePair<DisplayType, Dictionary<GameModeID, string>>[] array = ICollectionEx.ToArray<KeyValuePair<DisplayType, Dictionary<GameModeID, string>>>((ICollection<KeyValuePair<DisplayType, Dictionary<GameModeID, string>>>)state_LastLevelSetIDs);
			for (int i = 0; i < array.Length; i++)
			{
				KeyValuePair<DisplayType, Dictionary<GameModeID, string>> keyValuePair = array[i];
				KeyValuePair<GameModeID, string>[] array2 = ICollectionEx.ToArray<KeyValuePair<GameModeID, string>>((ICollection<KeyValuePair<GameModeID, string>>)keyValuePair.Value);
				for (int j = 0; j < array2.Length; j++)
				{
					KeyValuePair<GameModeID, string> keyValuePair2 = array2[j];
					if (keyValuePair2.Value == data.oldLevelSetID)
					{
						state_LastLevelSetIDs[keyValuePair.Key][keyValuePair2.Key] = data.newLevelSetID;
					}
				}
			}
			Dictionary<string, string> profileMainMenuLevelSets = ProfileMainMenuLevelSets;
			KeyValuePair<string, string>[] array3 = ICollectionEx.ToArray<KeyValuePair<string, string>>((ICollection<KeyValuePair<string, string>>)profileMainMenuLevelSets);
			for (int k = 0; k < array3.Length; k++)
			{
				KeyValuePair<string, string> keyValuePair3 = array3[k];
				if (string.Equals(keyValuePair3.Value, data.oldLevelSetID, StringComparison.InvariantCultureIgnoreCase))
				{
					profileMainMenuLevelSets[keyValuePair3.Key] = data.playlist.GetRelativePathID();
				}
			}
			SaveDictionary(state_LastLevelSetIDs);
			SaveDictionary(profileMainMenuLevelSets, "ProfileMainMenuLevelSets.json");
		}

		private void OnPlaylistFileDeleted(PlaylistFileDeleted.Data data)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<DisplayType, Dictionary<GameModeID, string>> state_LastLevelSetIDs = State_LastLevelSetIDs;
			KeyValuePair<DisplayType, Dictionary<GameModeID, string>>[] array = ICollectionEx.ToArray<KeyValuePair<DisplayType, Dictionary<GameModeID, string>>>((ICollection<KeyValuePair<DisplayType, Dictionary<GameModeID, string>>>)state_LastLevelSetIDs);
			for (int i = 0; i < array.Length; i++)
			{
				KeyValuePair<DisplayType, Dictionary<GameModeID, string>> keyValuePair = array[i];
				KeyValuePair<GameModeID, string>[] array2 = ICollectionEx.ToArray<KeyValuePair<GameModeID, string>>((ICollection<KeyValuePair<GameModeID, string>>)keyValuePair.Value);
				for (int j = 0; j < array2.Length; j++)
				{
					KeyValuePair<GameModeID, string> keyValuePair2 = array2[j];
					if (keyValuePair2.Value == data.levelSetID)
					{
						state_LastLevelSetIDs[keyValuePair.Key][keyValuePair2.Key] = null;
					}
				}
			}
			Dictionary<string, string> profileMainMenuLevelSets = ProfileMainMenuLevelSets;
			KeyValuePair<string, string>[] array3 = ICollectionEx.ToArray<KeyValuePair<string, string>>((ICollection<KeyValuePair<string, string>>)profileMainMenuLevelSets);
			for (int k = 0; k < array3.Length; k++)
			{
				KeyValuePair<string, string> keyValuePair3 = array3[k];
				if (string.Equals(keyValuePair3.Value, data.levelSetID, StringComparison.InvariantCultureIgnoreCase))
				{
					profileMainMenuLevelSets[keyValuePair3.Key] = null;
				}
			}
			SaveDictionary(profileMainMenuLevelSets, "ProfileMainMenuLevelSets.json");
		}

		public void ShowLevelSetOptionsMenu(DisplayType displayType, GameModeID modeID, LevelPlaylist playlist, Action onDeletePlaylist)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			LevelSetMenuType levelSetMenuType = playlist.GetLevelSetMenuType();
			bool key = (int)displayType == 2;
			LevelSetOptionsMenus[levelSetMenuType][key].Show(displayType, modeID, playlist, onDeletePlaylist);
		}
	}
}
namespace Distance.LevelSelectAdditions.Sorting
{
	public class LevelFilter
	{
		public const int Infinite = -1;

		public static int[] GetArbitraryLimitsList()
		{
			return new int[10] { -1, 25, 50, 100, 250, 500, 750, 1000, 1500, 2000 };
		}

		public static string GetLimitName(int limit)
		{
			int num = limit;
			int num2 = num;
			if (num2 == -1)
			{
				return "Infinite";
			}
			return limit.ToString();
		}

		public static void LimitLevels(LevelPlaylist levelPlaylist, int limit)
		{
			if (limit != -1 && limit >= 0)
			{
				levelPlaylist.LimitCountTo(limit);
			}
		}

		public static void ExcludeLevelsInPersonalPlaylists(LevelPlaylist levelPlaylist, GameModeID modeID)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (!DirectoryEx.Exists(Resource.PersonalLevelPlaylistsDirPath_))
			{
				return;
			}
			HashSet<string> hashSet = new HashSet<string>();
			List<string> filePathsInDirWithPattern = Resource.GetFilePathsInDirWithPattern(Resource.PersonalLevelPlaylistsDirPath_, "*.xml", (List<string>)null);
			filePathsInDirWithPattern.RemoveAll((string s) => !Resource.FileExist(s));
			foreach (string item in filePathsInDirWithPattern)
			{
				LevelPlaylist val = LevelGridMenu.LoadPlaylist(item);
				if (!Object.op_Implicit((Object)(object)levelPlaylist))
				{
					Mod.Log.LogWarning((object)("Failed to load: " + item));
				}
				else if (val.Count_ != 0 && val.FirstModeID_ == modeID)
				{
					for (int i = 0; i < val.Count_; i++)
					{
						hashSet.Add(val.GetLevelNameAndPathPairAtIndex(i).levelPath_);
					}
				}
			}
			for (int j = 0; j < levelPlaylist.Count_; j++)
			{
				LevelNameAndPathPair levelNameAndPathPairAtIndex = levelPlaylist.GetLevelNameAndPathPairAtIndex(j);
				if (hashSet.Remove(levelNameAndPathPairAtIndex.levelPath_))
				{
					levelPlaylist.Remove(j);
					j--;
				}
			}
		}
	}
	public class LevelSort
	{
		public class LevelSortEntry
		{
			public LevelNameAndPathPair LevelNameAndPath { get; }

			public GameModeID ModeID { get; }

			public LevelInfo LevelInfo { get; }

			public string AuthorName { get; }

			public LevelProgress LevelProgress { get; }

			public MedalStatus MedalStatus { get; }

			public LevelSortEntry(LevelSelectMenuLogic levelSelectMenu, LevelNameAndPathPair levelNameAndPath)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: 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_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_009e: Unknown result type (might be due to invalid IL or missing references)
				LevelNameAndPath = levelNameAndPath;
				ModeID = levelSelectMenu.modeID_;
				LevelInfo = levelSelectMenu.levelSets_.GetLevelInfo(LevelNameAndPath.levelPath_);
				AuthorName = GetAuthorName(LevelInfo);
				Profile currentProfile_ = levelSelectMenu.currentProfile_;
				object obj;
				if (currentProfile_ == null)
				{
					obj = null;
				}
				else
				{
					ProfileProgress progress_ = currentProfile_.progress_;
					obj = ((progress_ != null) ? progress_.GetLevelProgress(LevelNameAndPath.levelPath_) : null);
				}
				LevelProgress = (LevelProgress)obj;
				MedalStatus = (MedalStatus)0;
				if (LevelProgress != null)
				{
					MedalStatus = LevelProgress.GetMedal(ModeID);
				}
			}

			public LevelSortEntry(LevelGridMenu levelGridMenu, ModeAndLevelInfo modeAndLevelInfo)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				LevelNameAndPath = modeAndLevelInfo.levelNameAndPath_;
				ModeID = levelGridMenu.modeID_;
				LevelInfo = levelGridMenu.levelSets_.GetLevelInfo(LevelNameAndPath.levelPath_);
				AuthorName = GetAuthorName(LevelInfo);
				ProfileProgress profileProgress_ = levelGridMenu.profileProgress_;
				LevelProgress = ((profileProgress_ != null) ? profileProgress_.GetLevelProgress(LevelNameAndPath.levelPath_) : null);
				MedalStatus = (MedalStatus)0;
				if (LevelProgress != null)
				{
					MedalStatus = LevelProgress.GetMedal(ModeID);
				}
			}
		}

		public const SortingMethod None = -1;

		public const SortingMethod Level_Name = 0;

		public const SortingMethod Author = 10;

		public const SortingMethod Recently_Downloaded = 1;

		public const SortingMethod Difficulty = 5;

		public const SortingMethod Finish_Status = 6;

		public const SortingMethod Medal_Earned = 7;

		private readonly Comparison<LevelSortEntry>[] comparisonMethods;

		private readonly bool[] reverseMethods;

		private Dictionary<ModeAndLevelInfo, LevelSortEntry> playlistEntries;

		public static SortingMethod[] GetSupportedMethodsList()
		{
			return (SortingMethod[])(object)new SortingMethod[7]
			{
				(SortingMethod)(-1),
				default(SortingMethod),
				(SortingMethod)10,
				(SortingMethod)1,
				(SortingMethod)5,
				(SortingMethod)6,
				(SortingMethod)7
			};
		}

		public static string GetMethodName(SortingMethod sortingMethod)
		{
			//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)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			SortingMethod val = sortingMethod;
			SortingMethod val2 = val;
			if ((int)val2 == -1)
			{
				return "None";
			}
			return ((object)(SortingMethod)(ref sortingMethod)).ToString().Replace('_', ' ');
		}

		public LevelSort(SortingMethod[] sortingMethods, bool[] reverseMethods)
		{
			List<Comparison<LevelSortEntry>> list = sortingMethods.Select((SortingMethod x) => GetComparison(x)).ToList();
			List<bool> list2 = (reverseMethods ?? new bool[sortingMethods.Length]).ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i] == null)
				{
					list.RemoveAt(i);
					list2.RemoveAt(i);
					i--;
				}
				else if (i > 0 && list[i - 1] == list[i] && list2[i - 1] == list2[i])
				{
					list.RemoveAt(i);
					list2.RemoveAt(i);
					i--;
				}
			}
			comparisonMethods = list.ToArray();
			this.reverseMethods = list2.ToArray();
		}

		private static Comparison<LevelSortEntry> GetComparison(SortingMethod sortingMethod)
		{
			//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)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected I4, but got Unknown
			return (sortingMethod - -1) switch
			{
				1 => CompareLevelName, 
				11 => CompareAuthor, 
				6 => CompareDifficulty, 
				7 => CompareFinishStatus, 
				8 => CompareMedalEarned, 
				2 => CompareMostRecentlyDownloaded, 
				0 => null, 
				_ => null, 
			};
		}

		internal static string GetAuthorName(LevelInfo levelInfo)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			string result = "Unknown";
			if ((int)levelInfo.levelType_ == 2)
			{
				result = "Refract";
			}
			if ((int)levelInfo.levelType_ == 6)
			{
				result = (string.IsNullOrEmpty(levelInfo.levelCreatorName_) ? "Community Creator" : levelInfo.levelCreatorName_);
			}
			else if ((int)levelInfo.levelType_ == 3)
			{
				result = SteamworksManager.GetSteamName(levelInfo.workshopCreatorID_);
			}
			return result;
		}

		public void SortPlaylist(LevelGridMenu levelGridMenu, LevelPlaylist playlist)
		{
			playlistEntries = new Dictionary<ModeAndLevelInfo, LevelSortEntry>();
			foreach (ModeAndLevelInfo item in playlist.playlist_)
			{
				playlistEntries.Add(item, new LevelSortEntry(levelGridMenu, item));
			}
			playlist.Sort((Comparison<ModeAndLevelInfo>)ComparePlaylist);
		}

		private int ComparePlaylist(ModeAndLevelInfo x, ModeAndLevelInfo y)
		{
			LevelSortEntry x2 = playlistEntries[x];
			LevelSortEntry y2 = playlistEntries[y];
			int num = 0;
			int num2 = 0;
			while (num == 0 && num2 < comparisonMethods.Length)
			{
				num = comparisonMethods[num2](x2, y2);
				if (reverseMethods[num2])
				{
					num = -num;
				}
				num2++;
			}
			return num;
		}

		public static int CompareLevelName(LevelSortEntry x, LevelSortEntry y)
		{
			return LevelSelectMenuLogic.CompareAlphabeticalWithSpecialCharLast(x.LevelInfo.levelName_, y.LevelInfo.levelName_);
		}

		public static int CompareAuthor(LevelSortEntry x, LevelSortEntry y)
		{
			return LevelSelectMenuLogic.CompareAlphabeticalWithSpecialCharLast(x.AuthorName, y.AuthorName);
		}

		public static int CompareDifficulty(LevelSortEntry x, LevelSortEntry y)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return ((Enum)(LevelDifficulty)(ref x.LevelInfo.difficulty_)).CompareTo((object?)y.LevelInfo.difficulty_);
		}

		public static int CompareFinishStatus(LevelSortEntry x, LevelSortEntry y)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			bool flag = (int)x.MedalStatus <= 1;
			bool flag2 = (int)y.MedalStatus <= 1;
			if (flag == flag2)
			{
				return 0;
			}
			if (!flag)
			{
				return -1;
			}
			return 1;
		}

		public static int CompareMedalEarned(LevelSortEntry x, LevelSortEntry y)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_0019: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			MedalStatus val = x.MedalStatus;
			MedalStatus val2 = y.MedalStatus;
			if ((int)val < 1)
			{
				val = (MedalStatus)1;
			}
			if ((int)val2 < 1)
			{
				val2 = (MedalStatus)1;
			}
			return ((Enum)(MedalStatus)(ref val2)).CompareTo((object?)val);
		}

		public static int CompareMostRecentlyDownloaded(LevelSortEntry x, LevelSortEntry y)
		{
			return y.LevelInfo.fileLastWriteDateTime_.CompareTo(x.LevelInfo.fileLastWriteDateTime_);
		}
	}
}
namespace Distance.LevelSelectAdditions.Scripts
{
	public class LevelGridButtonCurrentMainMenuLogic : MonoBehaviour
	{
		public const string PlaylistIconSpriteName = "Play";

		public const string CellIconSpriteName = "CameraIcon";

		private const int PlaylistIconSize = 14;

		private const int CellIconSize = 28;

		private const int CellIconLocation = 2;

		public const bool ShowIconImprint = false;

		public const bool ShowIconHighlight = false;

		public const bool ShowIconShadow = true;

		private static readonly Color IconColor = new Color(0.6235f, 0.9059f, 0.502f);

		private static readonly Color IconImprintColor = new Color(0.286f, 0.286f, 0.286f, 0.298f);

		private static readonly Color IconHighlightColor = Color.black;

		private static readonly Color IconShadowColor = new Color(0f, 0f, 0f, 0.502f);

		public InterpolateUIPanelAlphaLogic panelInterp_;

		public UISprite iconSprite_;

		public UISprite iconSpriteShadow_;

		public LevelGridCell GridCell { get; internal set; }

		public LevelGridPlaylistButton PlaylistButton { get; internal set; }

		public LevelGridMenu LevelGridMenu { get; internal set; }

		public bool IsPlaylist { get; internal set; }

		public bool IsCurrentMainMenu { get; internal set; }

		public bool IsCoveringUnplayedCircle => IsCurrentMainMenu && IsPlaylist;

		public void UpdateCurrentMainMenuIcon()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			panelInterp_.Reset(1f);
			if ((int)((LevelSelectMenuAbstract)LevelGridMenu).DisplayType_ == 2)
			{
				Profile currentProfile_ = G.Sys.ProfileManager_.CurrentProfile_;
				string text;
				string text2;
				if (IsPlaylist)
				{
					Entry entry_ = ((UIExButtonListButton)PlaylistButton).entry_;
					PlaylistEntry val = (PlaylistEntry)(object)((entry_ is PlaylistEntry) ? entry_ : null);
					text = val.Playlist_.GetRelativePathID();
					text2 = Mod.Instance.GetProfileMainMenuRelativePathID(currentProfile_.Name_);
				}
				else
				{
					Entry entry_2 = ((UIExButtonListButton)GridCell).entry_;
					LevelEntry val2 = (LevelEntry)(object)((entry_2 is LevelEntry) ? entry_2 : null);
					text = val2.levelInfo_.relativePath_;
					text2 = currentProfile_.MainMenuLevelRelativePath_;
				}
				IsCurrentMainMenu = text2 == text;
				if (IsCurrentMainMenu)
				{
					((UIWidget)iconSprite_).color = IconColor;
				}
				else
				{
					bool flag = false;
				}
				UISprite obj = iconSpriteShadow_;
				if (obj != null)
				{
					((Component)obj).gameObject.SetActive(!IsPlaylist && IsCurrentMainMenu);
				}
				((Component)iconSprite_).gameObject.SetActive(IsCurrentMainMenu);
				if (Object.op_Implicit((Object)(object)iconSpriteShadow_))
				{
					((UIWidget)iconSprite_).depth = 6;
					((UIWidget)iconSpriteShadow_).depth = 5;
				}
			}
			else
			{
				IsCurrentMainMenu = false;
				UISprite obj2 = iconSpriteShadow_;
				if (obj2 != null)
				{
					((Component)obj2).gameObject.SetActive(false);
				}
				((Component)iconSprite_).gameObject.SetActive(false);
			}
		}

		private void Update()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (!IsPlaylist && Object.op_Implicit((Object)(object)iconSprite_) && IsCurrentMainMenu)
			{
				if (((UIExButtonListButton)GridCell).buttonList_.selectedEntry_ != ((UIExButtonListButton)GridCell).entry_ && false)
				{
					((UIWidget)iconSprite_).color = IconHighlightColor;
				}
				else
				{
					((UIWidget)iconSprite_).color = IconColor;
				}
			}
		}

		private bool SetupCurrentMainMenuIcon(GameObject unplayedCircle)
		{
			//IL_0084: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: 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)
			GameObject val = Object.Instantiate<GameObject>(unplayedCircle, unplayedCircle.transform.parent);
			((Object)val).name = "CurrentMainMenuIcon";
			panelInterp_ = val.GetComponent<InterpolateUIPanelAlphaLogic>();
			GameObject gameObject = ((Component)val.transform.Find("Circle")).gameObject;
			if (!Object.op_Implicit((Object)(object)gameObject))
			{
				Mod.Log.LogError((object)"\"Circle\" game object not found");
				return false;
			}
			((Object)gameObject).name = "IconSprite";
			iconSprite_ = gameObject.GetComponent<UISprite>();
			((UIWidget)iconSprite_).color = IconColor;
			if (IsPlaylist)
			{
				iconSprite_.spriteName = "Play";
				((UIWidget)iconSprite_).width = 14;
				((UIWidget)iconSprite_).height = 14;
				Vector3 position = ((Component)panelInterp_).gameObject.transform.position;
				position.x += 0.0025f;
				position.y += 0.0025f;
				((Component)panelInterp_).gameObject.transform.position = position;
			}
			else
			{
				iconSprite_.spriteName = "CameraIcon";
				((UIWidget)iconSprite_).width = 28;
				((UIWidget)iconSprite_).height = 28;
				Vector3 position2 = ((Component)panelInterp_).gameObject.transform.position;
				bool flag = false;
				position2.x += 0.3675f;
				bool flag2 = false;
				position2.y -= 0.2725f;
				((Component)panelInterp_).gameObject.transform.position = position2;
				bool flag3 = true;
				GameObject val2 = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
				((Object)val2).name = "IconSpriteShadow";
				iconSpriteShadow_ = val2.GetComponent<UISprite>();
				((UIWidget)iconSpriteShadow_).color = IconShadowColor;
				iconSpriteShadow_.spriteName = "CameraIcon";
				((UIWidget)iconSpriteShadow_).width = 28;
				((UIWidget)iconSpriteShadow_).height = 28;
				Vector3 localPosition = ((Component)iconSpriteShadow_).transform.localPosition;
				localPosition.x += 1.5f;
				localPosition.y -= 1.5f;
				((Component)iconSpriteShadow_).transform.localPosition = localPosition;
			}
			GameObjectEx.ForEachChildObjectDepthFirstRecursive(val, (Action<GameObject>)delegate(GameObject obj)
			{
				obj.SetActive(true);
			});
			UISprite obj2 = iconSpriteShadow_;
			if (obj2 != null)
			{
				((Component)obj2).gameObject.SetActive(false);
			}
			((Component)iconSprite_).gameObject.SetActive(false);
			return true;
		}

		public static LevelGridButtonCurrentMainMenuLogic GetOrCreate(LevelGridCell gridCell)
		{
			LevelGridButtonCurrentMainMenuLogic levelGridButtonCurrentMainMenuLogic = ((Component)gridCell).GetComponent<LevelGridButtonCurrentMainMenuLogic>();
			if (!Object.op_Implicit((Object)(object)levelGridButtonCurrentMainMenuLogic))
			{
				Entry entry_ = ((UIExButtonListButton)gridCell).entry_;
				LevelEntry val = (LevelEntry)(object)((entry_ is LevelEntry) ? entry_ : null);
				levelGridButtonCurrentMainMenuLogic = ((Component)gridCell).gameObject.AddComponent<LevelGridButtonCurrentMainMenuLogic>();
				levelGridButtonCurrentMainMenuLogic.GridCell = gridCell;
				levelGridButtonCurrentMainMenuLogic.LevelGridMenu = val.levelGridMenu_;
				levelGridButtonCurrentMainMenuLogic.IsPlaylist = false;
				levelGridButtonCurrentMainMenuLogic.SetupCurrentMainMenuIcon(((Component)gridCell.panelInterp_).gameObject);
			}
			return levelGridButtonCurrentMainMenuLogic;
		}

		public static LevelGridButtonCurrentMainMenuLogic GetOrCreate(LevelGridPlaylistButton playlistButton)
		{
			LevelGridButtonCurrentMainMenuLogic levelGridButtonCurrentMainMenuLogic = ((Component)playlistButton).GetComponent<LevelGridButtonCurrentMainMenuLogic>();
			if (!Object.op_Implicit((Object)(object)levelGridButtonCurrentMainMenuLogic))
			{
				Entry entry_ = ((UIExButtonListButton)playlistButton).entry_;
				PlaylistEntry val = (PlaylistEntry)(object)((entry_ is PlaylistEntry) ? entry_ : null);
				levelGridButtonCurrentMainMenuLogic = ((Component)playlistButton).gameObject.AddComponent<LevelGridButtonCurrentMainMenuLogic>();
				levelGridButtonCurrentMainMenuLogic.PlaylistButton = playlistButton;
				levelGridButtonCurrentMainMenuLogic.LevelGridMenu = val.levelGridMenu_;
				levelGridButtonCurrentMainMenuLogic.IsPlaylist = true;
				levelGridButtonCurrentMainMenuLogic.SetupCurrentMainMenuIcon(((Component)playlistButton.panelInterp_).gameObject);
			}
			return levelGridButtonCurrentMainMenuLogic;
		}
	}
	public class LevelPlaylistEntryUpdateLogic : MonoBehaviour
	{
		private LevelGridMenu menu_;

		private void Awake()
		{
			menu_ = ((Component)this).GetComponentInParent<LevelGridMenu>();
			if (!Object.op_Implicit((Object)(object)menu_))
			{
				Mod.Log.LogError((object)"LevelGridMenu component not found");
			}
			StaticEvent<PlaylistNameChanged.Data>.Subscribe((Delegate<PlaylistNameChanged.Data>)OnPlaylistNameChanged);
			StaticEvent<PlaylistColorChanged.Data>.Subscribe((Delegate<PlaylistColorChanged.Data>)OnPlaylistColorChanged);
		}

		private void OnDestroy()
		{
			StaticEvent<PlaylistNameChanged.Data>.Unsubscribe((Delegate<PlaylistNameChanged.Data>)OnPlaylistNameChanged);
			StaticEvent<PlaylistColorChanged.Data>.Unsubscribe((Delegate<PlaylistColorChanged.Data>)OnPlaylistColorChanged);
		}

		private void OnPlaylistNameChanged(PlaylistNameChanged.Data data)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Invalid comparison between Unknown and I4
			//IL_009c: 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)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (PlaylistEntry item in menu_.ScrollableEntries_)
				{
					if (item.Playlist_.GetLevelSetID() == data.levelSetID && (int)item.type_ != 3)
					{
						data.playlist.Name_.DecodeNGUIColorTag(out var stripped);
						((Entry)item).labelText_ = stripped;
						UIExButtonListButton obj = ((UIExButtonContainer)menu_.buttonList_).EntryToButton((Entry)(object)item);
						LevelGridPlaylistButton val = (LevelGridPlaylistButton)(object)((obj is LevelGridPlaylistButton) ? obj : null);
						Color val2 = item.Color_;
						if (!item.unlocked_)
						{
							val2 *= 0.425f;
						}
						((UIWidget)val.name_).color = val2;
						UIButton component = ((Component)val).GetComponent<UIButton>();
						((UIButtonColor)component).defaultColor = val2;
						((UIButtonColor)component).hover = val2;
						if ((int)item.type_ != 3)
						{
							val2.a = 0.25f;
						}
						((UIButtonColor)component).disabledColor = val2;
						val.SetNameLabel(((Entry)item).labelText_);
					}
				}
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in OnPlaylistNameChanged()");
				Mod.Log.LogError((object)ex);
			}
		}

		private void OnPlaylistColorChanged(PlaylistColorChanged.Data data)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Invalid comparison between Unknown and I4
			//IL_009c: 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)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (PlaylistEntry item in menu_.ScrollableEntries_)
				{
					if (item.Playlist_.GetLevelSetID() == data.levelSetID && (int)item.type_ != 3)
					{
						data.playlist.Name_.DecodeNGUIColorTag(out var stripped);
						((Entry)item).labelText_ = stripped;
						UIExButtonListButton obj = ((UIExButtonContainer)menu_.buttonList_).EntryToButton((Entry)(object)item);
						LevelGridPlaylistButton val = (LevelGridPlaylistButton)(object)((obj is LevelGridPlaylistButton) ? obj : null);
						Color val2 = item.Color_;
						if (!item.unlocked_)
						{
							val2 *= 0.425f;
						}
						((UIWidget)val.name_).color = val2;
						UIButton component = ((Component)val).GetComponent<UIButton>();
						((UIButtonColor)component).defaultColor = val2;
						((UIButtonColor)component).hover = val2;
						if ((int)item.type_ != 3)
						{
							val2.a = 0.25f;
						}
						((UIButtonColor)component).disabledColor = val2;
						val.SetNameLabel(((Entry)item).labelText_);
					}
				}
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in OnPlaylistColorChanged()");
				Mod.Log.LogError((object)ex);
			}
		}
	}
	public class LevelSelectWorkshopRateButtonLogic : MonoBehaviour
	{
		private LevelSelectMenuLogic levelSelectMenu_;

		private GameObject visitButton_;

		private GameObject rateButton_;

		private UILabel votingLabel_;

		private float visitButtonNewPositionX_;

		private int visitButtonNewWidth_;

		private float visitButtonOldPositionX_;

		private int visitButtonOldWidth_;

		public void Initialize()
		{
			if (Object.op_Implicit((Object)(object)levelSelectMenu_) && (Object)(object)visitButton_ != (Object)null && (Object)(object)rateButton_ != (Object)null)
			{
				UIWidget component = visitButton_.GetComponent<UIWidget>();
				if (Mod.EnableRateWorkshopLevelButton.Value)
				{
					TransformExtensionOnly.SetGlobalPosX(visitButton_.transform, visitButtonNewPositionX_);
					component.width = visitButtonNewWidth_;
					rateButton_.SetActive(true);
				}
				else
				{
					TransformExtensionOnly.SetGlobalPosX(visitButton_.transform, visitButtonOldPositionX_);
					component.width = visitButtonOldWidth_;
					rateButton_.SetActive(false);
				}
			}
		}

		private void Awake()
		{
			levelSelectMenu_ = ((Component)this).GetComponentInParent<LevelSelectMenuLogic>();
			if (!Object.op_Implicit((Object)(object)levelSelectMenu_))
			{
				Mod.Log.LogError((object)"LevelSelectMenuLogic component not found");
				return;
			}
			SetupWorkshopRateButton();
			Initialize();
		}

		private void Update()
		{
			if (!((Object)(object)levelSelectMenu_ == (Object)null))
			{
				SetRatingText();
				if (levelSelectMenu_.IsMenuActiveAndTop_)
				{
					UpdateInput();
				}
			}
		}

		private void UpdateInput()
		{
			if (!levelSelectMenu_.ignoreMenuInputForOneFrame_ && G.Sys.MenuPanelManager_.MenuInputEnabled_ && !levelSelectMenu_.SearchButtonSelected_)
			{
			}
		}

		private void SetupWorkshopRateButton()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			Transform obj2 = ((Component)this).transform.Find("Panel - Level Select/Anchor - Center/Left Panel/WorkshopItemControlsPanel/VisitWorkshopButton");
			GameObject val = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Mod.Log.LogError((object)"\"VisitWorkshopButton\" game object not found");
				return;
			}
			visitButton_ = val;
			GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent);
			((Object)val2).name = "RateWorkshopLevelButton";
			rateButton_ = val2;
			Vector3 position = val.transform.position;
			Vector3 position2 = position;
			visitButtonOldPositionX_ = position.x;
			position.x -= -0.195f;
			position2.x -= 0.23500001f;
			visitButtonNewPositionX_ = position.x;
			val.transform.position = position;
			val2.transform.position = position2;
			UIWidget component = val.GetComponent<UIWidget>();
			UIWidget component2 = val2.GetComponent<UIWidget>();
			visitButtonOldWidth_ = component.width;
			component2.width = 157;
			visitButtonNewWidth_ = component.width;
			GameObjectEx.ForEachChildObjectDepthFirstRecursive(val2, (Action<GameObject>)delegate(GameObject obj)
			{
				obj.SetActive(true);
			});
			UILabel componentInChildren = val2.GetComponentInChildren<UILabel>();
			componentInChildren.text = "Rate this level";
			votingLabel_ = componentInChildren;
			SetRatingText();
			UIButton[] components = val2.GetComponents<UIButton>();
			foreach (UIButton val3 in components)
			{
				if (val3.onClick != null && val3.onClick.Count > 0)
				{
					val3.onClick.Clear();
					val3.onClick.Add(new EventDelegate(new Callback(OnWorkshopRateButtonClicked)));
					break;
				}
			}
		}

		private void OnWorkshopRateButtonClicked()
		{
			levelSelectMenu_.RateLevel();
		}

		private void SetRatingText()
		{
			if (G.Sys.OptionsManager_.General_.WorkshopRatingPrivacyMode_)
			{
				votingLabel_.text = "Rating: Hidden";
				return;
			}
			switch (levelSelectMenu_.selectedEntry_?.myWorkshopVoteIndex_ ?? 2)
			{
			case 0:
				votingLabel_.text = "My Rating:  [c][96FFB1]+[-][/c]";
				break;
			case 1:
				votingLabel_.text = "My Rating:  [c][FF9796]-[-][/c]";
				break;
			default:
				votingLabel_.text = "My Rating:  None";
				break;
			}
		}
	}
	public class LevelGridLevelSetOptionsLogic : MonoBehaviour
	{
		private LevelGridGrid grid_;

		private void Awake()
		{
			grid_ = ((Component)this).GetComponentInParent<LevelGridGrid>();
			if (!Object.op_Implicit((Object)(object)grid_))
			{
				Mod.Log.LogError((object)"LevelGridGrid component not found");
			}
		}

		private void Update()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (grid_.isGridPushed_ && Mod.EnableLevelSetOptionsMenu.Value)
			{
				bool flag = (int)((LevelSelectMenuAbstract)grid_.levelGridMenu_).displayType_ == 2;
				if ((!grid_.playlist_.IsResourcesPlaylist() || flag) && G.Sys.InputManager_.GetKeyUp((InputAction)45, -2))
				{
					Mod.Instance.ShowLevelSetOptionsMenu(((LevelSelectMenuAbstract)grid_.levelGridMenu_).displayType_, grid_.levelGridMenu_.modeID_, grid_.playlist_, OnDeletePlaylist);
				}
			}
		}

		private void OnDeletePlaylist()
		{
			G.Sys.MenuPanelManager_.Pop(false);
			grid_.levelGridMenu_.CreateEntries();
		}
	}
	public class LevelPlaylistCompoundData : MonoBehaviour
	{
		public LevelPlaylist Playlist { get; internal set; }

		public PlaylistEntry PlaylistEntry { get; internal set; }

		public string FilePath { get; internal set; }

		public GameModeID CustomGameModeID { get; internal set; }

		public LevelGroupFlags LevelGroupFlags { get; internal set; }

		public Type PlaylistType
		{
			get
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				PlaylistEntry playlistEntry = PlaylistEntry;
				return (Type)((playlistEntry == null) ? (-1) : ((int)playlistEntry.type_));
			}
		}
	}
	public class LevelPlaylistSelectRenameLogic : MonoBehaviour
	{
		private LevelSelectMenuLogic levelSelectMenu_;

		private void Awake()
		{
			levelSelectMenu_ = ((Component)this).GetComponentInParent<LevelSelectMenuLogic>();
			if (!Object.op_Implicit((Object)(object)levelSelectMenu_))
			{
				Mod.Log.LogError((object)"LevelSelectMenuLogic component not found");
			}
			else
			{
				SetupPlaylistRenameButton();
			}
		}

		private void SetupPlaylistRenameButton()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Expected O, but got Unknown
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			Transform obj2 = ((Component)this).transform.Find("Panel - Level Select/Anchor - Center/Left Panel/PlaylistButtonGroup2");
			GameObject val = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Mod.Log.LogError((object)"\"PlaylistButtonGroup2\" game object not found");
				return;
			}
			GameObject val2 = null;
			GameObject val3 = null;
			GameObject[] children = GameObjectEx.GetChildren(val);
			foreach (GameObject val4 in children)
			{
				if (((Object)val4).name == "SaveButton")
				{
					val2 = val4;
				}
				else if (((Object)val4).name == "LoadButton")
				{
					val3 = val4;
				}
			}
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3))
			{
				Mod.Log.LogError((object)"\"SaveButton\" and/or \"LoadButton\" component not found");
				return;
			}
			GameObject val5 = Object.Instantiate<GameObject>(val3, val3.transform.parent);
			((Object)val5).name = "PlaylistRenameButton";
			Vector3 localPosition = val2.transform.localPosition;
			Vector3 localPosition2 = val3.transform.localPosition;
			Vector3 localPosition3 = localPosition2;
			float num = (localPosition2.x - localPosition.x) / 2f;
			localPosition.x -= num;
			localPosition2.x -= num;
			localPosition3.x += num;
			val2.transform.localPosition = localPosition;
			val3.transform.localPosition = localPosition2;
			val5.transform.localPosition = localPosition3;
			GameObjectEx.ForEachChildObjectDepthFirstRecursive(val5, (Action<GameObject>)delegate(GameObject obj)
			{
				obj.SetActive(true);
			});
			UILabel componentInChildren = val5.GetComponentInChildren<UILabel>();
			componentInChildren.text = "Name";
			UIButton[] components = val5.GetComponents<UIButton>();
			foreach (UIButton val6 in components)
			{
				if (val6.onClick != null && val6.onClick.Count > 0)
				{
					val6.onClick.Clear();
					val6.onClick.Add(new EventDelegate(new Callback(OnPlaylistRenameButtonClicked)));
					break;
				}
			}
		}

		private void OnPlaylistRenameButtonClicked()
		{
			levelSelectMenu_.tempPlaylist_.PromptRename(OnPlaylistRenameSubmit, null, autoSave: false);
		}

		private void OnPlaylistRenameSubmit(bool changed)
		{
			levelSelectMenu_.UpdateQuickPlaylistText();
		}
	}
}
namespace Distance.LevelSelectAdditions.Scripts.Menus
{
	public enum LevelSetMenuType
	{
		Basic,
		Special,
		Playlist,
		Count
	}
	public static class LevelSetMenuTypeExtensions
	{
		public static LevelSetMenuType GetLevelSetMenuType(this LevelPlaylist playlist)
		{
			if ((Object)(object)playlist == (Object)null || (playlist.IsResourcesPlaylist() && !playlist.IsSpecialLevelSet()))
			{
				return LevelSetMenuType.Basic;
			}
			if (playlist.IsSpecialLevelSet())
			{
				return LevelSetMenuType.Special;
			}
			return LevelSetMenuType.Playlist;
		}
	}
	public class LevelSetOptionsMenu : ModdingMenuAbstract
	{
		protected GameModeID modeID_;

		protected DisplayType displayType_;

		protected LevelPlaylist playlist_;

		protected Action onPopBack_;

		protected Action onDeletePlaylist_;

		public override string Name_ => "custommenu.mod." + "Level Select Additions".ToLower() + ".LevelSetOptionsMenu." + LevelSetMenuType.ToString().ToLower() + (IsMainMenu ? "_mainmenu" : "");

		public override string Title => LevelSetMenuType switch
		{
			LevelSetMenuType.Special => "Special Level Set Options", 
			LevelSetMenuType.Playlist => "Playlist Level Set Options", 
			_ => "Level Set Options", 
		};

		public LevelSetMenuType LevelSetMenuType { get; internal set; }

		public bool IsMainMenu { get; internal set; }

		public GameObject TitleLabel => ((Component)((OptionsSubmenu)this).PanelObject_.transform.Find("MenuTitleTemplate/UILabel - Title")).gameObject;

		public GameObject DescriptionLabel => ((Component)((OptionsSubmenu)this).PanelObject_.transform.Find("MenuTitleTemplate/UILabel - Description")).gameObject;

		public void Show(DisplayType displayType, GameModeID modeID, LevelPlaylist playlist, Action onDeletePlaylist)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				displayType_ = displayType;
				modeID_ = modeID;
				playlist_ = playlist;
				onPopBack_ = null;
				onDeletePlaylist_ = onDeletePlaylist;
				UpdateMenuTitle();
				Mod.Instance.OptionsMenu.DisplaySubmenu(((OptionsSubmenu)this).Name_, (GameObject)null);
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in RenameFile()");
				Mod.Log.LogError((object)ex);
				throw;
			}
		}

		public void RemoveFancyFadeIn()
		{
			if (GameObjectEx.HasComponent<UIExFancyFadeInMenu>(((OptionsSubmenu)this).PanelObject_))
			{
				GameObjectEx.RemoveComponents<UIExFancyFadeInMenu>(((OptionsSubmenu)this).PanelObject_);
			}
		}

		protected void UpdateMenuTitle()
		{
			UILabel component = TitleLabel.GetComponent<UILabel>();
			(((SuperMenu)this).menu_.menuTitleLabel_ ?? component).text = ((ModdingMenuAbstract)this).Title;
		}

		protected void UpdateMenuDescription()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Color color = Color.white;
			LevelPlaylistCompoundData component = ((Component)playlist_).GetComponent<LevelPlaylistCompoundData>();
			if (component?.PlaylistEntry != null)
			{
				color = component.PlaylistEntry.Color_;
			}
			UILabel component2 = TitleLabel.GetComponent<UILabel>();
			UILabel component3 = DescriptionLabel.GetComponent<UILabel>();
			GameObject descriptionLabel = DescriptionLabel;
			if (descriptionLabel != null)
			{
				descriptionLabel.SetActive(true);
			}
			component3.text = playlist_.Name_;
			((UIWidget)component3).color = color;
			component3.fontStyle = component2.fontStyle;
			component3.fontSize = component2.fontSize;
			component3.ambigiousFont = component2.ambigiousFont;
		}

		public override bool DisplayInMenu(bool isPauseMenu)
		{
			return false;
		}

		public override void OnPanelPop()
		{
			onPopBack_?.Invoke();
		}

		public override void Update()
		{
			if ((Object)(object)((OptionsSubmenu)this).PanelObject_ != (Object)null && ((OptionsSubmenu)this).PanelObject_.activeInHierarchy)
			{
				((ModdingMenuAbstract)this).UpdateVirtual();
			}
		}

		public override void UpdateVirtual()
		{
			UpdateMenuDescription();
		}

		public override void InitializeVirtual()
		{
			if (IsMainMenu)
			{
				((SuperMenu)this).TweakAction("SET AS MAIN MENU", (Action)OnSetAsMainMenuClicked, "Use this playlist as the main menu. A level will be chosen from the level set based on your Main Menu playlist selection options.");
				string relativePathID = playlist_.GetRelativePathID();
				Profile currentProfile_ = G.Sys.ProfileManager_.CurrentProfile_;
				string profileMainMenuRelativePathID = Mod.Instance.GetProfileMainMenuRelativePathID(currentProfile_.Name_);
				bool flag = relativePathID == profileMainMenuRelativePathID;
				UILabel componentInChildren = ((Component)((SuperMenu)this).menu_.actions_["SET AS MAIN MENU"]).gameObject.GetComponentInChildren<UILabel>();
				componentInChildren.text = "SET AS MAIN MENU" + (flag ? " (CURRENT)" : "");
			}
			if (LevelSetMenuType == LevelSetMenuType.Special)
			{
			}
			if (LevelSetMenuType == LevelSetMenuType.Playlist)
			{
				((SuperMenu)this).TweakAction("CHANGE DISPLAY NAME", (Action)OnRenamePlaylistClicked, "Change the display name of this playlist.");
				((SuperMenu)this).TweakAction("CHANGE DISPLAY COLOR", (Action)OnRecolorPlaylistClicked, "Change the display color of this playlist. Submit an empty input to remove the color.");
				((SuperMenu)this).TweakAction("RENAME PLAYLIST FILE", (Action)OnRenameFileClicked, "Change the filename of this playlist, which affects sorting order.");
				((SuperMenu)this).TweakAction("DELETE PLAYLIST FILE", (Action)OnDeleteFileClicked, "Delete this playlist from the game.");
			}
		}

		private void OnRenamePlaylistClicked()
		{
			try
			{
				playlist_.PromptRename(null, null, autoSave: true);
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in OnRenamePlaylistClicked()");
				Mod.Log.LogError((object)ex);
			}
		}

		private void OnRecolorPlaylistClicked()
		{
			try
			{
				playlist_.PromptRecolor(null, null, autoSave: true);
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in OnRecolorPlaylistClicked()");
				Mod.Log.LogError((object)ex);
			}
		}

		private void OnRenameFileClicked()
		{
			try
			{
				playlist_.PromptRenameFile(null, null);
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in OnRenameFileClicked()");
				Mod.Log.LogError((object)ex);
			}
		}

		private void OnDeleteFileClicked()
		{
			try
			{
				playlist_.PromptDeleteFile(OnDeleteFileSubmit, destroyObject: true);
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in OnDeleteFileClicked()");
				Mod.Log.LogError((object)ex);
			}
		}

		private void OnDeleteFileSubmit(bool changed)
		{
			try
			{
				G.Sys.MenuPanelManager_.Pop(false);
				onDeletePlaylist_?.Invoke();
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)"Error in OnDeleteFileSubmit()");
				Mod.Log.LogError((object)ex);
			}
		}

		private void OnSetAsMainMenuClicked()
		{
			MainMenuLevelSetHelper.SetMainMenuLevelSet(playlist_);
			G.Sys.GameManager_.GoToMainMenu((OpenOnMainMenuInit)4);
		}
	}
}
namespace Distance.LevelSelectAdditions.Helpers
{
	public static class MainMenuLevelSetHelper
	{
		private static bool StartupLevelChosen { get; set; }

		public static LevelPlaylist LoadFromRelativePathID(string relativePathID)
		{
			bool isName;
			string text = relativePathID.RelativePathIDToAbsolutePath(out isName);
			if (isName)
			{
				LevelSet set = G.Sys.LevelSets_.GetSet((GameModeID)13);
				return (LevelPlaylist)(text switch
				{
					"Official" => LevelPlaylist.Create(set, text, (LevelGroupFlags)3), 
					"Personal" => LevelPlaylist.Create(set, text, (LevelGroupFlags)12), 
					"Workshop" => LevelPlaylist.Create(set, text, (LevelGroupFlags)16), 
					_ => null, 
				});
			}
			GameObject val = LevelPlaylist.Load(text);
			return val.GetComponent<LevelPlaylist>();
		}

		public static bool SetMainMenuLevelSet(LevelPlaylist playlist)
		{
			string relativePathID = null;
			if ((Object)(object)playlist != (Object)null)
			{
				relativePathID = playlist.GetRelativePathID();
			}
			Profile currentProfile_ = G.Sys.ProfileManager_.CurrentProfile_;
			if (Mod.Instance.SetProfileMainMenuRelativePathID(currentProfile_.Name_, relativePathID))
			{
				Mod.Instance.SetStateLastMainMenuLevelRelativePath(currentProfile_.Name_, null);
				currentProfile_.MainMenuLevelRelativePath_ = null;
				if ((Object)(object)playlist != (Object)null)
				{
					ChooseNextMainMenu(force: true);
				}
				return true;
			}
			return false;
		}

		public static void ChooseNextMainMenu(bool force = false)
		{
			Profile currentProfile_ = G.Sys.ProfileManager_.CurrentProfile_;
			if ((Object)(object)currentProfile_ == (Object)null)
			{
				return;
			}
			string stateLastMainMenuLevelRelativePath = Mod.Instance.GetStateLastMainMenuLevelRelativePath(currentProfile_.Name_);
			if (!force && stateLastMainMenuLevelRelativePath != null && StartupLevelChosen && Mod.RandomStartupMainMenu.Value)
			{
				return;
			}
			string profileMainMenuRelativePathID = Mod.Instance.GetProfileMainMenuRelativePathID(currentProfile_.Name_);
			if (profileMainMenuRelativePathID == null)
			{
				return;
			}
			LevelPlaylist val = LoadFromRelativePathID(profileMainMenuRelativePathID);
			if ((Object)(object)val != (Object)null)
			{
				List<LevelInfo> list = (from x in val.Playlist_
					select G.Sys.LevelSets_.GetLevelInfo(x.levelNameAndPath_.levelPath_) into x
					where x.modes_.ContainsKey(13)
					select x).ToList();
				if (list.Count > 0)
				{
					StartupLevelChosen = true;
					Random random = new Random();
					LevelInfo val2 = list[random.Next(0, list.Count)];
					currentProfile_.MainMenuLevelRelativePath_ = val2.relativePath_;
					Mod.Instance.SetStateLastMainMenuLevelRelativePath(currentProfile_.Name_, val2.relativePath_);
				}
			}
		}
	}
	public static class Sanitizer
	{
		[Flags]
		public enum InvalidReason
		{
			Valid = 0,
			TooLong = 1,
			Trailing = 2,
			Reserved = 4
		}

		private static readonly HashSet<string> reservedNames = new HashSet<string>(new string[6] { ".", "..", "CON", "PRN", "AUX", "NUL" }.Concat(from x in Enumerable.Range(1, 9)
			select $"COM{x}").Concat(from x in Enumerable.Range(1, 9)
			select $"LPT{x}"));

		public static bool IsInvalidName(string name, int? maxLength, out InvalidReason reason)
		{
			reason = InvalidReason.Valid;
			if (reservedNames.Contains(name.ToUpperInvariant()))
			{
				reason |= InvalidReason.Reserved;
			}
			int num = name.IndexOf('.');
			if (num != -1 && reservedNames.Contains(name.Substring(0, num).ToUpperInvariant()))
			{
				reason |= InvalidReason.Reserved;
			}
			if (name.Trim().Length != name.Length || name.TrimEnd(new char[1] { '.' }).Length != name.Length)
			{
				reason |= InvalidReason.Trailing;
			}
			if (!maxLength.HasValue)
			{
				maxLength = 260;
			}
			if (maxLength.HasValue && name.Length > maxLength.Value)
			{
				reason |= InvalidReason.TooLong;
			}
			return reason != InvalidReason.Valid;
		}

		public static string SubstituteReservedName(string name, string formatString = "{0}_")
		{
			if (IsInvalidName(name, null, out var reason) && System__EnumExtensions.HasFlag<InvalidReason>(reason, InvalidReason.Reserved))
			{
				string[] array = name.Split(new char[1] { '.' }, 2, StringSplitOptions.None);
				array[0] = string.Format(formatString, array[0]);
				return string.Join(".", array);
			}
			return name;
		}
	}
	public static class SteamworksHelper
	{
		public const int VoteIndex_For = 0;

		public const int VoteIndex_Against = 1;

		public const int VoteIndex_None = 2;

		public static void Init()
		{
		}

		private static Delegate CreateAccessor(Type type, string accessorPath)
		{
			Mod.Log.LogDebug((object)("CreateAccessor: " + type.Name + "." + accessorPath));
			Stopwatch stopwatch = Stopwatch.StartNew();
			ParameterExpression parameterExpression = Expression.Parameter(type, "x");
			Expression expression = parameterExpression;
			string[] array = accessorPath.Split(new char[1] { '.' });
			foreach (string propertyOrFieldName in array)
			{
				expression = Expression.PropertyOrField(expression, propertyOrFieldName);
			}
			Delegate result = Expression.Lambda(expression, parameterExpression).Compile();
			stopwatch.Stop();
			Mod.Log.LogDebug((object)$"CreateAccessor: {stopwatch.ElapsedMilliseconds}ms");
			return result;
		}

		private static Func<T, R> CreateAccessor<T, R>(string accessorPath)
		{
			return (Func<T, R>)CreateAccessor(typeof(T), accessorPath);
		}
	}
}
namespace Distance.LevelSelectAdditions.Patches
{
	[HarmonyPatch(typeof(LevelGridCell), "OnDisplayedVirtual")]
	internal static class LevelGridCell__OnDisplayedVirtual
	{
		[HarmonyPostfix]
		internal static void Postfix(LevelGridCell __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			Entry entry_ = ((UIExButtonListButton)__instance).entry_;
			LevelEntry val = (LevelEntry)(object)((entry_ is LevelEntry) ? entry_ : null);
			bool flag = (int)((LevelSelectMenuAbstract)val.levelGridMenu_).DisplayType_ == 2;
			((Component)__instance.medalLogo_).gameObject.SetActive(!flag);
			LevelGridButtonCurrentMainMenuLogic orCreate = LevelGridButtonCurrentMainMenuLogic.GetOrCreate(__instance);
			if (Object.op_Implicit((Object)(object)orCreate))
			{
				orCreate.UpdateCurrentMainMenuIcon();
				if (orCreate.IsCoveringUnplayedCircle)
				{
					((Component)__instance.unplayed_).gameObject.SetActive(false);
					__instance.isNew_ = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(LevelGridCell), "Update")]
	internal static class LevelGridCell__Update
	{
		[HarmonyPostfix]
		internal static void Postfix(LevelGridCell __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			Entry entry_ = ((UIExButtonListButton)__instance).entry_;
			LevelEntry val = (LevelEntry)(object)((entry_ is LevelEntry) ? entry_ : null);
			if ((int)((LevelSelectMenuAbstract)val.levelGridMenu_).DisplayType_ != 2 && false)
			{
				((Behaviour)__instance).enabled = true;
			}
		}
	}
	[HarmonyPatch(typeof(LevelGridGrid), "PushGrid")]
	internal static class LevelGridGrid__PushGrid
	{
		[HarmonyTranspiler]
		internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			Mod.Log.LogInfo((object)"Transpiling...");
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 3; i < list.Count; i++)
			{
				if (list[i - 2].opcode == OpCodes.Callvirt && ((MethodInfo)list[i - 2].operand).Name == "Push" && list[i].opcode == OpCodes.Call && ((MethodInfo)list[i].operand).Name == "GridPushChange")
				{
					Mod.Log.LogInfo((object)$"call MenuPanel.Push @ {i - 2}");
					List<Label> collection = new List<Label>(list[i - 3].labels);
					list[i - 3].labels.Clear();
					list.InsertRange(i - 3, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)typeof(LevelGridGrid__PushGrid).GetMethod("AddMenuPanelButtons_"))
					});
					list[i - 3].labels.AddRange(collection);
					break;
				}
			}
			return list.AsEnumerable();
		}

		public static void AddMenuPanelButtons_(LevelGridGrid levelGridGrid)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			ComponentEx.GetOrAddComponent<LevelGridLevelSetOptionsLogic>((Component)(object)levelGridGrid);
			if (!Mod.EnableLevelSetOptionsMenu.Value)
			{
				return;
			}
			MenuPanel component = levelGridGrid.gridPanel_.GetComponent<MenuPanel>();
			bool flag = (int)((LevelSelectMenuAbstract)levelGridGrid.levelGridMenu_).displayType_ == 2;
			if (Object.op_Implicit((Object)(object)component) && (!((LevelSelectMenuAbstract)levelGridGrid.levelGridMenu_).IsSimpleMenu_ || flag))
			{
				if (!levelGridGrid.playlist_.IsResourcesPlaylist())
				{
					component.SetBottomLeftButton((InputAction)45, "PLAYLIST\nOPTIONS");
				}
				else if (flag)
				{
					component.SetBottomLeftButton((InputAction)45, "LEVEL SET\nOPTIONS");
				}
			}
		}
	}
	[HarmonyPatch(typeof(LevelGridMenu), "CreateAndAddLevelSet")]
	internal static class LevelGridMenu__CreateAndAddLevelSet
	{
		[HarmonyPrefix]
		internal static bool Prefix(LevelGridMenu __instance, LevelSet set, string name, Type type, LevelGroupFlags flags)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)type == 2)
			{
				LevelPlaylist val = LevelPlaylist.Create(set, name, flags);
				UnlockStyle val2 = (UnlockStyle)7;
				if (Mod.HideWorkshopLevelsInPlaylists.Value)
				{
					LevelFilter.ExcludeLevelsInPersonalPlaylists(val, __instance.modeID_);
				}
				LevelSort levelSort = new LevelSort(Mod.Instance.GetWorkshopSortingMethods(), Mod.Instance.GetWorkshopReverseSortingMethods());
				levelSort.SortPlaylist(__instance, val);
				if (Mod.WorkshopLevelLimit.Value != -1)
				{
					LevelFilter.LimitLevels(val, Mod.WorkshopLevelLimit.Value);
				}
				__instance.CreateAndAddEntry(val, type, true, val2, string.Empty);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(LevelGridMenu), "CreateEntries")]
	internal static class LevelGridMenu__CreateEntries
	{
		[HarmonyTranspiler]
		internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Expected O, but got Unknown
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Expected O, but got Unknown
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Expected O, but got Unknown
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			Mod.Log.LogInfo((object)"Transpiling 1/2...");
			for (int i = 10; i < list.Count; i++)
			{
				if (list[i - 10].opcode.Name.StartsWith("ldloc") && list[i - 9].opcode == OpCodes.Brfalse && list[i - 6].opcode == OpCodes.Callvirt && ((MethodInfo)list[i - 6].operand).Name == "CollectedAllCrabs" && list[i - 5].opcode == OpCodes.Brfalse && list[i - 4].opcode == OpCodes.Ldc_I4_1 && list[i - 2].opcode == OpCodes.Ldc_I4_7 && list[i].opcode == OpCodes.Ldc_I4_S && list[i].operand.ToString() == "16")
				{
					Mod.Log.LogInfo((object)$"callvirt CollectedAllCrabs @ {i - 6}");
					list.RemoveAt(i - 10);
					list.InsertRange(i - 10, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)typeof(LevelGridMenu__CreateEntries).GetMethod("GetTheOtherSideCampaignVisible_"))
					});
					i++;
					list.RemoveAt(i - 4);
					list.InsertRange(i - 4, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)typeof(LevelGridMenu__CreateEntries).GetMethod("GetTheOtherSideCampaignUnlocked_"))
					});
					i++;
					list.RemoveAt(i - 2);
					list.InsertRange(i - 2, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)typeof(LevelGridMenu__CreateEntries).GetMethod("GetTheOtherSideCampaignUnlockStyle_"))
					});
					i++;
					list.RemoveAt(i);
					list.InsertRange(i, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)typeof(LevelGridMenu__CreateEntries).GetMethod("GetTheOtherSideCampaignGameModeID_"))
					});
					i++;
					break;
				}
			}
			Mod.Log.LogInfo((object)"Transpiling 2/2...");
			for (int j = 3; j < list.Count; j++)
			{
				if (!(list[j - 3].opcode == OpCodes.Callvirt) || !(((MethodInfo)list[j - 3].operand).Name == "get_ScrollableEntryCount_") || !(list[j - 2].opcode == OpCodes.Ldc_I4_0) || !(list[j - 1].opcode == OpCodes.Ble))
				{
					continue;
				}
				Mod.Log.LogInfo((object)$"callvirt get_ScrollableEntryCount_ @ {j - 3}");
				for (int k = j; k < list.Count; k++)
				{
					if (list[k].opcode == OpCodes.Call && ((MethodInfo)list[k].operand).Name == "DoNextFrame")
					{
						Mod.Log.LogInfo((object)$"call DoNextFrame @ {k}");
						list.RemoveRange(j, k - j + 1);
						list.InsertRange(j, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
						{
							new CodeInstruction(OpCodes.Ldarg_0, (object)null),
							new CodeInstruction(OpCodes.Call, (object)typeof(LevelGridMenu__CreateEntries).GetMethod("HandleSelectPlaylistEntry_"))
						});
						break;
					}
				}
				break;
			}
			return list.AsEnumerable();
		}

		public static bool GetTheOtherSideCampaignVisible_(LevelGridMenu levelGridMenu)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)((LevelSelectMenuAbstract)levelGridMenu).displayType_ == 3)
			{
				return true;
			}
			return Mod.EnableTheOtherSideSprintCampaign.Value;
		}

		public static bool GetTheOtherSideCampaignUnlocked_(LevelGridMenu levelGridMenu)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)((LevelSelectMenuAbstract)levelGridMenu).displayType_ == 3)
			{
				return true;
			}
			return levelGridMenu.profileProgress_.LevelsCompletedInModePercentage((GameModeID)16) >= 1f;
		}

		public static UnlockStyle GetTheOtherSideCampaignUnlockStyle_(LevelGridMenu levelGridMenu)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((LevelSelectMenuAbstract)levelGridMenu).displayType_ == 3)
			{
				return (UnlockStyle)7;
			}
			return (UnlockStyle)1;
		}

		public static GameModeID GetTheOtherSideCampaignGameModeID_(LevelGridMenu levelGridMenu)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0016: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((LevelSelectMenuAbstract)levelGridMenu).displayType_ == 3)
			{
				return (GameModeID)16;
			}
			return (GameModeID)1;
		}

		public static void HandleSelectPlaylistEntry_(LevelGridMenu levelGridMenu)
		{
			//IL_0028: 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)
			List<PlaylistEntry> scrollableEntries_ = levelGridMenu.ScrollableEntries_;
			int num = -1;
			string lastLevelSetID = Mod.Instance.GetStateLastLevelSetID(((LevelSelectMenuAbstract)levelGridMenu).displayType_, levelGridMenu.modeID_);
			if (!string.IsNullOrEmpty(lastLevelSetID))
			{
				num = scrollableEntries_.FindIndex((PlaylistEntry val) => val.playlist_.GetLevelSetID() == lastLevelSetID);
			}
			string absoluteLevelPath = levelGridMenu.GetSelectedAbsoluteLevelPath();
			if (num == -1 && !string.IsNullOrEmpty(absoluteLevelPath))
			{
				num = scrollableEntries_.FindIndex((PlaylistEntry val) => val.ContainsLevelPath(absoluteLevelPath));
			}
			if (num == -1)
			{
				num = 0;
			}
			levelGridMenu.selectedEntry_ = scrollableEntries_[num];
			ComponentEx.DoNextFrame((MonoBehaviour)(object)levelGridMenu, (Action)delegate
			{
				levelGridMenu.SelectEntry(levelGridMenu.selectedEntry_, true);
			});
		}
	}
	[HarmonyPatch(typeof(LevelGridMenu), "Display")]
	internal static class LevelGridMenu__Display
	{
		[HarmonyPrefix]
		internal static void Prefix(LevelGridMenu __instance)
		{
			ComponentEx.GetOrAddComponent<LevelPlaylistEntryUpdateLogic>((Component)(object)__instance);
		}
	}
	[HarmonyPatch(typeof(LevelGridMenu), "OnGridCellClicked")]
	internal static class LevelGridMenu__OnGridCellClicked
	{
		[HarmonyPrefix]
		internal static void Prefix(LevelGridMenu __instance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (!__instance.levelSelectFinished_ && (int)((LevelSelectMenuAbstract)__instance).displayType_ == 2)
			{
				MainMenuLevelSetHelper.SetMainMenuLevelSet(null);
			}
		}
	}
	[HarmonyPatch(typeof(LevelGridMenu), "OnLevelEntrySelected")]
	internal static class LevelGridMenu__OnLevelEntrySelected
	{
		[HarmonyPrefix]
		internal static void Prefix(LevelGridMenu __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Mod.Instance.SetStateLastLevelSetID(((LevelSelectMenuAbstract)__instance).displayType_, __instance.modeID_, __instance.levelGridGrid_.playlist_.GetLevelSetID());
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class LevelGridMenu_PlaylistEntry__ctor
	{
		[HarmonyPostfix]
		internal static void Postfix(PlaylistEntry __instance)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)__instance.type_ == 1 && ((Entry)__instance).labelText_.DecodeNGUIColorTag(out var stripped))
			{
				((Entry)__instance).labelText_ = stripped;
			}
			LevelPlaylistCompoundData component = ((Component)__instance.Playlist_).GetComponent<LevelPlaylistCompoundData>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.PlaylistEntry = __instance;
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class LevelGridMenu_PlaylistEntry__get_Color_
	{
		[HarmonyPostfix]
		internal static void Postfix(PlaylistEntry __instance, ref Color __result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0023: 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)
			if ((int)__instance.type_ == 1 && __instance.playlist_.GetBaseColor(out var baseColor, alwaysUseBaseColor: false))
			{
				__result = baseColor;
			}
		}
	}
	[HarmonyPatch(typeof(LevelGridPlaylistButton), "OnDisplayedVirtual")]
	internal static class LevelGridPlaylistButton__OnDisplayedVirtual
	{
		[HarmonyPostfix]
		internal static void Postfix(LevelGridPlaylistButton __instance)
		{
			Entry entry_ = ((UIExButtonListButton)__instance).entry_;
			PlaylistEntry val = (PlaylistEntry)(object)((entry_ is PlaylistEntry) ? entry_ : null);
			LevelGridButtonCurrentMainMenuLogic orCreate = LevelGridButtonCurrentMainMenuLogic.GetOrCreate(__instance);
			if (Object.op_Implicit((Object)(object)orCreate))
			{
				orCreate.UpdateCurrentMainMenuIcon();
				if (orCreate.IsCoveringUnplayedCircle)
				{
					((Component)__instance.unplayed_).gameObject.SetActive(false);
					val.isNew_ = false;
				}
			}
		}
	}
	internal static class LevelPlaylist__Create
	{
		[HarmonyPatch(typeof(LevelPlaylist), "Create", new Type[] { typeof(bool) })]
		internal static class LevelPlaylist__Create_overload0
		{
			[HarmonyPostfix]
			internal static void Postfix(ref LevelPlaylist __result)
			{
				LevelPlaylistCompoundData levelPlaylistCompoundData = ((Component)__result).gameObject.AddComponent<LevelPlaylistCompoundData>();
				levelPlaylistCompoundData.Playlist = __result;
			}
		}

		[HarmonyPatch(typeof(LevelPlaylist), "Create", new Type[]
		{
			typeof(LevelSet),
			typeof(string)
		})]
		internal static class LevelPlaylist__Create_overload1
		{
			[HarmonyPostfix]
			internal static void Postfix(ref LevelPlaylist __result)
			{
				LevelPlaylistCompoundData orAddComponent = GameObjectEx.GetOrAddComponent<LevelPlaylistCompoundData>(((Component)__result).gameObject);
				orAddComponent.Playlist = __result;
			}
		}

		[HarmonyPatch(typeof(LevelPlaylist), "Create", new Type[]
		{
			typeof(LevelSet),
			typeof(string),
			typeof(GameModeID)
		})]
		internal static class LevelPlaylist__Create_overload2
		{
			[HarmonyPostfix]
			internal static void Postfix(ref LevelPlaylist __result, GameModeID customGameModeID)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				LevelPlaylistCompoundData orAddComponent = GameObjectEx.GetOrAddComponent<LevelPlaylistCompoundData>(((Component)__result).gameObject);
				orAddComponent.Playlist = __result;
				orAddComponent.CustomGameModeID = customGameModeID;
			}
		}

		[HarmonyPatch(typeof(LevelPlaylist), "Create", new Type[]
		{
			typeof(LevelSet),
			typeof(string),
			typeof(LevelGroupFlags)
		})]
		internal static class LevelPlaylist__Create_overload3
		{
			[HarmonyPostfix]
			internal static void Postfix(ref LevelPlaylist __result, LevelGroupFlags flags)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				LevelPlaylistCompoundData orAddComponent = GameObjectEx.GetOrAddComponent<LevelPlaylistCompoundData>(((Component)__result).gameObject);
				orAddComponent.Playlist = __result;
				orAddComponent.LevelGroupFlags = flags;
			}
		}
	}
	[HarmonyPatch(typeof(LevelPlaylist), "Load")]
	internal static class LevelPlaylist__Load
	{
		[HarmonyPostfix]
		internal static void Postfix(ref GameObject __result, string levelPlaylistPath)
		{
			LevelPlaylistCompoundData levelPlaylistCompoundData = __result.gameObject.AddComponent<LevelPlaylistCompoundData>();
			levelPlaylistCompoundData.FilePath = levelPlaylistPath;
			levelPlaylistCompoundData.Playlist = __result.GetComponent<LevelPlaylist>();
		}
	}
	[HarmonyPatch(typeof(LevelPlaylist), "Save")]
	internal static class LevelPlaylist__Save
	{
		[HarmonyPrefix]
		internal static bool Prefix(LevelPlaylist __instance)
		{
			string text = __instance.GenerateFilePath(assignPath: true);
			XmlSerializer.SaveGameObjectFile(text, ((Component)__instance).gameObject, __instance.playlistPrefab_);
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelSelectMenuLogic), "ClearTempPlaylist")]
	internal static class LevelSelectMenuLogic__ClearTempPlaylist
	{
		[HarmonyPostfix]
		internal static void Postfix(LevelSelectMenuLogic __instance)
		{
			__instance.ResetTempPlaylistState();
			__instance.UpdateBottomLeftButtonVisibility();
		}
	}
	[HarmonyPatch(typeof(LevelSelectMenuLogic), "Initialize")]
	internal static class LevelSelectMenuLogic__Initialize
	{
		[HarmonyPrefix]
		internal static void Prefix(LevelSelectMenuLogic __instance)
		{
			if (((UIInput)__instance.searchInput_).isSelected)
			{
				((UIInput)__instance.searchInput_).OnSelect(false);
			}
			LevelSelectWorkshopRateButtonLogic orAddComponent = ComponentEx.GetOrAddComponent<LevelSelectWorkshopRateButtonLogic>((Component)(object)__instance);
			if (Object.op_Implicit((Object)(object)orAddComponent))
			{
				orAddComponent.Initialize();
			}
			__instance.ResetTempPlaylistState();
		}

		[HarmonyPostfix]
		internal static void Postfix(LevelSelectMenuLogic __instance)
		{
			__instance.UpdateBottomLeftButtonVisibility();
		}
	}
	[HarmonyPatch(typeof(LevelSelectMenuLogic), "OnLevelButtonClicked")]
	internal static class LevelSelectMenuLogic__OnLevelButtonClicked
	{
		[HarmonyPrefix]
		internal static void Prefix(LevelSelectMenuLogic __instance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (!__instance.CurrentLevelLocked_ && (int)((LevelSelectMenuAbstract)__instance).displayType_ == 2)
			{
				MainMenuLevelSetHelper.SetMainMenuLevelSet(null);
			}
		}

		[HarmonyTranspiler]
		internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			Mod.Log.LogInfo((object)"Transpiling...");
			for (int i = 3; i < list.Count; i++)
			{
				if (list[i - 3].opcode == OpCodes.Ldarg_0 && list[i - 2].opcode == OpCodes.Ldfld && ((FieldInfo)list[i - 2].operand).Name == "displayType_" && list[i - 1].opcode == OpCodes.Ldc_I4_2 && list[i].opcode == OpCodes.Bne_Un)
				{
					Mod.Log.LogInfo((object)$"ldfld displayType_ @ {i - 2}");
					Mod.Log.LogInfo((object)$"ldc.i4.2           @ {i - 1}");
					list.RemoveRange(i - 2, 2);
					list.InsertRange(i - 2, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Call, (object)typeof(LevelSelectMenuLogic__OnLevelButtonClicked).GetMethod("AllowMainMenuDisplayTypeForQuickPlaylist_"))
					});
					i--;
					list[i].opcode = OpCodes.Brtrue;
					break;
				}
			}
			return list.AsEnumerable();
		}

		public static bool AllowMainMenuDisplayTypeForQuickPlaylist_(LevelSelectMenuLogic levelSelectMenu)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			if (levelSelectMenu.showingLevelPlaylist_ && Mod.EnableChooseMainMenuQuickPlaylist.Value)
			{
				return true;
			}
			return (int)((LevelSelectMenuAbstract)levelSelectMenu).displayType_ != 2;
		}
	}
	[HarmonyPatch(typeof(LevelSelectMenuLogic), "OnLevelPlaylistMenuClickLoad")]
	internal static class LevelSelectMenuLogic__OnLevelPlaylistMenuClickLoad
	{
		[HarmonyPrefix]
		internal static bool Prefix(LevelSelectMenuLogic __instance, string absolutePath)
		{
			GameObject val = LevelPlaylist.Load(absolutePath);
			if ((Object)(object)val != (Object)null)
			{
				LevelPlaylist component = val.GetComponent<LevelPlaylist>();
				__instance.tempPlaylist_.Clear();
				__instance.tempPlaylist_.CopyFrom(component);
				LevelPlaylistCompoundData component2 = ((Component)__instance.tempPlaylist_).GetComponent<LevelPlaylistCompoundData>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					component2.FilePath = absolutePath;
					component2.Playlist = __instance.tempPlaylist_;
				}
				__instance.SetupLevelPlaylistVisuals();
				__instance.tempPlaylist_.Name_ = component.Name_;
				__instance.UpdateQuickPlaylistText();
				G.Sys.MenuPanelManager_.Pop(false);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelSelectMenuLogic), "OnLevelPlaylistMenuClickSave")]
	internal static class LevelSelectMenuLogic__OnLevelPlaylistMenuClickSave
	{
		[HarmonyPrefix]
		internal static bool Prefix(LevelSelectMenuLogic __instance, string absolutePath)
		{
			string fileName = Resource.GetFileName(absolutePath);
			string text = __instance.quickPlaylistLabel_.text;
			string name_ = __instance.tempPlaylist_.Name_;
			Mod.Log.LogDebug((object)("Saving playlist file:  \"" + fileName +