Decompiled source of PEAK RANKED v0.10.3

plugins/RankedPeak.dll

Decompiled 11 hours ago
using System;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using RankedPeak.Live;
using RankedPeak.Localization;
using RankedPeak.Models;
using RankedPeak.Patches;
using RankedPeak.Seeds;
using RankedPeak.Services;
using RankedPeak.Timer;
using RankedPeak.Tracking;
using RankedPeak.Ui;
using RankedPeak.Ui.Menu;
using RankedPeak.Ui.Native;
using RankedPeak.Utils;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.ControllerSupport;
using Zorro.Core;
using Zorro.Core.CLI;
using Zorro.UI;
using Zorro.UI.Modal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ThomasAusHH")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("PEAK RANKED - Ranked ELO ladder, monthly seasons, daily cup and 1v1 ghost duels for PEAK, with a speedrun timer underneath. Feedback and bug reports welcome on Discord - the channel is linked in the description below")]
[assembly: AssemblyFileVersion("0.10.3.0")]
[assembly: AssemblyInformationalVersion("0.10.3+5107b4bcc1527fc8dc7195e63ee5fb1142b2248b")]
[assembly: AssemblyProduct("RankedPeak")]
[assembly: AssemblyTitle("RankedPeak")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://discord.gg/nKUHvzdmVp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.10.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 RankedPeak
{
	public enum RankedLogLevel
	{
		Error,
		Warning,
		Info,
		Debug
	}
	internal static class RankedLog
	{
		public static void Error(string message)
		{
			if (Enabled(RankedLogLevel.Error))
			{
				Plugin.Log.LogError((object)message);
			}
		}

		public static void Warning(string message)
		{
			if (Enabled(RankedLogLevel.Warning))
			{
				Plugin.Log.LogWarning((object)message);
			}
		}

		public static void Info(string message)
		{
			if (Enabled(RankedLogLevel.Info))
			{
				Plugin.Log.LogInfo((object)message);
			}
		}

		public static void Debug(string message)
		{
			if (Enabled(RankedLogLevel.Debug))
			{
				Plugin.Log.LogDebug((object)message);
			}
		}

		private static bool Enabled(RankedLogLevel level)
		{
			return level <= (Plugin.LogLevel?.Value ?? RankedLogLevel.Info);
		}
	}
	[BepInPlugin("com.rankedpeak.mod", "PEAK RANKED", "0.10.3")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.rankedpeak.mod";

		public const string PluginName = "PEAK RANKED";

		public const string PluginVersion = "0.10.3";

		public const string VersionLabel = "Beta";

		private Harmony _harmony;

		private RunStorageService _storageService;

		private RaceTimer _raceTimer;

		private ClimbStorageService _climbStorageService;

		private SeedService _seedService;

		public static string DisplayVersion
		{
			get
			{
				if (!string.IsNullOrEmpty("Beta"))
				{
					return "0.10.3 Beta";
				}
				return "0.10.3";
			}
		}

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<KeyCode> OverlayToggleKey { get; private set; }

		internal static ConfigEntry<float> OverlayPositionX { get; private set; }

		internal static ConfigEntry<float> OverlayPositionY { get; private set; }

		internal static ConfigEntry<KeyCode> RunResetKey { get; private set; }

		internal static ConfigEntry<GameMode> SelectedMode { get; private set; }

		internal static ConfigEntry<bool> DebugSpawnLogging { get; private set; }

		internal static ConfigEntry<RankedLogLevel> LogLevel { get; private set; }

		internal static ConfigEntry<KeyCode> RaceMenuKey { get; private set; }

		internal static ConfigEntry<bool> GhostEnabled { get; private set; }

		internal static ConfigEntry<float> GhostOpacity { get; private set; }

		internal static ConfigEntry<bool> GhostItemsEnabled { get; private set; }

		internal static ConfigEntry<bool> RaceHudEnabled { get; private set; }

		internal static ConfigEntry<float> RaceHudX { get; private set; }

		internal static ConfigEntry<float> RaceHudY { get; private set; }

		internal static ConfigEntry<bool> ComparisonManual { get; private set; }

		internal static ConfigEntry<bool> GhostPanelEnabled { get; private set; }

		internal static ConfigEntry<float> GhostPanelX { get; private set; }

		internal static ConfigEntry<float> GhostPanelY { get; private set; }

		internal static ConfigEntry<bool> UseNativeTimer { get; private set; }

		internal static ConfigEntry<bool> ShowRunSummary { get; private set; }

		internal static ConfigEntry<bool> SummaryMinimized { get; private set; }

		internal static ConfigEntry<KeyCode> SettingsMenuKey { get; private set; }

		internal static ConfigFile ConfigFile { get; private set; }

		internal static RunStorageService StorageService { get; private set; }

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)("PEAK RANKED " + DisplayVersion + " geladen. API: https://followme-peak.ddns.net"));
			InitializeConfig();
			Loc.Initialize();
			InitializeServices();
			ApplyHarmonyPatches();
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void InitializeConfig()
		{
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			ConfigFile = ((BaseUnityPlugin)this).Config;
			OverlayToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Overlay", "ToggleKey", (KeyCode)289, "Hotkey zum Ein-/Ausblenden des Timer-Overlays.");
			OverlayPositionX = ((BaseUnityPlugin)this).Config.Bind<float>("Overlay", "PositionX", 10f, "Overlay X-Position in Pixeln (von links).");
			OverlayPositionY = ((BaseUnityPlugin)this).Config.Bind<float>("Overlay", "PositionY", 10f, "Overlay Y-Position in Pixeln (von oben).");
			UseNativeTimer = ((BaseUnityPlugin)this).Config.Bind<bool>("Overlay", "UseNativeTimer", true, "true = natives uGUI-Timer-Panel (E4.3) statt IMGUI-Overlay. Position (PositionX/Y) und Toggle (F8) gelten fuer beide.");
			RunResetKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "RunResetKey", (KeyCode)0, "Soft-Reset-Hotkey (E1.5): verwirft den laufenden Run und armiert den Timer neu (State -> Armed). KeyCode.None = deaktiviert. Kein hartes Level-Reload - das waere ein Spiel-Logik-Eingriff und bleibt bewusst aussen vor.");
			SelectedMode = ((BaseUnityPlugin)this).Config.Bind<GameMode>("Ranked", "GameMode", GameMode.StaticDaily, "Modus des naechsten Runs. Setzen die Schilder im Hauptmenue - der Wert hier dient nur als Ausgangswert und zur Diagnose.");
			DebugSpawnLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "SpawnLogging", false, "true = loggt jeden Spawn-Vorgang (Spawner, Position, Items) ins BepInEx-Log. Fuer die Seed-Verifikation (docs/seed-spike.md §8): zwei Runs mit gleichem Seed muessen identische Logs liefern. Eigener Schalter, unabhaengig von LogLevel.");
			LogLevel = ((BaseUnityPlugin)this).Config.Bind<RankedLogLevel>("Debug", "LogLevel", RankedLogLevel.Info, "Schwellenwert fuer alle Log-Zeilen des Mods (RankedLog): Error = nur Fehler, Warning = zusaetzlich Warnungen, Info = zusaetzlich normale Ablaufmeldungen (Vorgabe), Debug = zusaetzlich ausfuehrliche Diagnosemeldungen. Wirkt sofort, kein Neustart noetig. Der Start-Banner und das SpawnLogging-Protokoll haengen bewusst nicht an dieser Stufe.");
			RaceMenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "RaceMenuKey", (KeyCode)287, "Hotkey fuer das Race-Menue (Code, Teilnehmer, Verlassen) - auch im Flughafen und waehrend eines Rennens. KeyCode.None = deaktiviert.");
			SettingsMenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "SettingsMenuKey", (KeyCode)288, "Hotkey fuer das Einstellungsfenster (RankedSettingsModal) - im Hauptmenue wie auf dem Berg. Alle Werte dieser Datei lassen sich dort im Spiel setzen; das Fenster ist die eigentliche Bedienung, diese Datei nur ihr Speicherort. KeyCode.None = deaktiviert (dann bleibt das Schild EINSTELLUNGEN im Hauptmenue der einzige Weg).");
			GhostEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Ranked", "GhostEnabled", true, "true = waehrend eines Runs laeuft der eigene PB-Ghost mit (E5.5): ein durchsichtiger, nicht-kollidierender Marker auf dem Pfad des schnellsten eigenen Completed-Climbs (gleiche Map + Modus, lokale climbs.json).");
			GhostOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Ranked", "GhostOpacity", 0.6f, new ConfigDescription("Deckkraft des Ghosts: 0 = unsichtbar, 1 = undurchsichtig. Wirkt sofort, auch waehrend ein Ghost laeuft. Das Einstellungsfenster bietet drei Stufen an (0.35 / 0.6 / 0.85); hier ist jeder Wert dazwischen erlaubt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
			GhostItemsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Ranked", "GhostItemsEnabled", true, "true = der Ghost haelt das Item in der Hand, das der Laeufer an dieser Stelle hielt. Aus, wenn das im Rennen zu viel Bewegung im Bild ist - die Aufzeichnung laeuft unabhaengig davon weiter und das Ghost-Panel zeigt das Inventar ohnehin.");
			ComparisonManual = ((BaseUnityPlugin)this).Config.Bind<bool>("Ranked", "ComparisonManual", false, "false = der Vergleich im Timer ist automatisch der schnellste eigene Lauf auf derselben Karte und Strecke. true = es gilt der Lauf, den du in der Rangliste unter MEINE LAEUFE festgenagelt hast; ohne Wahl greift wieder die Automatik.");
			RaceHudEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Overlay", "RaceHudEnabled", true, "true = waehrend eines Rennens zeigt die Renn-Anzeige den Zwischenstand: Platz, Name, Fortschritt, Leisten und Items je Teilnehmer.");
			RaceHudX = ((BaseUnityPlugin)this).Config.Bind<float>("Overlay", "RaceHudPositionX", 1510f, "X-Position der Renn-Anzeige in Canvas-Einheiten, von links. Bequemer ueber das Einstellungsfenster zu setzen: dort haengt sich die Anzeige an die Maus.");
			RaceHudY = ((BaseUnityPlugin)this).Config.Bind<float>("Overlay", "RaceHudPositionY", 20f, "Y-Position der Renn-Anzeige in Canvas-Einheiten, von oben.");
			GhostPanelEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Ranked", "GhostPanelEnabled", true, "true = waehrend eines Laufs gegen einen fremden Ghost zeigt ein kleines Panel dessen Uhr, Ausdauer, Statuswerte und Inventar (E5.7).");
			GhostPanelX = ((BaseUnityPlugin)this).Config.Bind<float>("Ranked", "GhostPanelPositionX", 10f, "X-Position des Ghost-Panels in Canvas-Einheiten, von links. Bequemer ueber das Einstellungsfenster zu setzen: dort haengt sich das Panel an die Maus.");
			GhostPanelY = ((BaseUnityPlugin)this).Config.Bind<float>("Ranked", "GhostPanelPositionY", 260f, "Y-Position des Ghost-Panels in Canvas-Einheiten, von oben.");
			SummaryMinimized = ((BaseUnityPlugin)this).Config.Bind<bool>("Overlay", "SummaryMinimized", false, "true = der Ergebnis-Screen erscheint zusammengeklappt als schmale Leiste am unteren Bildrand und gibt den Pfadfinderbericht des Spiels frei. Der Knopf in der Titelleiste des Fensters schreibt diesen Wert - wer einmal zuklappt, bekommt es beim naechsten Lauf gleich klein.");
			ShowRunSummary = ((BaseUnityPlugin)this).Config.Bind<bool>("Overlay", "ShowRunSummary", true, "true = nach Run-Ende erscheint der Summary-Screen (E4.4): Ergebnis, Gesamtzeit, Splits, PB-Vergleich, Upload-Status und Daily-Board-Platzierung. Schliesst automatisch beim naechsten Run.");
		}

		private void InitializeServices()
		{
			//IL_0037: 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_0042: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0083: 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_008e: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Expected O, but got Unknown
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Expected O, but got Unknown
			_storageService = new RunStorageService();
			StorageService = _storageService;
			_raceTimer = new RaceTimer(_storageService);
			_raceTimer.Arm();
			GameObject val = new GameObject("RankedPeak_TimerOverlay");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<TimerOverlay>().Initialize(_raceTimer, _storageService);
			GameObject val2 = new GameObject("RankedPeak_NativeTimerPanel");
			Object.DontDestroyOnLoad((Object)val2);
			val2.AddComponent<NativeTimerPanel>().Initialize(_raceTimer, _storageService);
			GameObject val3 = new GameObject("RankedPeak_RunSummary");
			Object.DontDestroyOnLoad((Object)val3);
			val3.AddComponent<RunSummaryPanel>().Initialize(_raceTimer, _storageService);
			GameObject val4 = new GameObject("RankedPeak_Settings");
			Object.DontDestroyOnLoad((Object)val4);
			val4.AddComponent<RankedSettingsModal>();
			GameObject val5 = new GameObject("RankedPeak_Help");
			Object.DontDestroyOnLoad((Object)val5);
			val5.AddComponent<RankedHelpModal>();
			GameObject val6 = new GameObject("RankedPeak_RunUpload");
			Object.DontDestroyOnLoad((Object)val6);
			RunUploadService uploadService = val6.AddComponent<RunUploadService>();
			GameObject val7 = new GameObject("RankedPeak_RunSentinel");
			Object.DontDestroyOnLoad((Object)val7);
			val7.AddComponent<RunSentinel>();
			_climbStorageService = new ClimbStorageService();
			GameObject val8 = new GameObject("RankedPeak_ClimbTracking");
			Object.DontDestroyOnLoad((Object)val8);
			val8.AddComponent<ClimbTrackingService>().Initialize(_raceTimer, _climbStorageService, uploadService);
			GameObject val9 = new GameObject("RankedPeak_GhostStatus");
			Object.DontDestroyOnLoad((Object)val9);
			val9.AddComponent<GhostStatusPanel>();
			GameObject val10 = new GameObject("RankedPeak_GhostPlayback");
			Object.DontDestroyOnLoad((Object)val10);
			val10.AddComponent<GhostPlaybackService>().Initialize(_raceTimer, _climbStorageService);
			_seedService = new SeedService();
			GameObject val11 = new GameObject("RankedPeak_DailySeed");
			Object.DontDestroyOnLoad((Object)val11);
			val11.AddComponent<DailySeedService>().RefreshIfStale();
			GameObject val12 = new GameObject("RankedPeak_ModAllowlist");
			Object.DontDestroyOnLoad((Object)val12);
			val12.AddComponent<ModAllowlistService>().RefreshIfStale();
			GameObject val13 = new GameObject("RankedPeak_RatingService");
			Object.DontDestroyOnLoad((Object)val13);
			val13.AddComponent<RatingService>();
			GameObject val14 = new GameObject("RankedPeak_DuelService");
			Object.DontDestroyOnLoad((Object)val14);
			val14.AddComponent<DuelService>();
			GameObject val15 = new GameObject("RankedPeak_RaceService");
			Object.DontDestroyOnLoad((Object)val15);
			val15.AddComponent<RaceService>();
			GameObject val16 = new GameObject("RankedPeak_RaceHud");
			Object.DontDestroyOnLoad((Object)val16);
			val16.AddComponent<RaceHudOverlay>();
			val16.AddComponent<RaceCountdownOverlay>();
			GameObject val17 = new GameObject("RankedPeak_AiDisclosureBanner");
			Object.DontDestroyOnLoad((Object)val17);
			val17.AddComponent<AiDisclosureHudBanner>();
			GameObject val18 = new GameObject("RankedPeak_RaceLive");
			Object.DontDestroyOnLoad((Object)val18);
			val18.AddComponent<RaceLiveConnection>();
			GameObject val19 = new GameObject("RankedPeak_LiveGhosts");
			Object.DontDestroyOnLoad((Object)val19);
			val19.AddComponent<LiveGhostManager>();
			GameObject val20 = new GameObject("RankedPeak_UpdateCheck");
			Object.DontDestroyOnLoad((Object)val20);
			val20.AddComponent<UpdateCheckService>();
			RankedLog.Info("Services initialisiert (RaceTimer, RunStorageService, TimerOverlay, ClimbTrackingService, RunUploadService, SeedService, DailySeedService, ModAllowlistService, GhostPlaybackService, RatingService, DuelService, RaceService).");
		}

		private void ApplyHarmonyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("com.rankedpeak.mod");
			try
			{
				_harmony.PatchAll(typeof(RunLifecyclePatches));
				RunLifecyclePatches.ApplyEndGamePatches(_harmony);
				_harmony.PatchAll(typeof(SeedScopePatches.TrySpawnItemsPatch));
				_harmony.PatchAll(typeof(SeedScopePatches.SpawnItemsPatch));
				_harmony.PatchAll(typeof(SeedScopePatches.GetSpawnSpotsPatch));
				_harmony.PatchAll(typeof(SeedScopePatches.GroundPlaceSpawnerPatch));
				_harmony.PatchAll(typeof(SeedScopePatches.BerryBushPatch));
				_harmony.PatchAll(typeof(SeedScopePatches.BerryVinePatch));
				_harmony.PatchAll(typeof(SeedScopePatches.TempleSeedPatch));
				_harmony.PatchAll(typeof(MainMenuPatches.PageInjectionPatch));
				_harmony.PatchAll(typeof(MainMenuPatches.SignpostPatch));
				_harmony.PatchAll(typeof(BoardingPassPatch));
				_harmony.PatchAll(typeof(RaceInputLockPatch));
				_harmony.PatchAll(typeof(RunSettingsPatch));
				_harmony.PatchAll(typeof(SteamLobbyCreatedPatch));
				SentinelPatches.Apply(_harmony);
				RankedLog.Info("Harmony-Patches angewendet.");
			}
			catch (Exception arg)
			{
				RankedLog.Error($"Harmony-Patching fehlgeschlagen: {arg}");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			Loc.Refresh();
			try
			{
				if (_raceTimer == null)
				{
					return;
				}
				MapCatalog.LogDiagnostics("Szene '" + ((Scene)(ref scene)).name + "'");
				SentinelPatches.ApplyConsoleGuards(_harmony);
				if (((Scene)(ref scene)).name.StartsWith("Level_"))
				{
					_seedService?.ResetForNewScene();
					if ((Object)(object)DailySeedService.Instance != (Object)null)
					{
						DailySeedService.Instance.RefreshIfStale();
					}
				}
				if ((_raceTimer.State == TimerState.Running || _raceTimer.State == TimerState.WaitingForInput) && !((Scene)(ref scene)).name.StartsWith("Level_"))
				{
					RankedLog.Info("[Plugin] Szenenwechsel nach '" + ((Scene)(ref scene)).name + "' bei aktivem Run - Run abgebrochen.");
					_raceTimer.AbortRun();
				}
				if (!((Scene)(ref scene)).name.StartsWith("Level_"))
				{
					RatingService.Instance?.RefreshRating();
					ModAllowlistService.Instance?.RefreshIfStale();
					RankedGameLauncher.ReapplyForcedLevel();
				}
			}
			catch (Exception arg)
			{
				RankedLog.Error($"[Plugin] Fehler in OnSceneLoaded: {arg}");
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class BuildInfo
	{
		public const string Version = "0.10.3";

		public const string Label = "Beta";

		public const string ProductName = "PEAK RANKED";

		public const string LanServerUrl = "http://localhost:3000";
	}
}
namespace RankedPeak.Utils
{
	public static class ClimbDataCrusher
	{
		private static class NanCodes
		{
			internal const byte AbsoluteReposition = 1;

			internal const byte AsHalfFloats = 2;
		}

		public static void WriteClimbData(MemoryStream dataStream, List<Vector3> points)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			if (points.Count < 2)
			{
				return;
			}
			byte[] array = new byte[14];
			Vector3 val = points[0];
			EncodePointAsFloats(array, val);
			dataStream.Write(array.AsSpan(0, 12));
			for (int i = 1; i < points.Count; i++)
			{
				Vector3 val2 = points[i];
				QuarterFloat quarter = QuarterFloat.FromFloat(val2.x - val.x);
				QuarterFloat quarter2 = QuarterFloat.FromFloat(val2.y - val.y);
				QuarterFloat quarter3 = QuarterFloat.FromFloat(val2.z - val.z);
				if (quarter.IsInfinity() || quarter2.IsInfinity() || quarter3.IsInfinity())
				{
					HalfFloat half = HalfFloat.FromFloat(val2.x - val.x);
					HalfFloat half2 = HalfFloat.FromFloat(val2.y - val.y);
					HalfFloat half3 = HalfFloat.FromFloat(val2.z - val.z);
					if (half.IsInfinity() || half2.IsInfinity() || half3.IsInfinity())
					{
						EncodeQuarterFloat(array.AsSpan(0, 1), QuarterFloat.EncodeNaN(1));
						EncodePointAsFloats(array.AsSpan(1, 12), val2);
						val = val2;
						dataStream.Write(array.AsSpan(0, 13));
						continue;
					}
					EncodeQuarterFloat(array.AsSpan(0, 1), QuarterFloat.EncodeNaN(2));
					EncodeHalfFloat(array.AsSpan(1, 2), half);
					EncodeHalfFloat(array.AsSpan(3, 2), half2);
					EncodeHalfFloat(array.AsSpan(5, 2), half3);
					val.x += half.ToFloat();
					val.y += half2.ToFloat();
					val.z += half3.ToFloat();
					dataStream.Write(array.AsSpan(0, 7));
				}
				else
				{
					if (quarter.IsZero() && quarter2.IsZero())
					{
						quarter3.IsZero();
					}
					EncodeQuarterFloat(array.AsSpan(0, 1), quarter);
					EncodeQuarterFloat(array.AsSpan(1, 1), quarter2);
					EncodeQuarterFloat(array.AsSpan(2, 1), quarter3);
					val.x += quarter.ToFloat();
					val.y += quarter2.ToFloat();
					val.z += quarter3.ToFloat();
					dataStream.Write(array.AsSpan(0, 3));
				}
			}
		}

		public static List<Vector3> ReadClimbData(byte[] data)
		{
			//IL_001b: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: 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_0072: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			if (data == null || data.Length < 12)
			{
				return list;
			}
			Vector3 item = DecodePointFromFloats(data.AsSpan(0, 12));
			list.Add(item);
			int num = 12;
			while (num < data.Length)
			{
				QuarterFloat quarterFloat = DecodeQuarterFloat(data.AsSpan(num, 1));
				if (quarterFloat.IsNaN())
				{
					switch (quarterFloat.DecodeNaN())
					{
					case 1:
						item = DecodePointFromFloats(data.AsSpan(num + 1, 12));
						list.Add(item);
						num += 13;
						break;
					case 2:
						item.x += DecodeHalfFloat(data.AsSpan(num + 1, 2)).ToFloat();
						item.y += DecodeHalfFloat(data.AsSpan(num + 3, 2)).ToFloat();
						item.z += DecodeHalfFloat(data.AsSpan(num + 5, 2)).ToFloat();
						list.Add(item);
						num += 7;
						break;
					default:
						throw new InvalidOperationException($"Unexpected NaN code in climb data: {quarterFloat.DecodeNaN()}");
					}
				}
				else
				{
					item.x += quarterFloat.ToFloat();
					item.y += DecodeQuarterFloat(data.AsSpan(num + 1, 1)).ToFloat();
					item.z += DecodeQuarterFloat(data.AsSpan(num + 2, 1)).ToFloat();
					list.Add(item);
					num += 3;
				}
			}
			return list;
		}

		private static void EncodePointAsFloats(Span<byte> span, Vector3 firstPoint)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			EncodeFloat(span.Slice(0, 4), firstPoint.x);
			EncodeFloat(span.Slice(4, 4), firstPoint.y);
			EncodeFloat(span.Slice(8, 4), firstPoint.z);
		}

		private static Vector3 DecodePointFromFloats(Span<byte> data)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(DecodeFloat(data.Slice(0, 4)), DecodeFloat(data.Slice(4, 4)), DecodeFloat(data.Slice(8, 4)));
		}

		private static void EncodeFloat(Span<byte> span, float value)
		{
			BinaryPrimitives.WriteInt32LittleEndian(span, BitConverter.SingleToInt32Bits(value));
		}

		private static float DecodeFloat(Span<byte> span)
		{
			return BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(span));
		}

		private static void EncodeHalfFloat(Span<byte> span, HalfFloat half)
		{
			BinaryPrimitives.WriteUInt16LittleEndian(span, half.RawValue);
		}

		private static HalfFloat DecodeHalfFloat(Span<byte> span)
		{
			return new HalfFloat
			{
				RawValue = BinaryPrimitives.ReadUInt16LittleEndian(span)
			};
		}

		private static void EncodeQuarterFloat(Span<byte> span, QuarterFloat quarter)
		{
			span[0] = quarter.RawValue;
		}

		private static QuarterFloat DecodeQuarterFloat(Span<byte> span)
		{
			return new QuarterFloat
			{
				RawValue = span[0]
			};
		}
	}
	public struct HalfFloat
	{
		public const byte TotalNumBits = 16;

		public const byte NumExponentBits = 4;

		public const byte NumMantissaBits = 11;

		public const byte SignBitPos = 15;

		private const ushort SignBit = 32768;

		private const ushort ExponentMask = 30720;

		private const ushort MantissaMask = 2047;

		private const ushort ExponentInfinity = 15;

		private const int ExponentBias = 7;

		private const int SingleExponentBias = 127;

		private const byte SingleNumExponentBits = 8;

		private const byte SingleNumMantissaBits = 23;

		private const byte SingleSignBitPos = 31;

		private const uint SingleExponentMask = 2139095040u;

		private const uint SingleMantissaMask = 8388607u;

		private const uint SingleExponentInfinity = 255u;

		public ushort RawValue;

		public static HalfFloat NaN => new HalfFloat
		{
			RawValue = 30721
		};

		public ushort ExponentBits => (ushort)((uint)(RawValue & 0x7800) >> 11);

		public ushort MantissaBits => (ushort)(RawValue & 0x7FF);

		public static HalfFloat FromFloat(float value)
		{
			int num = BitConverter.SingleToInt32Bits(value);
			uint num2 = (uint)num >> 31;
			uint num3 = (uint)(num & 0x7F800000) >> 23;
			uint num4 = (uint)(num & 0x7FFFFF);
			int num5 = (int)(num3 - 127 + 7);
			if (num5 == -11)
			{
				num4 = 0u;
				num5++;
			}
			else if (num5 > -11)
			{
				uint num6 = (uint)(1 << 11 + Math.Max(0, 1 - num5));
				if ((num4 & num6) != 0)
				{
					num4 += num6;
					if ((num4 & 0xFF800000u) != 0)
					{
						num4 = 0u;
						num5++;
					}
				}
			}
			if (num5 >= 15)
			{
				if (num4 != 0 && num3 == 255)
				{
					return NaN;
				}
				num5 = 15;
				num4 = 0u;
			}
			else if (num5 <= 0)
			{
				if (num5 > -11)
				{
					num4 |= 0x800000;
					int num7 = 1 - num5;
					num4 >>= num7;
					num5 = 0;
				}
				else
				{
					num5 = 0;
					num4 = 0u;
				}
			}
			ushort num8 = (ushort)(num2 << 15);
			ushort num9 = (ushort)(num5 << 11);
			ushort num10 = (ushort)(num4 >> 12);
			return new HalfFloat
			{
				RawValue = (ushort)(num8 | num9 | num10)
			};
		}

		public float ToFloat()
		{
			uint num = (uint)((RawValue & 0x8000) << 16);
			uint exponentBits = ExponentBits;
			uint num2 = MantissaBits;
			if (exponentBits == 0 && num2 == 0)
			{
				return BitConverter.Int32BitsToSingle((int)num);
			}
			uint num3 = exponentBits + 127 - 7;
			if (exponentBits == 15)
			{
				num3 = 255u;
			}
			else if (exponentBits == 0)
			{
				while ((num2 & 0x800) == 0)
				{
					num2 <<= 1;
					num3--;
				}
				num2 &= 0x7FF;
				num3++;
			}
			return BitConverter.Int32BitsToSingle((int)(num | (num3 << 23) | (num2 << 12)));
		}

		public static HalfFloat EncodeNaN(ushort value)
		{
			value++;
			ushort num = (ushort)((uint)value >> 11);
			if (num > 1)
			{
				throw new ArgumentOutOfRangeException("value", "Value too large to encode as NaN");
			}
			ushort num2 = (ushort)(value & 0x7FF);
			return new HalfFloat
			{
				RawValue = (ushort)((num << 15) | 0x7800 | num2)
			};
		}

		public ushort DecodeNaN()
		{
			if (!IsNaN())
			{
				throw new InvalidOperationException("Not a NaN value");
			}
			ushort num = (ushort)((RawValue & 0x8000) >>> 15);
			ushort num2 = (ushort)(RawValue & 0x7FF);
			return (ushort)(((num << 11) | num2) - 1);
		}

		public bool IsNaN()
		{
			if (ExponentBits == 15)
			{
				return MantissaBits != 0;
			}
			return false;
		}

		public bool IsInfinity()
		{
			if (ExponentBits == 15)
			{
				return MantissaBits == 0;
			}
			return false;
		}

		public bool IsPositiveInfinity()
		{
			if (IsInfinity())
			{
				return (RawValue & 0x8000) == 0;
			}
			return false;
		}

		public bool IsNegativeInfinity()
		{
			if (IsInfinity())
			{
				return (RawValue & 0x8000) != 0;
			}
			return false;
		}

		public bool IsZero()
		{
			return (RawValue & -32769) == 0;
		}

		public bool IsPositiveZero()
		{
			return RawValue == 0;
		}

		public bool IsNegativeZero()
		{
			return RawValue == 32768;
		}

		public bool IsDenormalized()
		{
			if (ExponentBits == 0)
			{
				return MantissaBits != 0;
			}
			return false;
		}

		public override string ToString()
		{
			return ToFloat().ToString(CultureInfo.InvariantCulture);
		}
	}
	public struct QuarterFloat
	{
		public const byte TotalNumBits = 8;

		public const byte NumExponentBits = 2;

		public const byte NumMantissaBits = 5;

		public const byte SignBitPos = 7;

		private const byte SignBit = 128;

		private const byte ExponentMask = 96;

		private const byte MantissaMask = 31;

		private const byte ExponentInfinity = 3;

		private const int ExponentBias = 1;

		private const int SingleExponentBias = 127;

		private const byte SingleNumExponentBits = 8;

		private const byte SingleNumMantissaBits = 23;

		private const byte SingleSignBitPos = 31;

		private const uint SingleExponentMask = 2139095040u;

		private const uint SingleMantissaMask = 8388607u;

		private const uint SingleExponentInfinity = 255u;

		public byte RawValue;

		public static QuarterFloat NaN => new QuarterFloat
		{
			RawValue = 97
		};

		public byte ExponentBits => (byte)((uint)(RawValue & 0x60) >> 5);

		public byte MantissaBits => (byte)(RawValue & 0x1F);

		public static QuarterFloat FromFloat(float value)
		{
			int num = BitConverter.SingleToInt32Bits(value);
			uint num2 = (uint)num >> 31;
			uint num3 = (uint)(num & 0x7F800000) >> 23;
			uint num4 = (uint)(num & 0x7FFFFF);
			int num5 = (int)(num3 - 127 + 1);
			if (num5 == -5)
			{
				num4 = 0u;
				num5++;
			}
			else if (num5 > -5)
			{
				uint num6 = (uint)(1 << 17 + Math.Max(0, 1 - num5));
				if ((num4 & num6) != 0)
				{
					num4 += num6;
					if ((num4 & 0xFF800000u) != 0)
					{
						num4 = 0u;
						num5++;
					}
				}
			}
			if (num5 >= 3)
			{
				if (num4 != 0 && num3 == 255)
				{
					return NaN;
				}
				num5 = 3;
				num4 = 0u;
			}
			else if (num5 <= 0)
			{
				if (num5 > -5)
				{
					num4 |= 0x800000;
					int num7 = 1 - num5;
					num4 >>= num7;
					num5 = 0;
				}
				else
				{
					num5 = 0;
					num4 = 0u;
				}
			}
			byte b = (byte)(num2 << 7);
			byte b2 = (byte)(num5 << 5);
			byte b3 = (byte)(num4 >> 18);
			return new QuarterFloat
			{
				RawValue = (byte)(b | b2 | b3)
			};
		}

		public float ToFloat()
		{
			uint num = (uint)((RawValue & 0x80) << 24);
			uint exponentBits = ExponentBits;
			uint num2 = MantissaBits;
			if (exponentBits == 0 && num2 == 0)
			{
				return BitConverter.Int32BitsToSingle((int)num);
			}
			uint num3 = exponentBits + 127 - 1;
			if (exponentBits == 3)
			{
				num3 = 255u;
			}
			else if (exponentBits == 0)
			{
				while ((num2 & 0x20) == 0)
				{
					num2 <<= 1;
					num3--;
				}
				num2 &= 0x1F;
				num3++;
			}
			return BitConverter.Int32BitsToSingle((int)(num | (num3 << 23) | (num2 << 18)));
		}

		public static QuarterFloat EncodeNaN(byte value)
		{
			value++;
			byte b = (byte)((uint)value >> 5);
			if (b > 1)
			{
				throw new ArgumentOutOfRangeException("value", "Value too large to encode as NaN");
			}
			byte b2 = (byte)(value & 0x1F);
			return new QuarterFloat
			{
				RawValue = (byte)((b << 7) | 0x60 | b2)
			};
		}

		public byte DecodeNaN()
		{
			if (!IsNaN())
			{
				throw new InvalidOperationException("Not a NaN value");
			}
			byte num = (byte)((RawValue & 0x80) >>> 7);
			byte b = (byte)(RawValue & 0x1F);
			return (byte)(((num << 5) | b) - 1);
		}

		public bool IsNaN()
		{
			if (ExponentBits == 3)
			{
				return MantissaBits != 0;
			}
			return false;
		}

		public bool IsInfinity()
		{
			if (ExponentBits == 3)
			{
				return MantissaBits == 0;
			}
			return false;
		}

		public bool IsPositiveInfinity()
		{
			if (IsInfinity())
			{
				return (RawValue & 0x80) == 0;
			}
			return false;
		}

		public bool IsNegativeInfinity()
		{
			if (IsInfinity())
			{
				return (RawValue & 0x80) != 0;
			}
			return false;
		}

		public bool IsZero()
		{
			return (RawValue & -129) == 0;
		}

		public bool IsPositiveZero()
		{
			return RawValue == 0;
		}

		public bool IsNegativeZero()
		{
			return RawValue == 128;
		}

		public bool IsDenormalized()
		{
			if (ExponentBits == 0)
			{
				return MantissaBits != 0;
			}
			return false;
		}

		public override string ToString()
		{
			return ToFloat().ToString(CultureInfo.InvariantCulture);
		}
	}
	public static class MenuHierarchyDump
	{
		public static void Dump(MainMenuMainPage page)
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("[MenuDump] === Title-Menue-Hierarchie ===");
				stringBuilder.AppendLine($"[MenuDump] MainPage '{((Object)page).name}' {RectInfo(((Component)page).transform)} children={((Component)page).transform.childCount}:");
				DumpChildren(stringBuilder, ((Component)page).transform, 1, 1);
				TMP_SpriteAsset[] array = Resources.FindObjectsOfTypeAll<TMP_SpriteAsset>();
				if (array != null && array.Length != 0)
				{
					TMP_SpriteAsset[] array2 = array;
					foreach (TMP_SpriteAsset val in array2)
					{
						string text = ((val.spriteCharacterTable != null) ? string.Join(", ", val.spriteCharacterTable.Select((TMP_SpriteCharacter c) => c.name)) : "keine");
						stringBuilder.AppendLine("[MenuDump] SpriteAsset '" + ((Object)val).name + "': " + text);
					}
				}
				DumpLogoDetail(stringBuilder, ((Component)page).transform.Find("Logo"), "Logo");
				DumpLogoDetail(stringBuilder, ((Component)page).transform.Find("LogoBlack"), "LogoBlack");
				Transform val2 = (((Object)(object)page.m_playButton != (Object)null) ? ((Component)page.m_playButton).transform.parent : null);
				if ((Object)(object)val2 != (Object)null)
				{
					stringBuilder.AppendLine("[MenuDump] Linker Original-Mast (Sign-Container): '" + ((Object)val2).name + "' " + RectInfo(val2));
					DumpChildren(stringBuilder, val2, 1, 4);
					if ((Object)(object)val2.parent != (Object)null && (Object)(object)val2.parent != (Object)(object)((Component)page).transform)
					{
						stringBuilder.AppendLine("[MenuDump] Linker Mast-Parent: '" + ((Object)val2.parent).name + "' " + RectInfo(val2.parent));
						DumpChildren(stringBuilder, val2.parent, 1, 2);
					}
				}
				Transform val3 = ((Component)page).transform.Find("RankedSignpostContainer") ?? (((Object)(object)((val2 != null) ? val2.parent : null) != (Object)null) ? val2.parent.Find("RankedSignpostContainer") : null);
				if ((Object)(object)val3 != (Object)null)
				{
					stringBuilder.AppendLine("[MenuDump] Rechter Ranked-Mast: '" + ((Object)val3).name + "' " + RectInfo(val3));
					DumpChildren(stringBuilder, val3, 1, 2);
				}
				else
				{
					stringBuilder.AppendLine("[MenuDump] Rechter Ranked-Mast: noch nicht gefunden.");
				}
				RankedLog.Debug(stringBuilder.ToString());
			}
			catch (Exception ex)
			{
				RankedLog.Warning("[MenuDump] Fehler beim Hierarchie-Dump: " + ex.Message);
			}
		}

		private static void DumpLogoDetail(StringBuilder sb, Transform root, string label)
		{
			if ((Object)(object)root == (Object)null)
			{
				sb.AppendLine("[MenuDump] " + label + ": nicht gefunden.");
				return;
			}
			sb.AppendLine("[MenuDump] === " + label + " im Detail ===");
			DumpLogoNode(sb, root, 0);
		}

		private static void DumpLogoNode(StringBuilder sb, Transform node, int indent)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			string text = new string(' ', indent * 2);
			sb.AppendLine($"{text}'{((Object)node).name}' {RectInfo(node)} active={((Component)node).gameObject.activeSelf} ({Components(node)})");
			Graphic component = ((Component)node).GetComponent<Graphic>();
			if ((Object)(object)component != (Object)null)
			{
				Material materialForRendering = component.materialForRendering;
				string text2 = (((Object)(object)materialForRendering != (Object)null && (Object)(object)materialForRendering.shader != (Object)null) ? ((Object)materialForRendering.shader).name : "-");
				string text3 = (((Object)(object)materialForRendering != (Object)null) ? ((Object)materialForRendering).name : "-");
				sb.AppendLine($"{text}  -> Graphic {((object)component).GetType().Name}: color={component.color} material='{text3}' shader='{text2}'");
				Image val = (Image)(object)((component is Image) ? component : null);
				if (val != null)
				{
					string text4 = (((Object)(object)val.sprite != (Object)null) ? ((Object)val.sprite).name : "-");
					string text5 = (((Object)(object)val.sprite != (Object)null && (Object)(object)val.sprite.texture != (Object)null) ? ((Object)val.sprite.texture).name : "-");
					sb.AppendLine($"{text}  -> Image: sprite='{text4}' texture='{text5}' type={val.type} fill={val.fillAmount}");
				}
				if ((Object)(object)materialForRendering != (Object)null)
				{
					string[] texturePropertyNames = materialForRendering.GetTexturePropertyNames();
					if (texturePropertyNames != null && texturePropertyNames.Length != 0)
					{
						sb.AppendLine(text + "  -> Textur-Slots: " + string.Join(", ", texturePropertyNames));
					}
				}
			}
			Mask component2 = ((Component)node).GetComponent<Mask>();
			if ((Object)(object)component2 != (Object)null)
			{
				sb.AppendLine($"{text}  -> Mask: showMaskGraphic={component2.showMaskGraphic}");
			}
			Animator component3 = ((Component)node).GetComponent<Animator>();
			if ((Object)(object)component3 != (Object)null)
			{
				RuntimeAnimatorController runtimeAnimatorController = component3.runtimeAnimatorController;
				string text6 = (((Object)(object)runtimeAnimatorController != (Object)null && runtimeAnimatorController.animationClips != null) ? string.Join(", ", runtimeAnimatorController.animationClips.Select((AnimationClip c) => (!((Object)(object)c != (Object)null)) ? "?" : $"{((Object)c).name} ({c.length:0.##}s, loop={((Motion)c).isLooping})")) : "keine");
				sb.AppendLine(string.Format("{0}  -> Animator: controller='{1}' clips=[{2}] enabled={3} speed={4}", text, ((Object)(object)runtimeAnimatorController != (Object)null) ? ((Object)runtimeAnimatorController).name : "-", text6, ((Behaviour)component3).enabled, component3.speed));
			}
			for (int num = 0; num < node.childCount; num++)
			{
				DumpLogoNode(sb, node.GetChild(num), indent + 1);
			}
		}

		private static void DumpChildren(StringBuilder sb, Transform parent, int indent, int maxDepth)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			string text = new string(' ', indent * 2);
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				TextMeshProUGUI componentInChildren = ((Component)child).GetComponentInChildren<TextMeshProUGUI>(true);
				string text2 = (((Object)(object)componentInChildren != (Object)null) ? (" text='" + ((TMP_Text)componentInChildren).text + "'") : string.Empty);
				Image component = ((Component)child).GetComponent<Image>();
				string text3 = (((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null) ? $" sprite='{((Object)component.sprite).name}' type={component.type}" : string.Empty);
				sb.AppendLine($"{text}[{i}] '{((Object)child).name}' {RectInfo(child)} active={((Component)child).gameObject.activeSelf}{text2}{text3} ({Components(child)})");
				if (indent < maxDepth)
				{
					DumpChildren(sb, child, indent + 1, maxDepth);
				}
			}
		}

		private static string RectInfo(Transform t)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null);
			if (val != null)
			{
				return $"pos={val.anchoredPosition} size={val.sizeDelta} scale={((Transform)val).localScale} pivot={val.pivot} anchorMin={val.anchorMin} anchorMax={val.anchorMax}";
			}
			return $"localPos={t.localPosition} scale={t.localScale}";
		}

		private static string Components(Transform t)
		{
			Component[] components = ((Component)t).GetComponents<Component>();
			string[] array = new string[components.Length];
			for (int i = 0; i < components.Length; i++)
			{
				array[i] = (((Object)(object)components[i] != (Object)null) ? ((object)components[i]).GetType().Name : "?");
			}
			return string.Join(",", array);
		}
	}
}
namespace RankedPeak.Ui
{
	internal static class AiDisclosure
	{
		private static readonly string[] Keys = new string[7] { "aiDisclosure.1", "aiDisclosure.2", "aiDisclosure.3", "aiDisclosure.4", "aiDisclosure.5", "aiDisclosure.6", "aiDisclosure.7" };

