Decompiled source of HardcoreMode v1.0.0

plugins/HardcoreMode.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HardcoreMode.Compat;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HardcoreMode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HardcoreMode")]
[assembly: AssemblyTitle("Hardcore Mode")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace HardcoreMode
{
	internal class BoardingPassCleanup : MonoBehaviour
	{
		private void OnEnable()
		{
			HardcoreModeSettings.Revert();
		}
	}
	internal static class HardcoreModeClearTracking
	{
		public readonly struct StarDisplay
		{
			public readonly bool HasStar1;

			public readonly bool Star1Gold;

			public readonly bool HasStar2;

			public readonly bool Star2Gold;

			public readonly int RedStarCount;

			public StarDisplay(bool hasStar1, bool star1Gold, bool hasStar2, bool star2Gold, int redStarCount)
			{
				HasStar1 = hasStar1;
				Star1Gold = star1Gold;
				HasStar2 = hasStar2;
				Star2Gold = star2Gold;
				RedStarCount = redStarCount;
			}
		}

		private const string ShadowSilverKey = "Hardcore_ShadowSilverMaxAscent";

		private const string ShadowGoldKey = "Hardcore_ShadowGoldMaxAscent";

		private const string ExtremeSilverKey = "Hardcore_ExtremeSilverMaxAscent";

		private const string ExtremeGoldKey = "Hardcore_ExtremeGoldMaxAscent";

		private const string ShadowFastKey = "Hardcore_ShadowFastMaxAscent";

		private const string ExtremeFastKey = "Hardcore_ExtremeFastMaxAscent";

		private const int NotAchievedDefault = -2;

		public const float FastClearSeconds = 3600f;

		public static StarDisplay GetStars(int ascent)
		{
			int qualityAtOrAbove = GetQualityAtOrAbove("Hardcore_ShadowSilverMaxAscent", "Hardcore_ShadowGoldMaxAscent", ascent);
			int qualityAtOrAbove2 = GetQualityAtOrAbove("Hardcore_ExtremeSilverMaxAscent", "Hardcore_ExtremeGoldMaxAscent", ascent);
			bool flag = IsAtOrAbove("Hardcore_ExtremeFastMaxAscent", ascent);
			bool flag2 = IsAtOrAbove("Hardcore_ShadowFastMaxAscent", ascent);
			int redStarCount = (flag ? 2 : (flag2 ? 1 : 0));
			if (qualityAtOrAbove2 > 0)
			{
				int num = Mathf.Max(qualityAtOrAbove, qualityAtOrAbove2);
				return new StarDisplay(hasStar1: true, num == 2, hasStar2: true, qualityAtOrAbove2 == 2, redStarCount);
			}
			if (qualityAtOrAbove > 0)
			{
				return new StarDisplay(hasStar1: true, qualityAtOrAbove == 2, hasStar2: false, star2Gold: false, redStarCount);
			}
			return new StarDisplay(hasStar1: false, star1Gold: false, hasStar2: false, star2Gold: false, 0);
		}

		public static void MarkCleared(int ascent, HardcoreModeTier tier, bool hasBingBong, bool clearedWithinOneHour)
		{
			string key = ((tier != HardcoreModeTier.Extreme) ? (hasBingBong ? "Hardcore_ShadowGoldMaxAscent" : "Hardcore_ShadowSilverMaxAscent") : (hasBingBong ? "Hardcore_ExtremeGoldMaxAscent" : "Hardcore_ExtremeSilverMaxAscent"));
			if (MarkCleared(ascent, key))
			{
				Plugin.Log.LogInfo((object)$"[HardcoreMode] {tier}でアセント{ascent}をクリア済みとして記録しました(ビンボン所持: {hasBingBong})。");
			}
			if (clearedWithinOneHour)
			{
				string key2 = ((tier == HardcoreModeTier.Extreme) ? "Hardcore_ExtremeFastMaxAscent" : "Hardcore_ShadowFastMaxAscent");
				if (MarkCleared(ascent, key2))
				{
					Plugin.Log.LogInfo((object)$"[HardcoreMode] {tier}でアセント{ascent}を1時間以内クリアとして記録しました。");
				}
			}
		}

		private static bool MarkCleared(int ascent, string key)
		{
			int num = PlayerPrefs.GetInt(key, -2);
			if (ascent > num)
			{
				PlayerPrefs.SetInt(key, ascent);
				PlayerPrefs.Save();
				return true;
			}
			return false;
		}

		private static int GetQualityAtOrAbove(string silverKey, string goldKey, int ascent)
		{
			if (ascent <= PlayerPrefs.GetInt(goldKey, -2))
			{
				return 2;
			}
			if (ascent <= PlayerPrefs.GetInt(silverKey, -2))
			{
				return 1;
			}
			return 0;
		}

		private static bool IsAtOrAbove(string key, int ascent)
		{
			return ascent <= PlayerPrefs.GetInt(key, -2);
		}

		public static void DebugForceRecord(int ascent, int shadowQuality, int extremeQuality, bool shadowFast, bool extremeFast)
		{
			switch (shadowQuality)
			{
			case 2:
				MarkCleared(ascent, "Hardcore_ShadowGoldMaxAscent");
				break;
			case 1:
				MarkCleared(ascent, "Hardcore_ShadowSilverMaxAscent");
				break;
			}
			switch (extremeQuality)
			{
			case 2:
				MarkCleared(ascent, "Hardcore_ExtremeGoldMaxAscent");
				break;
			case 1:
				MarkCleared(ascent, "Hardcore_ExtremeSilverMaxAscent");
				break;
			}
			if (shadowFast)
			{
				MarkCleared(ascent, "Hardcore_ShadowFastMaxAscent");
			}
			if (extremeFast)
			{
				MarkCleared(ascent, "Hardcore_ExtremeFastMaxAscent");
			}
			Plugin.Log.LogInfo((object)$"[HardcoreMode] [Debug] アセント{ascent}の記録を格上げ設定: Shadow={shadowQuality}, Extreme={extremeQuality}, ShadowFast={shadowFast}, ExtremeFast={extremeFast}");
		}

		public static void DebugResetAll()
		{
			PlayerPrefs.SetInt("Hardcore_ShadowSilverMaxAscent", -2);
			PlayerPrefs.SetInt("Hardcore_ShadowGoldMaxAscent", -2);
			PlayerPrefs.SetInt("Hardcore_ExtremeSilverMaxAscent", -2);
			PlayerPrefs.SetInt("Hardcore_ExtremeGoldMaxAscent", -2);
			PlayerPrefs.SetInt("Hardcore_ShadowFastMaxAscent", -2);
			PlayerPrefs.SetInt("Hardcore_ExtremeFastMaxAscent", -2);
			PlayerPrefs.Save();
			Plugin.Log.LogInfo((object)"[HardcoreMode] [Debug] ★の記録を全てリセットしました。");
		}
	}
	internal static class HardcoreModeLabels
	{
		public static string BuildLabel(int ascent)
		{
			string text = ((HardcoreModeState.Tier == HardcoreModeTier.Extreme) ? "Extreme" : "Hardcore");
			switch (ascent)
			{
			case -1:
				return text + " Tenderfoot";
			case 0:
				return text + " Peak";
			default:
				if (MoreAscentsCompat.IsChaosAscent(ascent))
				{
					return text + " Chaos " + MoreAscentsCompat.ChaosNumber(ascent);
				}
				return text + " Ascent " + ascent;
			}
		}
	}
	internal class HardcoreModeNetwork : MonoBehaviour
	{
		[PunRPC]
		private void RPC_SetHardcoreMode(int tier)
		{
			HardcoreModeState.SetTier((HardcoreModeTier)tier);
		}
	}
	internal class HardcoreModeOptionMulti : CustomOptionBase
	{
		private static readonly string[] Labels = new string[3] { "Normal", "Hardcore", "Extreme" };

		private TMP_Text? _buttonText;

		private Image? _buttonImage;

		private Color _defaultColor;

		private Color _adjustedColor;

		private readonly List<(Graphic graphic, Color defaultColor)> _tintTargets = new List<(Graphic, Color)>();

		public void Setup(Button button, LocalizedText? buttonText, Image? buttonImage, Color defaultColor, Color adjustedColor)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			if ((Object)(object)buttonText != (Object)null)
			{
				_buttonText = ((Component)buttonText).GetComponent<TMP_Text>();
				Object.Destroy((Object)(object)buttonText);
			}
			_buttonImage = buttonImage;
			_defaultColor = defaultColor;
			_adjustedColor = adjustedColor;
			CollectTintTargets();
			((UnityEventBase)button.onClick).RemoveAllListeners();
			((UnityEvent)button.onClick).AddListener(new UnityAction(((CustomOptionBase)this).OnClick));
			HardcoreModeState.OnChanged += OnStateChanged;
			ApplyPositionFromConfig();
			Refresh();
		}

		private void CollectTintTargets()
		{
			Transform parent = ((Component)this).transform.parent;
			if (!((Object)(object)parent == (Object)null))
			{
				AddTintTarget(parent, "BlueTop");
				AddTintTarget(parent, "BlueBot");
				AddTintTarget(parent, "StartGameButton");
			}
		}

		private void AddTintTarget(Transform parent, string childName)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Transform val = parent.Find(childName);
			Graphic val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Graphic>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				_tintTargets.Add((val2, val2.color));
			}
		}

		private void OnDestroy()
		{
			HardcoreModeState.OnChanged -= OnStateChanged;
		}

		public void ApplyPositionFromConfig()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = default(RectTransform);
			if (((Component)this).TryGetComponent<RectTransform>(ref val))
			{
				val.anchoredPosition = new Vector2(PluginConfig.ModeButtonOffsetX.Value, PluginConfig.ModeButtonOffsetY.Value);
			}
		}

		internal static void ReapplyPositionToAllInstances()
		{
			HardcoreModeOptionMulti[] array = FindAllInstances();
			foreach (HardcoreModeOptionMulti hardcoreModeOptionMulti in array)
			{
				hardcoreModeOptionMulti.ApplyPositionFromConfig();
			}
		}

		internal static void RefreshAllInstances()
		{
			HardcoreModeOptionMulti[] array = FindAllInstances();
			foreach (HardcoreModeOptionMulti hardcoreModeOptionMulti in array)
			{
				hardcoreModeOptionMulti.Refresh();
			}
		}

		private static HardcoreModeOptionMulti[] FindAllInstances()
		{
			return Object.FindObjectsByType<HardcoreModeOptionMulti>((FindObjectsInactive)1, (FindObjectsSortMode)0);
		}

		private void OnStateChanged(HardcoreModeTier tier)
		{
			Refresh();
		}

		public override void OnClick()
		{
			((CustomOptionBase)this).OnClick();
			HardcoreModeTier tier = (HardcoreModeTier)((int)(HardcoreModeState.Tier + 1) % 3);
			HardcoreModeState.SetTier(tier);
			BroadcastState(tier);
			Refresh();
		}

		public override void RestoreDefault()
		{
			((CustomOptionBase)this).RestoreDefault();
			HardcoreModeState.SetTier(HardcoreModeTier.Off);
			BroadcastState(HardcoreModeTier.Off);
			Refresh();
		}

		private void Refresh()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_buttonText != (Object)null)
			{
				_buttonText.text = Labels[(int)HardcoreModeState.Tier];
			}
			bool flag = HardcoreModeState.Tier != HardcoreModeTier.Off;
			if ((Object)(object)_buttonImage != (Object)null)
			{
				((Graphic)_buttonImage).color = (flag ? _adjustedColor : _defaultColor);
			}
			if (flag && PluginConfig.EnableModeBackgroundColor.Value)
			{
				return;
			}
			foreach (var (val, color) in _tintTargets)
			{
				val.color = color;
			}
		}

		private void LateUpdate()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (HardcoreModeState.Tier == HardcoreModeTier.Off || !PluginConfig.EnableModeBackgroundColor.Value)
			{
				return;
			}
			foreach (var (val, b) in _tintTargets)
			{
				if (ColorsApproximatelyEqual(val.color, b))
				{
					val.color = _adjustedColor;
				}
			}
		}

		private static bool ColorsApproximatelyEqual(Color a, Color b)
		{
			//IL_0000: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (Mathf.Abs(a.r - b.r) < 0.05f && Mathf.Abs(a.g - b.g) < 0.05f)
			{
				return Mathf.Abs(a.b - b.b) < 0.05f;
			}
			return false;
		}

		private static void BroadcastState(HardcoreModeTier tier)
		{
			if ((Object)(object)GameUtils.instance != (Object)null)
			{
				GameUtils.instance.photonView.RPC("RPC_SetHardcoreMode", (RpcTarget)0, new object[1] { (int)tier });
			}
		}
	}
	internal static class HardcoreModeSettings
	{
		private static bool _weEnabledCustomRun;

		private static Dictionary<SETTINGTYPE, int>? _settingSnapshot;

		private static Dictionary<string, int>? _itemSnapshot;

		public static void ApplyForAscent(int ascent)
		{
			SnapshotAndResetToDefaults();
			RunSettings.SetValue((SETTINGTYPE)100, (ascent != -1) ? 1 : 0);
			RunSettings.SetValue((SETTINGTYPE)200, (ascent == -1) ? 1 : ((ascent >= 2) ? 3 : 2));
			RunSettings.SetValue((SETTINGTYPE)600, (ascent < 3) ? 1 : 2);
			RunSettings.SetValue((SETTINGTYPE)700, (ascent < 4) ? 1 : 0);
			RunSettings.SetValue((SETTINGTYPE)500, (ascent >= 5) ? 1 : 0);
			RunSettings.SetValue((SETTINGTYPE)800, (ascent >= 6) ? 3 : ((ascent == -1) ? 1 : 2));
			RunSettings.SetValue((SETTINGTYPE)2700, (ascent != -1) ? 1 : 0);
			RunSettings.SetValue((SETTINGTYPE)20000, 1);
			if (HardcoreModeState.Tier == HardcoreModeTier.Extreme)
			{
				RunSettings.SetValue((SETTINGTYPE)400, 3);
			}
			if (!RunSettings.IsCustomRun)
			{
				RunSettings.IsCustomRun = true;
				_weEnabledCustomRun = true;
			}
		}

		public static void Revert()
		{
			RestoreSnapshot();
			if (_weEnabledCustomRun)
			{
				RunSettings.IsCustomRun = false;
				_weEnabledCustomRun = false;
			}
		}

		private static void SnapshotAndResetToDefaults()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			_settingSnapshot = new Dictionary<SETTINGTYPE, int>();
			foreach (SETTINGTYPE value in Enum.GetValues(typeof(SETTINGTYPE)))
			{
				_settingSnapshot[value] = RunSettings.GetValue(value, true);
				RunSettings.SetValue(value, RunSettings.GetDefaultValue(value));
			}
			_itemSnapshot = new Dictionary<string, int>();
			foreach (Item modifiableItemPrefab in RunSettings.ModifiableItemPrefabs)
			{
				string name = ((Object)((Component)modifiableItemPrefab).gameObject).name;
				_itemSnapshot[name] = RunSettings.GetItemValue(name, true);
				RunSettings.SetItemValue(name, 1);
			}
		}

		private static void RestoreSnapshot()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (_settingSnapshot != null)
			{
				foreach (KeyValuePair<SETTINGTYPE, int> item in _settingSnapshot)
				{
					RunSettings.SetValue(item.Key, item.Value);
				}
				_settingSnapshot = null;
			}
			if (_itemSnapshot == null)
			{
				return;
			}
			foreach (KeyValuePair<string, int> item2 in _itemSnapshot)
			{
				RunSettings.SetItemValue(item2.Key, item2.Value);
			}
			_itemSnapshot = null;
		}
	}
	internal enum HardcoreModeTier
	{
		Off,
		Shadow,
		Extreme
	}
	internal static class HardcoreModeState
	{
		public static HardcoreModeTier Tier { get; private set; }

		public static bool Enabled => Tier != HardcoreModeTier.Off;

		public static event Action<HardcoreModeTier>? OnChanged;

		public static void SetTier(HardcoreModeTier tier)
		{
			if (Tier != tier)
			{
				Tier = tier;
				HardcoreModeState.OnChanged?.Invoke(tier);
			}
		}
	}
	[BepInPlugin("HardcoreMode", "Hardcore Mode", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony? _harmony;

		public const string Id = "HardcoreMode";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "Hardcore Mode";

		public static string Version => "1.0.0";

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			PluginConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("HardcoreMode");
			_harmony.PatchAll();
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}
	}
	public enum AirportStaminaTestMode
	{
		Off,
		Casual,
		Extreme
	}
	internal static class PluginConfig
	{
		public static ConfigEntry<AirportStaminaTestMode> StaminaDrainInAirport { get; private set; }

		public static ConfigEntry<bool> EnableAchievementsInHardcoreMode { get; private set; }

		public static ConfigEntry<bool> EnableClimbCountInHardcoreMode { get; private set; }

		public static ConfigEntry<float> ModeButtonOffsetX { get; private set; }

		public static ConfigEntry<float> ModeButtonOffsetY { get; private set; }

		public static ConfigEntry<bool> EnableModeBackgroundColor { get; private set; }

		public static void Bind(ConfigFile config)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			StaminaDrainInAirport = config.Bind<AirportStaminaTestMode>("Hardcore Mode", "StaminaDrainInAirport", AirportStaminaTestMode.Off, "Lets you preview climbing stamina drain inside the airport lobby only. Has no effect on an actual run (after pressing \"Start\" at the kiosk). Casual = same as \"Grapple Mode\" (4x), Extreme = same as Ascent 6+ (5.6x).");
			EnableAchievementsInHardcoreMode = config.Bind<bool>("Hardcore Mode", "EnableAchievementsInHardcoreMode", true, "When ON, unblocks your own Steam achievements while a run has Hardcore Mode (Hardcore/Extreme) enabled. The climb-count stat is handled separately by EnableClimbCountInHardcoreMode below and is not affected by this setting. Vanilla normally blocks all achievements during a Custom Run, but Hardcore Mode only borrows the Custom Run mechanism and otherwise plays like a normal ascent run, so this setting only applies to yourself if you have this mod installed (it has no effect on other players' achievements).");
			EnableClimbCountInHardcoreMode = config.Bind<bool>("Hardcore Mode", "EnableClimbCountInHardcoreMode", true, "When ON, unblocks your own climb-count stat (STEAMSTATTYPE.TimesPeaked) while a run has Hardcore Mode (Hardcore/Extreme) enabled. Achievements themselves are handled separately by EnableAchievementsInHardcoreMode above and are not affected by this setting. This also only applies to yourself if you have this mod installed.");
			ModeButtonOffsetX = config.Bind<float>("Hardcore Mode", "ModeButtonOffsetX", 0f, new ConfigDescription("X position of the Normal/Hardcore/Extreme toggle button on the ascent select screen (offset from the top-left of the header row). The header text width changes depending on the game's language, so adjust this if the button overlaps or overflows.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2000f, 2000f), Array.Empty<object>()));
			ModeButtonOffsetY = config.Bind<float>("Hardcore Mode", "ModeButtonOffsetY", -460f, new ConfigDescription("Y position of the Normal/Hardcore/Extreme toggle button on the ascent select screen (offset from the top-left of the header row).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1000f, 1000f), Array.Empty<object>()));
			ModeButtonOffsetX.SettingChanged += delegate
			{
				HardcoreModeOptionMulti.ReapplyPositionToAllInstances();
			};
			ModeButtonOffsetY.SettingChanged += delegate
			{
				HardcoreModeOptionMulti.ReapplyPositionToAllInstances();
			};
			EnableModeBackgroundColor = config.Bind<bool>("Hardcore Mode", "EnableModeBackgroundColor", true, "When ON, tints the ascent select screen's header background (the \"Boarding Pass\" banner) the same color as the toggle button while Hardcore/Extreme mode is selected. When OFF, the background always stays the vanilla color.");
			EnableModeBackgroundColor.SettingChanged += delegate
			{
				HardcoreModeOptionMulti.RefreshAllInstances();
			};
		}
	}
}
namespace HardcoreMode.Patches
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class AchievementUnblockPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ref bool __result)
		{
			if (!HardcoreModeState.Enabled)
			{
				return true;
			}
			if (!(AchievementIncrementStatContextPatch.InClimbCountStat ? PluginConfig.EnableClimbCountInHardcoreMode.Value : PluginConfig.EnableAchievementsInHardcoreMode.Value))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(AchievementManager), "IncrementSteamStat")]
	internal static class AchievementIncrementStatContextPatch
	{
		internal static bool InClimbCountStat;

		[HarmonyPrefix]
		private static void Prefix(STEAMSTATTYPE steamStatType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			InClimbCountStat = (int)steamStatType == 14;
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			InClimbCountStat = false;
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class AirportStaminaTestPatch
	{
		private const float CasualMultiplier = 4f;

		private const float ExtremeMultiplier = 5.6f;

		[HarmonyPrefix]
		private static bool Prefix(ref float __result)
		{
			if ((Object)(object)GameUtils.instance == (Object)null || !GameUtils.instance.m_inAirport)
			{
				return true;
			}
			switch (PluginConfig.StaminaDrainInAirport.Value)
			{
			case AirportStaminaTestMode.Casual:
				__result = 4f;
				return false;
			case AirportStaminaTestMode.Extreme:
				__result = 5.6f;
				return false;
			default:
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(AscentUI), "Start")]
	internal static class AscentUIPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(AscentUI __instance)
		{
			if (!HardcoreModeState.Enabled)
			{
				return true;
			}
			((TMP_Text)__instance.text).text = HardcoreModeLabels.BuildLabel(Ascents.currentAscent);
			return false;
		}
	}
	[HarmonyPatch(typeof(BoardingPass))]
	internal static class BoardingPassPatches
	{
		private const float CompactWidth = 200f;

		[HarmonyPatch("Initialize")]
		[HarmonyPostfix]
		private static void Initialize_Postfix(BoardingPass __instance)
		{
			TryInject(__instance);
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<BoardingPassCleanup>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<BoardingPassCleanup>();
			}
		}

		[HarmonyPatch("OnOpen")]
		[HarmonyPostfix]
		private static void OnOpen_Postfix(BoardingPass __instance)
		{
			TryInject(__instance);
			HardcoreModeSettings.Revert();
		}

		private static void TryInject(BoardingPass boardingPass)
		{
			//IL_00a5: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Component)boardingPass.closeButton).transform.parent;
			if ((Object)(object)((Component)parent).GetComponentInChildren<HardcoreModeOptionMulti>(true) != (Object)null)
			{
				return;
			}
			CustomOptionsWindow customOptionsWindow = boardingPass.customOptionsWindow;
			if ((Object)(object)customOptionsWindow == (Object)null)
			{
				return;
			}
			CustomOptionMulti val = ((IEnumerable<CustomOptionMulti>)((Component)customOptionsWindow).GetComponentsInChildren<CustomOptionMulti>(true)).FirstOrDefault((Func<CustomOptionMulti, bool>)((CustomOptionMulti t) => (int)t.settingType == 600));
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[HardcoreMode] ItemWeight用のCustomOptionMultiが見つからなかったため、選択肢の追加をスキップしました。");
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
			((Object)val2).name = "HardcoreModeToggle";
			RectTransform val3 = default(RectTransform);
			if (val2.TryGetComponent<RectTransform>(ref val3))
			{
				val3.anchorMin = new Vector2(0f, 1f);
				val3.anchorMax = new Vector2(0f, 1f);
				val3.pivot = new Vector2(0f, 1f);
				val3.sizeDelta = new Vector2(200f, val3.sizeDelta.y);
			}
			CustomOptionMulti component = val2.GetComponent<CustomOptionMulti>();
			Button val4 = (((Object)(object)component != (Object)null) ? component.button : val2.GetComponentInChildren<Button>(true));
			LocalizedText buttonText = (((Object)(object)component != (Object)null) ? component.buttonText : null);
			Image buttonImage = (((Object)(object)component != (Object)null) ? component.buttonImage : null);
			Color defaultColor = (((Object)(object)component != (Object)null) ? component.defaultColor : Color.white);
			Color adjustedColor = (((Object)(object)component != (Object)null) ? component.adjustedColor : Color.white);
			SFX_Instance sfxClick = (((Object)(object)component != (Object)null) ? ((CustomOptionBase)component).sfxClick : null);
			SFX_Instance sfxHover = (((Object)(object)component != (Object)null) ? ((CustomOptionBase)component).sfxHover : null);
			LocalizedText val5 = (((Object)(object)component != (Object)null) ? component.label : null);
			if ((Object)(object)val4 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[HardcoreMode] 複製したGameObjectにButtonが見つからなかったため、選択肢の追加をスキップしました。");
				Object.Destroy((Object)(object)val2);
				return;
			}
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			HardcoreModeOptionMulti hardcoreModeOptionMulti = val2.AddComponent<HardcoreModeOptionMulti>();
			((CustomOptionBase)hardcoreModeOptionMulti).sfxClick = sfxClick;
			((CustomOptionBase)hardcoreModeOptionMulti).sfxHover = sfxHover;
			hardcoreModeOptionMulti.Setup(val4, buttonText, buttonImage, defaultColor, adjustedColor);
			if ((Object)(object)val5 != (Object)null)
			{
				((Component)val5).gameObject.SetActive(false);
			}
			val2.SetActive(!RunSettings.IsCustomRun);
			Plugin.Log.LogInfo((object)"[HardcoreMode] Hardcore Modeの選択肢をアセント選択画面に追加しました。");
		}
	}
	[HarmonyPatch(typeof(BoardingPass), "UpdateAscent")]
	internal static class BoardingPassCustomPlayVisibilityPatch
	{
		[HarmonyPostfix]
		private static void Postfix(BoardingPass __instance)
		{
			HardcoreModeOptionMulti componentInChildren = ((Component)((Component)__instance.closeButton).transform.parent).GetComponentInChildren<HardcoreModeOptionMulti>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(!RunSettings.IsCustomRun);
			}
		}
	}
	[HarmonyPatch(typeof(BoardingPass), "UpdateAscent")]
	internal static class BoardingPassClearStarPatch
	{
		private const string GoldStar = "<color=#C9A227>★</color>";

		private const string SilverStar = "<color=#7D7D7D>★</color>";

		private const string RedStar = "<color=#E0115F>★</color>";

		[HarmonyPostfix]
		private static void Postfix(BoardingPass __instance)
		{
			if (RunSettings.IsCustomRun)
			{
				return;
			}
			HardcoreModeClearTracking.StarDisplay stars = HardcoreModeClearTracking.GetStars(__instance.ascentIndex);
			if (stars.HasStar1)
			{
				string text = " " + (stars.Star1Gold ? "<color=#C9A227>★</color>" : "<color=#7D7D7D>★</color>");
				if (stars.HasStar2)
				{
					text += (stars.Star2Gold ? "<color=#C9A227>★</color>" : "<color=#7D7D7D>★</color>");
				}
				for (int i = 0; i < stars.RedStarCount; i++)
				{
					text += "<color=#E0115F>★</color>";
				}
				TMP_Text ascentTitle = __instance.ascentTitle;
				ascentTitle.text += text;
			}
		}
	}
	[HarmonyPatch(typeof(BoardingPass), "StartGame")]
	internal static class BoardingPassStartGamePatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(600)]
		private static bool Prefix(BoardingPass __instance)
		{
			if (TrueFinalAscentCompat.ShouldDeferToFinalAscentSetup(__instance))
			{
				return true;
			}
			Reconcile.NotifyDeparture(HardcoreModeState.Enabled);
			if (!HardcoreModeState.Enabled || RunSettings.IsCustomRun)
			{
				return true;
			}
			int ascent = TrueFinalAscentCompat.TryGetChosenDifficulty(__instance) ?? __instance.ascentIndex;
			HardcoreModeSettings.ApplyForAscent(ascent);
			if (RandomiserCompat.IsRandomiserActive())
			{
				return true;
			}
			__instance.kiosk.StartGame(__instance.ascentIndex);
			return false;
		}
	}
	[HarmonyPatch(typeof(CharacterItems), "RPC_SpawnItemInHandMaster")]
	internal static class CharacterItemsPatch
	{
		private const string BingBongItemName = "BingBong";

		[HarmonyPrefix]
		private static void Prefix(ref string objName)
		{
			if (HardcoreModeState.Enabled && objName == RunSettings.GRAPPLE_MODE_ITEM)
			{
				objName = "BingBong";
			}
		}
	}
	internal static class ClearTrackingPatch
	{
		private static bool _handlerRegistered;

		public static void EnsureSubscribed()
		{
			if (_handlerRegistered)
			{
				GlobalEvents.OnLocalCharacterWonRun = (Action)Delegate.Remove(GlobalEvents.OnLocalCharacterWonRun, new Action(HandleWonRun));
			}
			GlobalEvents.OnLocalCharacterWonRun = (Action)Delegate.Combine(GlobalEvents.OnLocalCharacterWonRun, new Action(HandleWonRun));
			_handlerRegistered = true;
		}

		private static void HandleWonRun()
		{
			if (HardcoreModeState.Tier != HardcoreModeTier.Off)
			{
				HardcoreModeClearTracking.MarkCleared(Ascents.currentAscent, HardcoreModeState.Tier, HasBingBong(Character.localCharacter), ClearedWithinOneHour());
			}
		}

		private static bool ClearedWithinOneHour()
		{
			if ((Object)(object)RunManager.Instance == (Object)null)
			{
				return false;
			}
			return RunManager.Instance.TimeSinceRunStarted <= 3600f;
		}

		private static bool HasBingBong(Character character)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)character.data.currentItem) && ((Enum)character.data.currentItem.itemTags).HasFlag((Enum)(object)(ItemTags)16))
			{
				return true;
			}
			ItemSlot[] itemSlots = character.player.itemSlots;
			foreach (ItemSlot val in itemSlots)
			{
				if (val != null && (Object)(object)val.prefab != (Object)null && ((Enum)val.prefab.itemTags).HasFlag((Enum)(object)(ItemTags)16))
				{
					return true;
				}
			}
			BackpackData val2 = default(BackpackData);
			if (!((ItemSlot)character.player.backpackSlot).IsEmpty() && ((ItemSlot)character.player.backpackSlot).data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val2))
			{
				ItemSlot[] itemSlots2 = val2.itemSlots;
				foreach (ItemSlot val3 in itemSlots2)
				{
					if (val3 != null && (Object)(object)val3.prefab != (Object)null && ((Enum)val3.prefab.itemTags).HasFlag((Enum)(object)(ItemTags)16))
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(GameUtils))]
	internal static class GameUtilsPatches
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void Awake_Postfix(GameUtils __instance)
		{
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<HardcoreModeNetwork>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<HardcoreModeNetwork>();
			}
			Reconcile.TryRun();
			ClearTrackingPatch.EnsureSubscribed();
		}

		[HarmonyPatch("OnPlayerEnteredRoom")]
		[HarmonyPostfix]
		private static void OnPlayerEnteredRoom_Postfix(GameUtils __instance)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				__instance.photonView.RPC("RPC_SetHardcoreMode", (RpcTarget)0, new object[1] { (int)HardcoreModeState.Tier });
			}
		}
	}
	[HarmonyPatch(typeof(GameUtils), "ApplySerializedRunSettings")]
	internal static class RunSettingsSyncPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			Reconcile.TryRun();
		}
	}
	[HarmonyPatch(typeof(GlobalEvents), "ResetAllRunEvents")]
	internal static class ResetAllRunEventsPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			Reconcile.ClearSuppression();
		}
	}
	internal static class Reconcile
	{
		private static bool _suppressUntilNextDeparture;

		public static void NotifyDeparture(bool hardcoreModeApplied)
		{
			_suppressUntilNextDeparture = !hardcoreModeApplied;
		}

		public static void ClearSuppression()
		{
			_suppressUntilNextDeparture = false;
		}

		public static void TryRun()
		{
			if ((Object)(object)GameUtils.instance == (Object)null)
			{
				Plugin.Log.LogInfo((object)"[HardcoreMode] Reconcile.TryRun: GameUtils.instanceがnullのためスキップ");
				return;
			}
			if (_suppressUntilNextDeparture)
			{
				Plugin.Log.LogInfo((object)"[HardcoreMode] Reconcile.TryRun: 直近の空港出発で非Hardcoreと確定済みのため推定をスキップ");
				return;
			}
			bool flag = RunSettings.IsCustomRun && RunSettings.GetValue((SETTINGTYPE)20000, true) == 1;
			if (flag && HardcoreModeState.Tier == HardcoreModeTier.Off)
			{
				Plugin.Log.LogInfo((object)"[HardcoreMode] RunSettings復元に伴いHardcoreModeStateを再同期: Off -> Shadow");
				HardcoreModeState.SetTier(HardcoreModeTier.Shadow);
			}
			else if (!flag && HardcoreModeState.Tier != HardcoreModeTier.Off)
			{
				Plugin.Log.LogInfo((object)$"[HardcoreMode] RunSettings復元に伴いHardcoreModeStateを再同期: {HardcoreModeState.Tier} -> Off");
				HardcoreModeState.SetTier(HardcoreModeTier.Off);
			}
		}
	}
	[HarmonyPatch(typeof(Spawner), "TrySpawnItems")]
	internal static class SpawnerPatch
	{
		private static bool _overrodeIsCustomRun;

		[HarmonyPrefix]
		private static void Prefix()
		{
			if (PhotonNetwork.IsMasterClient && HardcoreModeState.Enabled && RunSettings.IsCustomRun)
			{
				RunSettings.IsCustomRun = false;
				_overrodeIsCustomRun = true;
			}
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			if (_overrodeIsCustomRun)
			{
				RunSettings.IsCustomRun = true;
				_overrodeIsCustomRun = false;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions), "UpdateWeight")]
	internal static class WeightRecalcSafetyPatch
	{
		private const float RecheckDelaySeconds = 0.5f;

		private static readonly HashSet<CharacterAfflictions> PendingRecheck = new HashSet<CharacterAfflictions>();

		private static bool _suppressing;

		[HarmonyPostfix]
		private static void Postfix(CharacterAfflictions __instance)
		{
			if (!_suppressing && HardcoreModeState.Enabled && !((Object)(object)__instance.character == (Object)null) && __instance.character.IsLocal && PendingRecheck.Add(__instance))
			{
				((MonoBehaviour)__instance).StartCoroutine(RecheckAfterDelay(__instance));
			}
		}

		private static IEnumerator RecheckAfterDelay(CharacterAfflictions afflictions)
		{
			yield return (object)new WaitForSeconds(0.5f);
			PendingRecheck.Remove(afflictions);
			_suppressing = true;
			try
			{
				afflictions.UpdateWeight();
			}
			finally
			{
				_suppressing = false;
			}
		}
	}
}
namespace HardcoreMode.Compat
{
	internal static class MoreAscentsCompat
	{
		internal const int ChaosStartAscent = 14;

