Decompiled source of PEAK RANKED v0.10.3
plugins/RankedPeak.dll
Decompiled 11 hours ago
The result has been truncated due to the large size, download it to view full contents!
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