		public static int Count => Keys.Length;

		public static string Label => Loc.T("aiDisclosure.label");

		public static string Get(int index)
		{
			return Loc.T(Keys[(index % Keys.Length + Keys.Length) % Keys.Length]);
		}
	}
	public class AiDisclosureHudBanner : MonoBehaviour
	{
		private const float RotateSeconds = 9f;

		private const float PaddingX = 10f;

		private const float PaddingY = 6f;

		private const float Gap = 4f;

		private const float StandaloneWidth = 340f;

		private static readonly Color Background = new Color(0.05f, 0.06f, 0.08f, 0.82f);

		private static readonly Color TextColor = new Color(0.62f, 0.66f, 0.72f);

		private const string LabelColorTag = "#FAB84D";

		private RectTransform _root;

		private TextMeshProUGUI _label;

		private bool _attached;

		private int _index;

		private float _nextRotateAt;

		private string _shown;

		private void Update()
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			RectTransform currentPanel = NativeTimerPanel.CurrentPanel;
			bool flag = (Object)(object)currentPanel != (Object)null;
			if ((Object)(object)_root == (Object)null || flag != _attached || (flag && (Object)(object)((Transform)_root).parent != (Object)(object)currentPanel))
			{
				Build(currentPanel);
			}
			if (!_attached)
			{
				bool visible = TimerOverlay.Visible;
				if (visible)
				{
					NativeUiFactory.EnsureCanvasAlive();
				}
				if (((Component)_root).gameObject.activeSelf != visible)
				{
					((Component)_root).gameObject.SetActive(visible);
				}
				if (!visible)
				{
					return;
				}
			}
			if (Time.time >= _nextRotateAt)
			{
				_index++;
				_nextRotateAt = Time.time + 9f;
				_shown = null;
			}
			string text = "<color=#FAB84D>" + AiDisclosure.Label + "</color>\n" + AiDisclosure.Get(_index);
			if (!(text == _shown))
			{
				_shown = text;
				((TMP_Text)_label).text = text;
				float num = ((TMP_Text)_label).preferredHeight + 12f;
				_root.sizeDelta = (_attached ? new Vector2(0f, num) : new Vector2(340f, num));
			}
		}