		internal static bool IsChaosAscent(int ascent)
		{
			return ascent >= 14;
		}

		internal static int ChaosNumber(int ascent)
		{
			return ascent - 14 + 1;
		}
	}
	internal static class RandomiserCompat
	{
		private const string AssemblyName = "TerrainRandomiser";

		private static bool _resolved;

		private static FieldInfo? _instanceField;

		private static FieldInfo? _mapSettingsField;

		private static FieldInfo? _enableRandomiserField;

		internal static bool IsRandomiserActive()
		{
			try
			{
				EnsureResolved();
				object obj = _instanceField?.GetValue(null);
				if (obj == null || _mapSettingsField == null || _enableRandomiserField == null)
				{
					return false;
				}
				object value = _mapSettingsField.GetValue(obj);
				if (value == null)
				{
					return false;
				}
				return (bool)_enableRandomiserField.GetValue(value);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"[HardcoreMode] RandomiserCompat: チェック失敗(通常処理を続行します): {arg}");
				return false;
			}
		}

		private static void EnsureResolved()
		{
			if (!_resolved)
			{
				_resolved = true;
				Type type = Type.GetType("TerrainRandomiser.Plugin, TerrainRandomiser");
				Type type2 = Type.GetType("TerrainRandomiser.MapSettings, TerrainRandomiser");
				_instanceField = type?.GetField("Instance", BindingFlags.Static | BindingFlags.Public);
				_mapSettingsField = type?.GetField("mapSettings", BindingFlags.Instance | BindingFlags.Public);
				_enableRandomiserField = type2?.GetField("enableRandomiser", BindingFlags.Instance | BindingFlags.Public);
			}
		}
	}
	internal static class TrueFinalAscentCompat
	{
		private const string AssemblyName = "TrueFinalAscent";

		private static bool _resolved;

		private static MethodInfo? _isChosenMethod;

		private static PropertyInfo? _confirmedProperty;

		private static PropertyInfo? _chosenDifficultyProperty;

		internal static bool ShouldDeferToFinalAscentSetup(BoardingPass pass)
		{
			try
			{
				EnsureResolved();
				if (_isChosenMethod == null || _confirmedProperty == null)
				{
					return false;
				}
				if (!(bool)_isChosenMethod.Invoke(null, new object[1] { pass }))
				{
					return false;
				}
				bool flag = (bool)_confirmedProperty.GetValue(null);
				return !flag;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"[HardcoreMode] TrueFinalAscentCompat: チェック失敗(通常処理を続行します): {arg}");
				return false;
			}
		}

		internal static int? TryGetChosenDifficulty(BoardingPass pass)
		{
			try
			{
				EnsureResolved();
				if (_isChosenMethod == null || _chosenDifficultyProperty == null)
				{
					return null;
				}
				if (!(bool)_isChosenMethod.Invoke(null, new object[1] { pass }))
				{
					return null;
				}
				return (int)_chosenDifficultyProperty.GetValue(null);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"[HardcoreMode] TrueFinalAscentCompat: 難易度取得失敗(ascentIndexをそのまま使用します): {arg}");
				return null;
			}
		}

		private static void EnsureResolved()
		{
			if (!_resolved)
			{
				_resolved = true;
				Type type = Type.GetType("TrueFinalAscent.FinalAscentMode, TrueFinalAscent");
				Type type2 = Type.GetType("TrueFinalAscent.FinalAscentSetupWindow, TrueFinalAscent");
				Type type3 = Type.GetType("TrueFinalAscent.FinalAscentDifficulty, TrueFinalAscent");
				_isChosenMethod = type?.GetMethod("IsChosen", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				_confirmedProperty = type2?.GetProperty("Confirmed", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				_chosenDifficultyProperty = type3?.GetProperty("Chosen", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}

plugins/MoreRunDetailsExpand.dll

Decompiled 3 days ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HardcoreMode;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MoreRunDetails;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("com.atomic.details")]
[assembly: IgnoresAccessChecksTo("HardcoreMode")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MoreRunDetailsExpand")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("MoreRunDetailsExpand")]
[assembly: AssemblyTitle("MoreRunDetailsExpand")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace MoreRunDetailsExpand
{
	internal static class HardcoreInterop
	{
		internal const int TierOff = 0;

		internal const int TierShadow = 1;

		internal const int TierExtreme = 2;

		internal static bool Enabled
		{
			get
			{
				try
				{
					return HardcoreModeState.Enabled;
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"[interop] Enabled取得失敗: {arg}");
					return false;
				}
			}
		}

		internal static int CurrentTier
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected I4, but got Unknown
				try
				{
					return (int)HardcoreModeState.Tier;
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"[interop] CurrentTier取得失敗: {arg}");
					return 0;
				}
			}
		}
	}
	internal static class HardcoreLabels
	{
		private const int ChaosStartAscent = 14;

		internal static string Build(int tier, int ascent)
		{
			string text = ((tier == 2) ? "EX." : "H.");
			if (ascent == -1)
			{
				return text + " Tenderfoot";
			}
			if (ascent == 0)
			{
				return text + " Peak";
			}
			if (ascent >= 14)
			{
				return text + " Chaos " + (ascent - 14 + 1).ToString(CultureInfo.InvariantCulture);
			}
			return text + " Ascent " + ascent.ToString(CultureInfo.InvariantCulture);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("MoreRunDetailsExpand", "MoreRunDetailsExpand", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string HardcoreModeGuid = "HardcoreMode";

		private const string MoreRunDetailsGuid = "com.atomic.details";

		private Harmony? _harmony;

		public const string Id = "MoreRunDetailsExpand";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "MoreRunDetailsExpand";

		public static string Version => "0.1.0";

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				_harmony = new Harmony("MoreRunDetailsExpand");
				_harmony.PatchAll(typeof(Plugin).Assembly);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Harmonyパッチの適用に失敗しました。MoreRunDetails/Hardcore Modeのバージョンが想定と異なる可能性があります: {arg}");
				return;
			}
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}
	}
}
namespace MoreRunDetailsExpand.Patches
{
	[HarmonyPatch(typeof(UICreator), "CreateOrUpdate")]
	internal static class AscentLabelPatch
	{
		private const string MarginPath = "Panel/Margin";

		private const string MoreDetailsAscentName = "MoreDetailsAscent";

		[HarmonyPostfix]
		private static void Postfix(EndScreen __0)
		{
			try
			{
				if (!HardcoreInterop.Enabled)
				{
					return;
				}
				if ((Object)(object)__0 == (Object)null)
				{
					Plugin.Log.LogWarning((object)"[AscentLabelPatch] CreateOrUpdateの引数(EndScreen)がnullでした。スキップします。");
					return;
				}
				Transform val = ((Component)__0).transform.Find("Panel/Margin");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				string text = HardcoreLabels.Build(HardcoreInterop.CurrentTier, Ascents.currentAscent);
				for (int i = 0; i < val.childCount; i++)
				{
					Transform child = val.GetChild(i);
					if (!(((Object)child).name != "MoreDetailsAscent"))
					{
						TMP_Text component = ((Component)child).GetComponent<TMP_Text>();
						if ((Object)(object)component != (Object)null)
						{
							component.text = text;
						}
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[AscentLabelPatch] Postfixで例外が発生しました: {arg}");
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}