		private void Build(RectTransform panel)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: 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_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_root).gameObject);
			}
			_attached = (Object)(object)panel != (Object)null;
			Image val = PeakWindowStyle.CreateSurface((Transform)(_attached ? ((object)panel) : ((object)(RectTransform)((Component)NativeUiFactory.GetCanvas()).transform)), "RankedPeak_AiDisclosureBanner", Background, 8);
			_root = (RectTransform)((Component)val).transform;
			if (_attached)
			{
				_root.anchorMin = new Vector2(0f, 0f);
				_root.anchorMax = new Vector2(1f, 0f);
				_root.pivot = new Vector2(0.5f, 1f);
				_root.anchoredPosition = new Vector2(0f, -4f);
				_root.sizeDelta = new Vector2(0f, 34f);
			}
			else
			{
				_root.anchorMin = new Vector2(0.5f, 0f);
				_root.anchorMax = new Vector2(0.5f, 0f);
				_root.pivot = new Vector2(0.5f, 0f);
				_root.anchoredPosition = new Vector2(0f, 22f);
				_root.sizeDelta = new Vector2(340f, 34f);
				((Component)_root).gameObject.SetActive(false);
			}
			_label = PeakWindowStyle.CreateText((Transform)(object)_root, "Text", string.Empty, 13f, TextColor, (TextAlignmentOptions)257);
			((TMP_Text)_label).textWrappingMode = (TextWrappingModes)1;
			RectTransform val2 = (RectTransform)((TMP_Text)_label).transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = new Vector2(10f, 6f);
			val2.offsetMax = new Vector2(-10f, -6f);
			_shown = null;
			_nextRotateAt = Time.time + 9f;
		}
	}
	public class CustomRunModal : MenuWindow
	{
		private enum RaceView
		{
			RoleSelect,
			HostSetup,
			JoinEntry
		}

		private const float WindowWidth = 1180f;

		private const float TitleBarHeight = 82f;

		private const float WindowPadding = 26f;

		private const float BoxPadding = 24f;

		private const float BoxGap = 14f;

		private const float BodyBottomPadding = 18f;

		private const int MinSeed = 100000000;

		private const int MaxSeed = 999999999;

		private const int MaxParticipantRows = 8;

		private const float ModeRowY = 8f;

		private const float ModeRowHeight = 44f;

		private const float MountainBoxHeight = 194f;

		private const float RandomBoxHeight = 96f;

		private const float AscentBoxHeight = 128f;

		private const float RouteBoxHeight = 146f;

		private const float RaceBoxHeight = 214f;

		private const float RoleBoxHeight = 170f;

		private const float FooterHeight = 52f;

		private const float SeedRowY = 50f;

		private const float MapRowY = 112f;

		private const float MapHintY = 160f;

		private const float RaceRow1Y = 50f;

		private const float RaceRow2Y = 104f;

		private const float RaceRow3Y = 160f;

		private static CustomRunModal _speedrunInstance;

		private static CustomRunModal _raceInstance;

		private RaceView _view;

		private RectTransform _root;

		private PeakWindowStyle.WindowParts _window;

		private TMP_InputField _seedInput;

		private TMP_InputField _codeInput;

		private TextMeshProUGUI _ascentDescriptionLabel;

		private TextMeshProUGUI _routeDescriptionLabel;

		private TextMeshProUGUI _summaryLabel;

		private TextMeshProUGUI _levelLabel;

		private TextMeshProUGUI _levelDescriptionLabel;

		private TextMeshProUGUI _playersLabel;

		private TextMeshProUGUI _codeLabel;

		private TextMeshProUGUI _modeHintLabel;

		private TextMeshProUGUI _joinHintLabel;

		private RectTransform _mountainBox;

		private RectTransform _randomBox;

		private RectTransform _ascentBox;

		private RectTransform _routeBox;

		private RectTransform _raceBox;

		private RectTransform _roleBox;

		private Button _staticModeButton;

		private Button _randomModeButton;

		private Button _dailyButton;

		private Button _copySeedButton;

		private Button _levelPrevButton;

		private Button _levelNextButton;

		private Button _todayButton;

		private Button _playersPrevButton;

		private Button _playersNextButton;

		private Button _autoStartButton;

		private Button _rivalsButton;

		private Button _startButton;

		private Button _cancelButton;

		private Button _backButton;

		private Button _createButton;

		private Button _hostStartButton;

		private Button _leaveButton;

		private Button _copyCodeButton;

		private Button _waitingAreaButton;

		private Button _joinButton;

		private readonly List<Button> _ascentPills = new List<Button>();

		private readonly List<Button> _routePills = new List<Button>();

		private readonly List<TextMeshProUGUI> _participantRows = new List<TextMeshProUGUI>();

		private bool _built;

		private bool _raceMode;

		private bool _randomMode;

		private int _seed = 100000000;

		private int _ascent;

		private int _routeIndex;

		private int _levelSlot;

		private int _maxPlayers = 4;

		private bool _autoStart = true;

		private bool _showRivals;

		private GameObject _panelPlaceholder;

		public override bool openOnStart => false;

		public override bool selectOnOpen => false;

		public override GameObject panel
		{
			get
			{
				if (!((Object)(object)_root != (Object)null))
				{
					return _panelPlaceholder;
				}
				return ((Component)_root).gameObject;
			}
		}

		private void Awake()
		{
			_seed = Random.Range(100000000, 999999999);
		}

		public override void Start()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_panelPlaceholder = new GameObject("PanelPlaceholder");
			_panelPlaceholder.transform.SetParent(((Component)this).transform, false);
			_panelPlaceholder.SetActive(false);
		}

		public static void OpenSpeedrun()
		{
			OpenModal(raceMode: false);
		}

		public static void OpenRace()
		{
			OpenModal(raceMode: true);
		}

		private static void OpenModal(bool raceMode)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (RaceService.Instance?.CurrentRace != null)
			{
				raceMode = true;
			}
			CustomRunModal customRunModal = (raceMode ? _raceInstance : _speedrunInstance);
			if ((Object)(object)customRunModal == (Object)null)
			{
				Canvas canvas = NativeUiFactory.GetCanvas();
				GameObject val = new GameObject(raceMode ? "RankedPeak_RaceModal" : "RankedPeak_SpeedrunModal");
				val.transform.SetParent(((Component)canvas).transform, false);
				customRunModal = val.AddComponent<CustomRunModal>();
				customRunModal._raceMode = raceMode;
				if (raceMode)
				{
					_raceInstance = customRunModal;
				}
				else
				{
					_speedrunInstance = customRunModal;
				}
			}
			CustomRunModal customRunModal2 = (raceMode ? _speedrunInstance : _raceInstance);
			if ((Object)(object)customRunModal2 != (Object)null && (Object)(object)customRunModal2 != (Object)(object)customRunModal)
			{
				customRunModal2.CloseModal();
			}
			customRunModal.ShowModal();
		}

		public void ShowModal()
		{
			if (!_built || (Object)(object)_root == (Object)null)
			{
				BuildUi();
			}
			if (_raceMode && RaceService.Instance?.CurrentRace == null)
			{
				_view = RaceView.RoleSelect;
			}
			_levelSlot = MapCatalog.SlotOf(MapCatalog.CurrentLevelIndex);
			RefreshDisplay();
			((MenuWindow)this).Open();
			NativeUiFactory.EnsureTopMost();
		}

		public void CloseModal()
		{
			((MenuWindow)this).Close();
		}

		private void OnEnable()
		{
			RaceService.RaceUpdated += OnRaceUpdated;
			Loc.LanguageChanged += OnLanguageChanged;
		}

		private void OnDisable()
		{
			RaceService.RaceUpdated -= OnRaceUpdated;
			Loc.LanguageChanged -= OnLanguageChanged;
		}

		private void OnLanguageChanged()
		{
			if (_built)
			{
				bool isOpen = ((MenuWindow)this).isOpen;
				if (isOpen)
				{
					CloseModal();
				}
				if ((Object)(object)_root != (Object)null)
				{
					((Component)_root).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)_root).gameObject);
					_root = null;
				}
				_built = false;
				_ascentPills.Clear();
				_routePills.Clear();
				_participantRows.Clear();
				if (isOpen)
				{
					ShowModal();
				}
			}
		}

		private void OnRaceUpdated(RaceInfo race)
		{
			if (_raceMode)
			{
				RefreshDisplay();
				if (race != null && (race.Status == "loading" || race.Status == "countdown"))
				{
					CloseModal();
				}
			}
		}

		public override void Update()
		{
			if (((MenuWindow)this).isOpen && !((Object)(object)_root == (Object)null))
			{
				bool flag = ((Object)(object)_seedInput != (Object)null && _seedInput.isFocused) || ((Object)(object)_codeInput != (Object)null && _codeInput.isFocused);
				if (Input.GetKeyDown((KeyCode)27) && !flag)
				{
					CloseModal();
				}
			}
		}

		private void BuildUi()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0084: 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_016e: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			_built = true;
			Canvas canvas = NativeUiFactory.GetCanvas();
			GameObject val = new GameObject("CustomModalRoot", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)canvas).transform, false);
			_root = (RectTransform)val.transform;
			_root.anchorMin = Vector2.zero;
			_root.anchorMax = Vector2.one;
			_root.offsetMin = Vector2.zero;
			_root.offsetMax = Vector2.zero;
			PeakWindowStyle.CreateBackdrop((Transform)(object)_root, "Backdrop");
			_window = PeakWindowStyle.CreateWindow((Transform)(object)_root, "CustomWindow", 1180f, 900f, 82f, Loc.T(_raceMode ? "mode.liveRace" : "mode.speedrun"), Loc.T(_raceMode ? "run.race.subtitle" : "run.speedrun.subtitle"));
			Button obj = PeakWindowStyle.CreatePill((Transform)(object)_window.TitleBar, "BtnClose", "X", 1094f, 20f, 48f, 42f, 24f);
			Image component = ((Component)obj).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = new Color(1f, 1f, 1f, 0.22f);
			}
			((UnityEvent)obj.onClick).AddListener(new UnityAction(CloseModal));
			RectTransform body = _window.Body;
			float innerWidth = 1128f;
			if (_raceMode)
			{
				BuildRoleBox(body, innerWidth);
			}
			BuildModeRow(body, innerWidth);
			BuildMountainBox(body, innerWidth);
			BuildRandomBox(body, innerWidth);
			BuildAscentBox(body, innerWidth);
			BuildRouteBox(body, innerWidth);
			if (_raceMode)
			{
				BuildRaceBox(body, innerWidth);
			}
			BuildFooter(body, innerWidth);
		}

		private void BuildRoleBox(RectTransform body, float innerWidth)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			_roleBox = PeakWindowStyle.CreateBox((Transform)(object)body, "BoxRole", Loc.T("race.role.box"), 26f, 0f, innerWidth, 170f);
			float num = innerWidth - 48f;
			((UnityEvent)PeakWindowStyle.CreatePill((Transform)(object)_roleBox, "BtnRoleHost", Loc.T("race.role.host"), 24f, 52f, num / 2f - 7f, 56f, 21f).onClick).AddListener((UnityAction)delegate
			{
				_view = RaceView.HostSetup;
				RefreshDisplay();
			});
			Button obj = PeakWindowStyle.CreatePill((Transform)(object)_roleBox, "BtnRoleJoin", Loc.T("race.role.join"), 24f + num / 2f + 7f, 52f, num / 2f - 7f, 56f, 21f);
			PeakWindowStyle.SetPillSelected(obj, selected: false);
			((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
			{
				_view = RaceView.JoinEntry;
				RefreshDisplay();
			});
			NativeUiFactory.Place((RectTransform)((TMP_Text)PeakWindowStyle.CreateText((Transform)(object)_roleBox, "RoleHint", Loc.T("race.role.hint"), 19f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513)).transform, 24f, 120f, num, 34f);
		}

		private void BuildModeRow(RectTransform body, float innerWidth)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			_staticModeButton = PeakWindowStyle.CreatePill((Transform)(object)body, "ModeStatic", Loc.T("run.mode.static"), 26f, 8f, 220f, 44f);
			((UnityEvent)_staticModeButton.onClick).AddListener((UnityAction)delegate
			{
				SetRandomMode(randomMode: false);
			});
			_randomModeButton = PeakWindowStyle.CreatePill((Transform)(object)body, "ModeRandom", Loc.T("run.mode.random"), 254f, 8f, 220f, 44f);
			((UnityEvent)_randomModeButton.onClick).AddListener((UnityAction)delegate
			{
				SetRandomMode(randomMode: true);
			});
			_modeHintLabel = PeakWindowStyle.CreateText((Transform)(object)body, "ModeHint", Loc.T("run.mode.hint"), 19f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_modeHintLabel).transform, 494f, 8f, innerWidth - 468f, 44f);
		}

		private void BuildMountainBox(RectTransform body, float innerWidth)
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Expected O, but got Unknown
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Expected O, but got Unknown
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Expected O, but got Unknown
			_mountainBox = PeakWindowStyle.CreateBox((Transform)(object)body, "BoxMountain", Loc.T("run.box.mountain"), 26f, 0f, innerWidth, 194f);
			float num = innerWidth - 48f;
			_seedInput = PeakWindowStyle.CreateInputField((Transform)(object)_mountainBox, "SeedInput", _seed.ToString(), 24f, 50f, 340f, 52f, 30f);
			_seedInput.characterLimit = 9;
			((UnityEvent<string>)(object)_seedInput.onValueChanged).AddListener((UnityAction<string>)OnSeedTyped);
			((UnityEvent<string>)(object)_seedInput.onEndEdit).AddListener((UnityAction<string>)delegate
			{
				PushRaceConfig();
			});
			_dailyButton = PeakWindowStyle.CreatePill((Transform)(object)_mountainBox, "BtnDailySeed", Loc.T("run.btn.daily"), 380f, 50f, 150f, 52f, 19f);
			((UnityEvent)_dailyButton.onClick).AddListener(new UnityAction(UseDailySeed));
			_copySeedButton = PeakWindowStyle.CreatePill((Transform)(object)_mountainBox, "BtnCopySeed", Loc.T("run.btn.copySeed"), 540f, 50f, 180f, 52f, 19f);
			((UnityEvent)_copySeedButton.onClick).AddListener(new UnityAction(CopySeed));
			NativeUiFactory.Place((RectTransform)((TMP_Text)PeakWindowStyle.CreateText((Transform)(object)_mountainBox, "SeedHint", Loc.T("run.seed.hint"), 18f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513)).transform, 736f, 50f, num - 712f, 52f);
			_levelPrevButton = PeakWindowStyle.CreatePill((Transform)(object)_mountainBox, "BtnLevelPrev", "<", 24f, 112f, 52f, 42f);
			((UnityEvent)_levelPrevButton.onClick).AddListener((UnityAction)delegate
			{
				StepLevel(-1);
			});
			_levelLabel = PeakWindowStyle.CreateText((Transform)(object)_mountainBox, "LevelLabel", string.Empty, 20f, PeakWindowStyle.TextPrimary, (TextAlignmentOptions)514);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_levelLabel).transform, 82f, 112f, 200f, 42f);
			_levelNextButton = PeakWindowStyle.CreatePill((Transform)(object)_mountainBox, "BtnLevelNext", ">", 288f, 112f, 52f, 42f);
			((UnityEvent)_levelNextButton.onClick).AddListener((UnityAction)delegate
			{
				StepLevel(1);
			});
			_todayButton = PeakWindowStyle.CreatePill((Transform)(object)_mountainBox, "BtnLevelToday", Loc.T("run.btn.today"), 348f, 112f, 120f, 42f, 18f);
			((UnityEvent)_todayButton.onClick).AddListener((UnityAction)delegate
			{
				_levelSlot = MapCatalog.SlotOf(MapCatalog.CurrentLevelIndex);
				PushRaceConfig();
				RefreshDisplay();
			});
			_levelDescriptionLabel = PeakWindowStyle.CreateText((Transform)(object)_mountainBox, "LevelDescription", string.Empty, 19f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_levelDescriptionLabel).transform, 24f, 160f, num, 24f);
		}

		private void BuildRandomBox(RectTransform body, float innerWidth)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			_randomBox = PeakWindowStyle.CreateBox((Transform)(object)body, "BoxRandom", Loc.T("run.box.random"), 26f, 0f, innerWidth, 96f);
			float width = innerWidth - 48f;
			NativeUiFactory.Place((RectTransform)((TMP_Text)PeakWindowStyle.CreateText((Transform)(object)_randomBox, "RandomHint", Loc.T(_raceMode ? "run.random.hint.race" : "run.random.hint.solo"), 21f, PeakWindowStyle.TextPrimary, (TextAlignmentOptions)513)).transform, 24f, 52f, width, 34f);
		}

		private void BuildAscentBox(RectTransform body, float innerWidth)
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			_ascentBox = PeakWindowStyle.CreateBox((Transform)(object)body, "BoxAscent", Loc.T("run.box.ascent"), 26f, 0f, innerWidth, 128f);
			float num = innerWidth - 48f;
			int num2 = Mathf.Max(1, RunConfigService.MaxAscent);
			int num3 = num2 + 2;
			float num4 = Mathf.Clamp((num - 140f - 110f - 8f * (float)(num3 - 1)) / (float)num2, 44f, 110f);
			float num5 = 24f;
			for (int i = -1; i <= RunConfigService.MaxAscent; i++)
			{
				float num6 = i switch
				{
					0 => 110f, 
					-1 => 140f, 
					_ => num4, 
				};
				int value = i;
				Button val = PeakWindowStyle.CreatePill((Transform)(object)_ascentBox, $"Ascent{i}", RunConfigService.GetAscentShortName(i), num5, 46f, num6, 44f, 19f);
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					_ascent = value;
					PushRaceConfig();
					RefreshDisplay();
				});
				_ascentPills.Add(val);
				num5 += num6 + 8f;
			}
			_ascentDescriptionLabel = PeakWindowStyle.CreateText((Transform)(object)_ascentBox, "AscentDescription", string.Empty, 20f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_ascentDescriptionLabel).transform, 24f, 96f, num, 28f);
		}

		private void BuildRouteBox(RectTransform body, float innerWidth)
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_015b: 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_018f: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			_routeBox = PeakWindowStyle.CreateBox((Transform)(object)body, "BoxRoute", Loc.T("run.box.route"), 26f, 0f, innerWidth, 146f);
			float width = innerWidth - 48f;
			float num = 24f;
			for (int i = 0; i < RunConfigService.RouteCount; i++)
			{
				float num2 = ((i == 0) ? 220f : 145f);
				int value = i;
				Button val = PeakWindowStyle.CreatePill((Transform)(object)_routeBox, $"Route{i}", RunConfigService.GetRouteName(i), num, 46f, num2, 44f, 19f);
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					_routeIndex = value;
					PushRaceConfig();
					RefreshDisplay();
				});
				_routePills.Add(val);
				num += num2 + 8f;
			}
			_routeDescriptionLabel = PeakWindowStyle.CreateText((Transform)(object)_routeBox, "RouteDescription", string.Empty, 20f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_routeDescriptionLabel).transform, 24f, 94f, width, 26f);
			NativeUiFactory.Place((RectTransform)((TMP_Text)PeakWindowStyle.CreateText((Transform)(object)_routeBox, "RouteLimitHint", Loc.T("run.route.limitHint", RunConfigService.MiniRunBiomeCount), 18f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513)).transform, 24f, 118f, width, 24f);
		}

		private void BuildRaceBox(RectTransform body, float innerWidth)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_01ec: 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_0237: Expected O, but got Unknown
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Expected O, but got Unknown
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Expected O, but got Unknown
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Expected O, but got Unknown
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Expected O, but got Unknown
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Expected O, but got Unknown
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Expected O, but got Unknown
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Expected O, but got Unknown
			_raceBox = PeakWindowStyle.CreateBox((Transform)(object)body, "BoxRace", Loc.T("run.box.race"), 26f, 0f, innerWidth, 214f);
			float num = innerWidth - 48f;
			_playersPrevButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnPlayersPrev", "-", 24f, 50f, 52f, 42f);
			((UnityEvent)_playersPrevButton.onClick).AddListener((UnityAction)delegate
			{
				_maxPlayers = Mathf.Max(2, _maxPlayers - 1);
				PushRaceConfig();
				RefreshDisplay();
			});
			_playersLabel = PeakWindowStyle.CreateText((Transform)(object)_raceBox, "PlayersLabel", string.Empty, 20f, PeakWindowStyle.TextPrimary, (TextAlignmentOptions)514);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_playersLabel).transform, 82f, 50f, 150f, 42f);
			_playersNextButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnPlayersNext", "+", 238f, 50f, 52f, 42f);
			((UnityEvent)_playersNextButton.onClick).AddListener((UnityAction)delegate
			{
				_maxPlayers = Mathf.Min(8, _maxPlayers + 1);
				PushRaceConfig();
				RefreshDisplay();
			});
			_autoStartButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnAutoStart", Loc.T("run.btn.autoStart"), 314f, 50f, 200f, 42f, 18f);
			((UnityEvent)_autoStartButton.onClick).AddListener((UnityAction)delegate
			{
				_autoStart = !_autoStart;
				PushRaceConfig();
				RefreshDisplay();
			});
			_rivalsButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnRivals", Loc.T("run.btn.rivals"), 524f, 50f, 240f, 42f, 16f);
			((UnityEvent)_rivalsButton.onClick).AddListener((UnityAction)delegate
			{
				_showRivals = !_showRivals;
				PushRaceConfig();
				RefreshDisplay();
			});
			_codeLabel = PeakWindowStyle.CreateText((Transform)(object)_raceBox, "CodeLabel", string.Empty, 30f, PeakWindowStyle.Heading, (TextAlignmentOptions)516, display: false, 8f);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_codeLabel).transform, 24f + num - 320f, 50f, 320f, 42f);
			_joinHintLabel = PeakWindowStyle.CreateText((Transform)(object)_raceBox, "JoinHint", Loc.T("race.join.hint"), 19f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513);
			NativeUiFactory.Place((RectTransform)((TMP_Text)_joinHintLabel).transform, 24f, 50f, num, 42f);
			_codeInput = PeakWindowStyle.CreateInputField((Transform)(object)_raceBox, "CodeInput", string.Empty, 24f, 104f, 200f, 46f, 24f);
			_codeInput.characterLimit = 6;
			_codeInput.contentType = (ContentType)4;
			_joinButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnJoin", Loc.T("run.btn.join"), 236f, 104f, 190f, 46f, 19f);
			((UnityEvent)_joinButton.onClick).AddListener(new UnityAction(JoinRace));
			_createButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnCreateRace", Loc.T("run.btn.create"), 444f, 104f, 300f, 46f, 19f);
			((UnityEvent)_createButton.onClick).AddListener(new UnityAction(CreateRace));
			_copyCodeButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnCopyCode", Loc.T("run.btn.copyCode"), 24f, 104f, 240f, 46f, 18f);
			((UnityEvent)_copyCodeButton.onClick).AddListener(new UnityAction(CopyInviteCode));
			_waitingAreaButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnWaitingArea", Loc.T("run.btn.airport"), 274f, 104f, 260f, 46f, 18f);
			((UnityEvent)_waitingAreaButton.onClick).AddListener(new UnityAction(GoToWaitingArea));
			_hostStartButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnHostStart", Loc.T("run.btn.startRace"), 544f, 104f, 270f, 46f, 19f);
			((UnityEvent)_hostStartButton.onClick).AddListener((UnityAction)delegate
			{
				RaceService.Instance?.StartRace(delegate(string err)
				{
					SetSummary(Loc.T("run.msg.startFailed", err));
				});
			});
			_leaveButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnLeaveRace", Loc.T("run.btn.leave"), 824f, 104f, 240f, 46f, 19f);
			PeakWindowStyle.SetPillSelected(_leaveButton, selected: false);
			((UnityEvent)_leaveButton.onClick).AddListener((UnityAction)delegate
			{
				RaceService.Instance?.LeaveRace();
				SetSummary(Loc.T("run.msg.left"));
			});
			for (int num2 = 0; num2 < 8; num2++)
			{
				TextMeshProUGUI val = PeakWindowStyle.CreateText((Transform)(object)_raceBox, $"Participant{num2}", string.Empty, 18f, PeakWindowStyle.TextPrimary, (TextAlignmentOptions)513);
				NativeUiFactory.Place((RectTransform)((TMP_Text)val).transform, 24f + (float)(num2 % 4) * (num / 4f), 160f + (float)(num2 / 4) * 22f, num / 4f, 22f);
				((Component)val).gameObject.SetActive(false);
				_participantRows.Add(val);
			}
		}

		private void StepLevel(int direction)
		{
			int slotCount = MapCatalog.SlotCount;
			if (slotCount > 0)
			{
				_levelSlot = ((_levelSlot + direction) % slotCount + slotCount) % slotCount;
				PushRaceConfig();
				RefreshDisplay();
			}
		}

		private void BuildFooter(RectTransform body, float innerWidth)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			_summaryLabel = PeakWindowStyle.CreateText((Transform)(object)body, "Summary", string.Empty, 21f, PeakWindowStyle.TextPrimary, (TextAlignmentOptions)513);
			_backButton = PeakWindowStyle.CreatePill((Transform)(object)body, "BtnBack", Loc.T("run.btn.back"), 26f, 0f, 200f, 52f);
			PeakWindowStyle.SetPillSelected(_backButton, selected: false);
			((UnityEvent)_backButton.onClick).AddListener((UnityAction)delegate
			{
				_view = RaceView.RoleSelect;
				RefreshDisplay();
			});
			_cancelButton = PeakWindowStyle.CreatePill((Transform)(object)body, "BtnCancel", Loc.T("run.btn.cancel"), 26f, 0f, 220f, 52f);
			PeakWindowStyle.SetPillSelected(_cancelButton, selected: false);
			((UnityEvent)_cancelButton.onClick).AddListener(new UnityAction(CloseModal));
			_startButton = PeakWindowStyle.CreatePill((Transform)(object)body, "BtnStart", Loc.T("run.btn.start"), 26f, 0f, 270f, 52f, 22f);
			((UnityEvent)_startButton.onClick).AddListener(new UnityAction(StartSoloRun));
		}

		private void SetRandomMode(bool randomMode)
		{
			_randomMode = randomMode;
			RaceInfo raceInfo = RaceService.Instance?.CurrentRace;
			if (randomMode && raceInfo != null)
			{
				RaceService instance = RaceService.Instance;
				if (instance != null && instance.IsHost && raceInfo.Status == "lobby")
				{
					RollRandomIfNeeded();
				}
			}
			PushRaceConfig();
			RefreshDisplay();
		}

		private void OnSeedTyped(string value)
		{
			if (int.TryParse(value, out var result))
			{
				_seed = result;
				RefreshSummary();
			}
		}

		private void SetSeed(int seed)
		{
			_seed = seed;
			if ((Object)(object)_seedInput != (Object)null)
			{
				_seedInput.SetTextWithoutNotify(_seed.ToString());
			}
			RefreshSummary();
		}

		private void UseDailySeed()
		{
			if ((Object)(object)DailySeedService.Instance != (Object)null && DailySeedService.Instance.HasValidServerSeed)
			{
				SetSeed(DailySeedService.Instance.ServerSeed);
				PushRaceConfig();
			}
			else
			{
				SetSummary(Loc.T("run.msg.noDailySeed"));
			}
		}

		private void CopySeed()
		{
			GUIUtility.systemCopyBuffer = _seed.ToString();
			SetSummary(Loc.T("run.msg.seedCopied", _seed));
		}

		private void RollRandomIfNeeded()
		{
			if (_randomMode)
			{
				_seed = Random.Range(100000000, 999999999);
				int slotCount = MapCatalog.SlotCount;
				_levelSlot = ((slotCount > 0) ? Random.Range(0, slotCount) : 0);
			}
		}

		private void PushRaceConfig()
		{
			RaceService instance = RaceService.Instance;
			RaceInfo raceInfo = instance?.CurrentRace;
			if (_raceMode && !((Object)(object)instance == (Object)null) && raceInfo != null && instance.IsHost && !(raceInfo.Status != "lobby"))
			{
				instance.UpdateRaceConfig(_seed, _levelSlot, _ascent, _routeIndex, _maxPlayers, _autoStart, _showRivals, _randomMode, delegate(string err)
				{
					SetSummary(Loc.T("run.msg.configFailed", err));
				});
			}
		}

		private void StartSoloRun()
		{
			RollRandomIfNeeded();
			string sceneName = MapCatalog.GetSceneName(_levelSlot);
			RankedLog.Info("[CustomRun] Starte Speedrun (" + (_randomMode ? "RANDOM" : "STATIC") + ") - " + $"Seed {_seed}, Karte {sceneName} " + $"(Slot {_levelSlot}, Spiel {MapCatalog.GameVersion}), " + RunConfigService.GetAscentName(_ascent) + ", " + RunConfigService.GetRouteName(_routeIndex));
			SeedService.Instance?.SetOverrideSeed(_seed);
			if (!RankedRunGate.Select(GameMode.Speedrun, _levelSlot, _randomMode))
			{
				SeedService.Instance?.ClearOverrideSeed();
				RankedNoticeModal.Show(Loc.T("gate.mapAltered.title"), RankedRunGate.LastRefusal);
				return;
			}
			RunConfigService.ApplyCustomRun(_ascent, _routeIndex);
			RankedGameLauncher.ForceLevelIndex(_levelSlot);
			GhostPlaybackService.Instance?.ClearExternalGhost();
			CloseModal();
			RankedGameLauncher.LaunchDirectToIsland();
		}

		private void CreateRace()
		{
			RollRandomIfNeeded();
			SetSummary(Loc.T("run.msg.creating"));
			RaceService.Instance?.CreateRace(_seed, _levelSlot, _ascent, _routeIndex, _maxPlayers, _autoStart, _showRivals, _randomMode, delegate(RaceInfo race)
			{
				SetSummary(Loc.T("run.msg.created", race.InviteCode));
			}, delegate(string err)
			{
				SetSummary(Loc.T("run.msg.createFailed", err));
			});
		}

		private void JoinRace()
		{
			string text = (((Object)(object)_codeInput != (Object)null) ? _codeInput.text.Trim() : string.Empty);
			if (text.Length < 4)
			{
				SetSummary(Loc.T("run.msg.codeTooShort"));
				return;
			}
			SetSummary(Loc.T("run.msg.joining", text.ToUpperInvariant()));
			RaceService.Instance?.JoinRace(text, delegate(RaceInfo race)
			{
				SetSummary(Loc.T("run.msg.joined", race.Participants.Count, race.MaxPlayers));
			}, delegate(string err)
			{
				SetSummary(Loc.T("run.msg.joinFailed", err));
			});
		}

		private void GoToWaitingArea()
		{
			CloseModal();
			RaceService.Instance?.EnterWaitingArea();
		}

		private void CopyInviteCode()
		{
			RaceInfo raceInfo = RaceService.Instance?.CurrentRace;
			if (raceInfo != null)
			{
				GUIUtility.systemCopyBuffer = raceInfo.InviteCode;
				SetSummary(Loc.T("run.msg.codeCopied", raceInfo.InviteCode));
			}
		}

		private void RefreshDisplay()
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			if (!_built)
			{
				return;
			}
			RaceInfo raceInfo = RaceService.Instance?.CurrentRace;
			bool flag = raceInfo != null;
			bool flag2 = RaceService.Instance?.IsHost ?? false;
			if (_raceMode && flag)
			{
				_seed = raceInfo.Seed;
				_levelSlot = raceInfo.LevelIndex;
				_ascent = raceInfo.Ascent;
				_routeIndex = raceInfo.Route;
				_maxPlayers = raceInfo.MaxPlayers;
				_autoStart = raceInfo.AutoStart;
				_showRivals = raceInfo.GhostsVisible;
				_randomMode = raceInfo.SecretSeed;
			}
			bool interactable = !_raceMode || (!flag && _view == RaceView.HostSetup) || (flag && flag2 && raceInfo.Status == "lobby");
			PeakWindowStyle.SetPillSelected(_staticModeButton, !_randomMode);
			PeakWindowStyle.SetPillSelected(_randomModeButton, _randomMode, PeakWindowStyle.PillAccent);
			((Selectable)_staticModeButton).interactable = interactable;
			((Selectable)_randomModeButton).interactable = interactable;
			RefreshLayout();
			((Component)_startButton).gameObject.SetActive(!_raceMode);
			if ((Object)(object)_seedInput != (Object)null)
			{
				((Selectable)_seedInput).interactable = interactable;
				if (!_seedInput.isFocused)
				{
					_seedInput.SetTextWithoutNotify(_seed.ToString());
				}
			}
			for (int i = 0; i < _ascentPills.Count; i++)
			{
				PeakWindowStyle.SetPillSelected(_ascentPills[i], -1 + i == _ascent);
				((Selectable)_ascentPills[i]).interactable = interactable;
			}
			for (int j = 0; j < _routePills.Count; j++)
			{
				PeakWindowStyle.SetPillSelected(_routePills[j], j == _routeIndex);
				((Selectable)_routePills[j]).interactable = interactable;
			}
			((Selectable)_levelPrevButton).interactable = interactable;
			((Selectable)_levelNextButton).interactable = interactable;
			((Selectable)_todayButton).interactable = interactable;
			((Selectable)_dailyButton).interactable = interactable;
			((Selectable)_copySeedButton).interactable = interactable;
			((TMP_Text)_ascentDescriptionLabel).text = "<color=#" + ColorUtility.ToHtmlStringRGB(PeakWindowStyle.Heading) + ">" + RunConfigService.GetAscentName(_ascent) + "</color>   " + RunConfigService.GetAscentDescription(_ascent);
			((TMP_Text)_routeDescriptionLabel).text = RunConfigService.GetRouteDescription(_routeIndex);
			RefreshLevelDisplay();
			if (_raceMode)
			{
				RefreshRaceSection(raceInfo, flag, flag2);
			}
			RefreshSummary();
		}

		private void RefreshLayout()
		{
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Expected O, but got Unknown
			//IL_0326: Expected O, but got Unknown
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Expected O, but got Unknown
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Expected O, but got Unknown
			float num = 1128f;
			bool flag = RaceService.Instance?.CurrentRace != null;
			bool flag2 = _raceMode && !flag && _view == RaceView.RoleSelect;
			bool flag3 = _raceMode && !flag && _view == RaceView.JoinEntry;
			bool flag4 = !_raceMode || flag || _view == RaceView.HostSetup;
			((Component)_staticModeButton).gameObject.SetActive(flag4);
			((Component)_randomModeButton).gameObject.SetActive(flag4);
			((Component)_modeHintLabel).gameObject.SetActive(flag4);
			if ((Object)(object)_roleBox != (Object)null)
			{
				((Component)_roleBox).gameObject.SetActive(flag2);
			}
			bool flag5 = !flag2 && !flag3;
			((Component)_mountainBox).gameObject.SetActive(flag5 && !_randomMode);
			((Component)_randomBox).gameObject.SetActive(flag5 && _randomMode);
			((Component)_ascentBox).gameObject.SetActive(flag5);
			((Component)_routeBox).gameObject.SetActive(flag5);
			if ((Object)(object)_raceBox != (Object)null)
			{
				((Component)_raceBox).gameObject.SetActive(_raceMode && !flag2);
			}
			float num2 = 8f;
			if (flag2)
			{
				NativeUiFactory.Place(_roleBox, 26f, num2, num, 170f);
				num2 += 184f;
			}
			else if (flag3)
			{
				NativeUiFactory.Place(_raceBox, 26f, num2, num, 214f);
				num2 += 228f;
			}
			else
			{
				if (flag4)
				{
					num2 += 58f;
				}
				if (_randomMode)
				{
					NativeUiFactory.Place(_randomBox, 26f, num2, num, 96f);
					num2 += 110f;
				}
				else
				{
					NativeUiFactory.Place(_mountainBox, 26f, num2, num, 194f);
					num2 += 208f;
				}
				NativeUiFactory.Place(_ascentBox, 26f, num2, num, 128f);
				num2 += 142f;
				NativeUiFactory.Place(_routeBox, 26f, num2, num, 146f);
				num2 += 160f;
				if (_raceMode && (Object)(object)_raceBox != (Object)null)
				{
					NativeUiFactory.Place(_raceBox, 26f, num2, num, 214f);
					num2 += 228f;
				}
			}
			bool flag6 = _raceMode && !flag && _view != RaceView.RoleSelect;
			if ((Object)(object)_backButton != (Object)null)
			{
				((Component)_backButton).gameObject.SetActive(flag6);
				if (flag6)
				{
					NativeUiFactory.Place((RectTransform)((Component)_backButton).transform, 26f + num - 730f, num2, 200f, 52f);
				}
			}
			NativeUiFactory.Place((RectTransform)((TMP_Text)_summaryLabel).transform, 26f, num2, num - (flag6 ? 760f : 520f), 52f);
			NativeUiFactory.Place((RectTransform)((Component)_cancelButton).transform, 26f + num - 500f, num2, 220f, 52f);
			NativeUiFactory.Place((RectTransform)((Component)_startButton).transform, 26f + num - 270f, num2, 270f, 52f);
			float num3 = num2 + 52f + 18f;
			PeakWindowStyle.ResizeWindow(_window, 1180f, num3 + 82f + 14f, 82f);
		}

		private void RefreshLevelDisplay()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_levelLabel == (Object)null)
			{
				return;
			}
			string sceneName = MapCatalog.GetSceneName(_levelSlot);
			((TMP_Text)_levelLabel).text = (string.IsNullOrEmpty(sceneName) ? Loc.T("run.level.slot", _levelSlot) : sceneName);
			if (!((Object)(object)_levelDescriptionLabel == (Object)null))
			{
				int slotCount = MapCatalog.SlotCount;
				if (slotCount <= 0)
				{
					((TMP_Text)_levelDescriptionLabel).text = Loc.T("run.level.noCatalog");
					return;
				}
				string text = ColorUtility.ToHtmlStringRGB(PeakWindowStyle.TextMuted);
				bool flag = _levelSlot == MapCatalog.SlotOf(MapCatalog.CurrentLevelIndex);
				string text2 = ((!MapCatalog.IsSlotAuthentic(_levelSlot)) ? ("   <color=#" + text + ">·</color>   <color=#" + ColorUtility.ToHtmlStringRGB(PeakWindowStyle.Danger) + ">" + Loc.T("run.level.swapped", MapCatalog.ExpectedSceneName(_levelSlot)) + "</color>") : string.Empty);
				((TMP_Text)_levelDescriptionLabel).text = Loc.T("run.level.map", _levelSlot + 1, slotCount) + "   <color=#" + text + ">·</color>   " + Loc.T("run.level.biomes", MapCatalog.GetBiomeLabel(_levelSlot)) + "   <color=#" + text + ">·</color>   " + Loc.T("run.level.version", MapCatalog.GameVersion, MapCatalog.MapSetHash) + (flag ? ("   <color=#" + text + ">·</color>   " + Loc.T("run.level.today")) : string.Empty) + text2;
			}
		}

		private void RefreshRaceSection(RaceInfo race, bool inRace, bool isHost)
		{
			bool flag = !inRace && _view == RaceView.JoinEntry;
			bool flag2 = !inRace && _view == RaceView.HostSetup;
			bool flag3 = inRace && isHost && race.Status == "lobby";
			((TMP_Text)_playersLabel).text = Loc.T("run.players", inRace ? race.MaxPlayers : _maxPlayers);
			((Component)_playersLabel).gameObject.SetActive(!flag);
			((Component)_playersPrevButton).gameObject.SetActive(flag2 || flag3);
			((Component)_playersNextButton).gameObject.SetActive(flag2 || flag3);
			((Component)_autoStartButton).gameObject.SetActive(flag2 || inRace);
			((Selectable)_autoStartButton).interactable = flag2 || flag3;
			PeakWindowStyle.SetPillSelected(_autoStartButton, inRace ? race.AutoStart : _autoStart);
			((Component)_rivalsButton).gameObject.SetActive(flag2 || inRace);
			((Selectable)_rivalsButton).interactable = flag2 || flag3;
			PeakWindowStyle.SetPillSelected(_rivalsButton, inRace ? race.GhostsVisible : _showRivals);
			((Component)_joinHintLabel).gameObject.SetActive(flag);
			((TMP_Text)_codeLabel).text = (inRace ? race.InviteCode : string.Empty);
			((Component)_codeLabel).gameObject.SetActive(inRace);
			((Component)_codeInput).gameObject.SetActive(flag);
			((Component)_joinButton).gameObject.SetActive(flag);
			((Component)_createButton).gameObject.SetActive(flag2);
			((Component)_copyCodeButton).gameObject.SetActive(inRace);
			((Component)_waitingAreaButton).gameObject.SetActive(inRace);
			((Component)_hostStartButton).gameObject.SetActive(inRace && isHost);
			((Component)_leaveButton).gameObject.SetActive(inRace);
			for (int i = 0; i < _participantRows.Count; i++)
			{
				bool flag4 = inRace && i < race.Participants.Count;
				((Component)_participantRows[i]).gameObject.SetActive(flag4);
				if (flag4)
				{
					RaceParticipant raceParticipant = race.Participants[i];
					bool flag5 = raceParticipant.SteamId == race.HostSteamId;
					((TMP_Text)_participantRows[i]).text = raceParticipant.PlayerName + (flag5 ? (" (" + Loc.T("common.host") + ")") : string.Empty);
				}
			}
		}

		private void SetSummary(string text)
		{
			if ((Object)(object)_summaryLabel != (Object)null)
			{
				((TMP_Text)_summaryLabel).text = text;
			}
			RankedLog.Info("[Custom] " + text);
		}

		private void RefreshSummary()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_summaryLabel == (Object)null))
			{
				string text = ColorUtility.ToHtmlStringRGB(PeakWindowStyle.TextMuted);
				string text2 = "<color=#" + text + ">" + Loc.T("run.summary.seed") + "</color>";
				string text3 = (_randomMode ? (text2 + " ???   <color=#" + text + ">·</color>   ???") : ($"{text2} {_seed}   " + "<color=#" + text + ">·</color>   " + MapCatalog.GetSceneName(_levelSlot)));
				((TMP_Text)_summaryLabel).text = text3 + "   <color=#" + text + ">·</color>   " + RunConfigService.GetAscentName(_ascent) + "   <color=#" + text + ">·</color>   " + RunConfigService.GetRouteName(_routeIndex);
			}
		}
	}
	public class EndScreenTakeover : MonoBehaviour
	{
		private const float StandingsRefreshSeconds = 0.5f;

		private TMP_Text _timeLabel;

		private string _timeText = string.Empty;

		private TMP_Text[] _bannerLabels = Array.Empty<TMP_Text>();

		private string _bannerText = string.Empty;

		private RectTransform _standingsContent;

		private TMP_Text _standingsTemplate;

		private readonly List<TextMeshProUGUI> _standingRows = new List<TextMeshProUGUI>();

		private float _nextStandingsRefresh;

		public void Initialize(TMP_Text timeLabel, string timeText, TMP_Text[] bannerLabels, string bannerText)
		{
			_timeLabel = timeLabel;
			_timeText = timeText;
			_bannerLabels = bannerLabels ?? Array.Empty<TMP_Text>();
			_bannerText = bannerText;
		}

		private void RefreshBannerText()
		{
			RaceService instance = RaceService.Instance;
			RaceInfo raceInfo = instance?.CurrentRace ?? instance?.LastFinishedRace;
			if (raceInfo != null)
			{
				RaceParticipant raceParticipant = raceInfo.Participants.Find((RaceParticipant p) => p.SteamId == SteamIdentity.GetSteamId64());
				if (raceParticipant != null && raceParticipant.Rank.HasValue)
				{
					_bannerText = ((raceParticipant.Rank == 1) ? Loc.T("verdict.raceWon") : Loc.T("verdict.placeN", raceParticipant.Rank));
				}
			}
		}

		public void TrackStandings(RectTransform content, TMP_Text template, List<TextMeshProUGUI> rows)
		{
			_standingsContent = content;
			_standingsTemplate = template;
			_standingRows.Clear();
			_standingRows.AddRange(rows);
		}

		private void LateUpdate()
		{
			if ((Object)(object)_timeLabel != (Object)null && _timeLabel.text != _timeText)
			{
				_timeLabel.text = _timeText;
			}
			TMP_Text[] bannerLabels = _bannerLabels;
			foreach (TMP_Text val in bannerLabels)
			{
				if ((Object)(object)val != (Object)null && val.text != _bannerText)
				{
					val.text = _bannerText;
				}
			}
			if (!((Object)(object)_standingsContent == (Object)null) && !(Time.unscaledTime < _nextStandingsRefresh))
			{
				_nextStandingsRefresh = Time.unscaledTime + 0.5f;
				RefreshBannerText();
				RefreshStandings();
			}
		}

		private void RefreshStandings()
		{
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			RaceService instance = RaceService.Instance;
			RaceInfo raceInfo = instance?.CurrentRace ?? instance?.LastFinishedRace;
			if (raceInfo == null)
			{
				return;
			}
			List<RaceParticipant> list = new List<RaceParticipant>(raceInfo.Participants);
			list.Sort(CompareStandings);
			string steamId = SteamIdentity.GetSteamId64();
			for (int i = 0; i < _standingRows.Count; i++)
			{
				bool flag = i < list.Count;
				((Component)_standingRows[i]).gameObject.SetActive(flag);
				if (flag)
				{
					RaceParticipant raceParticipant = list[i];
					string text = (raceParticipant.Rank.HasValue ? $"#{raceParticipant.Rank.Value}" : "-");
					string state = raceParticipant.State;
					string text2 = ((state == "finished") ? (raceParticipant.TotalMs.HasValue ? FormatTime(raceParticipant.TotalMs.Value) : Loc.T("state.finished")) : ((!(state == "dnf")) ? $"{Mathf.RoundToInt(raceParticipant.Progress * 100f)} %" : Loc.T("state.dnf")));
					string text3 = text2;
					((TMP_Text)_standingRows[i]).text = text + "<pos=45%>" + raceParticipant.PlayerName + "<pos=80%>" + text3;
					Color color = (Color)(((Object)(object)_standingsTemplate != (Object)null) ? ((Graphic)_standingsTemplate).color : new Color(0.25f, 0.22f, 0.19f));
					color.a = ((raceParticipant.SteamId == steamId) ? 1f : 0.8f);
					((Graphic)_standingRows[i]).color = color;
				}
			}
		}

		private static int CompareStandings(RaceParticipant a, RaceParticipant b)
		{
			int num = Weight(a).CompareTo(Weight(b));
			if (num != 0)
			{
				return num;
			}
			if (Weight(a) == 0)
			{
				return (a.Rank ?? int.MaxValue).CompareTo(b.Rank ?? int.MaxValue);
			}
			return b.Progress.CompareTo(a.Progress);
			static int Weight(RaceParticipant p)
			{
				if (!(p.State == "finished"))
				{
					if (!(p.State == "dnf"))
					{
						return 1;
					}
					return 2;
				}
				return 0;
			}
		}

		private static string FormatTime(long ms)
		{
			TimeSpan timeSpan = TimeSpan.FromMilliseconds(ms);
			return $"{(int)timeSpan.TotalMinutes:00}:{timeSpan.Seconds:00}.{timeSpan.Milliseconds:000}";
		}
	}
	public class GhostStatusPanel : MonoBehaviour
	{
		private const float PanelWidth = 214f;

		private const float Padding = 10f;

		private const float BarHeight = 7f;

		private const float IconSize = 26