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 OverlayToggleKey { get; private set; } internal static ConfigEntry OverlayPositionX { get; private set; } internal static ConfigEntry OverlayPositionY { get; private set; } internal static ConfigEntry RunResetKey { get; private set; } internal static ConfigEntry SelectedMode { get; private set; } internal static ConfigEntry DebugSpawnLogging { get; private set; } internal static ConfigEntry LogLevel { get; private set; } internal static ConfigEntry RaceMenuKey { get; private set; } internal static ConfigEntry GhostEnabled { get; private set; } internal static ConfigEntry GhostOpacity { get; private set; } internal static ConfigEntry GhostItemsEnabled { get; private set; } internal static ConfigEntry RaceHudEnabled { get; private set; } internal static ConfigEntry RaceHudX { get; private set; } internal static ConfigEntry RaceHudY { get; private set; } internal static ConfigEntry ComparisonManual { get; private set; } internal static ConfigEntry GhostPanelEnabled { get; private set; } internal static ConfigEntry GhostPanelX { get; private set; } internal static ConfigEntry GhostPanelY { get; private set; } internal static ConfigEntry UseNativeTimer { get; private set; } internal static ConfigEntry ShowRunSummary { get; private set; } internal static ConfigEntry SummaryMinimized { get; private set; } internal static ConfigEntry 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("Overlay", "ToggleKey", (KeyCode)289, "Hotkey zum Ein-/Ausblenden des Timer-Overlays."); OverlayPositionX = ((BaseUnityPlugin)this).Config.Bind("Overlay", "PositionX", 10f, "Overlay X-Position in Pixeln (von links)."); OverlayPositionY = ((BaseUnityPlugin)this).Config.Bind("Overlay", "PositionY", 10f, "Overlay Y-Position in Pixeln (von oben)."); UseNativeTimer = ((BaseUnityPlugin)this).Config.Bind("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("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("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("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("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("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("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("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("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(0.1f, 1f), Array.Empty())); GhostItemsEnabled = ((BaseUnityPlugin)this).Config.Bind("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("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("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("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("Overlay", "RaceHudPositionY", 20f, "Y-Position der Renn-Anzeige in Canvas-Einheiten, von oben."); GhostPanelEnabled = ((BaseUnityPlugin)this).Config.Bind("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("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("Ranked", "GhostPanelPositionY", 260f, "Y-Position des Ghost-Panels in Canvas-Einheiten, von oben."); SummaryMinimized = ((BaseUnityPlugin)this).Config.Bind("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("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().Initialize(_raceTimer, _storageService); GameObject val2 = new GameObject("RankedPeak_NativeTimerPanel"); Object.DontDestroyOnLoad((Object)val2); val2.AddComponent().Initialize(_raceTimer, _storageService); GameObject val3 = new GameObject("RankedPeak_RunSummary"); Object.DontDestroyOnLoad((Object)val3); val3.AddComponent().Initialize(_raceTimer, _storageService); GameObject val4 = new GameObject("RankedPeak_Settings"); Object.DontDestroyOnLoad((Object)val4); val4.AddComponent(); GameObject val5 = new GameObject("RankedPeak_Help"); Object.DontDestroyOnLoad((Object)val5); val5.AddComponent(); GameObject val6 = new GameObject("RankedPeak_RunUpload"); Object.DontDestroyOnLoad((Object)val6); RunUploadService uploadService = val6.AddComponent(); GameObject val7 = new GameObject("RankedPeak_RunSentinel"); Object.DontDestroyOnLoad((Object)val7); val7.AddComponent(); _climbStorageService = new ClimbStorageService(); GameObject val8 = new GameObject("RankedPeak_ClimbTracking"); Object.DontDestroyOnLoad((Object)val8); val8.AddComponent().Initialize(_raceTimer, _climbStorageService, uploadService); GameObject val9 = new GameObject("RankedPeak_GhostStatus"); Object.DontDestroyOnLoad((Object)val9); val9.AddComponent(); GameObject val10 = new GameObject("RankedPeak_GhostPlayback"); Object.DontDestroyOnLoad((Object)val10); val10.AddComponent().Initialize(_raceTimer, _climbStorageService); _seedService = new SeedService(); GameObject val11 = new GameObject("RankedPeak_DailySeed"); Object.DontDestroyOnLoad((Object)val11); val11.AddComponent().RefreshIfStale(); GameObject val12 = new GameObject("RankedPeak_ModAllowlist"); Object.DontDestroyOnLoad((Object)val12); val12.AddComponent().RefreshIfStale(); GameObject val13 = new GameObject("RankedPeak_RatingService"); Object.DontDestroyOnLoad((Object)val13); val13.AddComponent(); GameObject val14 = new GameObject("RankedPeak_DuelService"); Object.DontDestroyOnLoad((Object)val14); val14.AddComponent(); GameObject val15 = new GameObject("RankedPeak_RaceService"); Object.DontDestroyOnLoad((Object)val15); val15.AddComponent(); GameObject val16 = new GameObject("RankedPeak_RaceHud"); Object.DontDestroyOnLoad((Object)val16); val16.AddComponent(); val16.AddComponent(); GameObject val17 = new GameObject("RankedPeak_AiDisclosureBanner"); Object.DontDestroyOnLoad((Object)val17); val17.AddComponent(); GameObject val18 = new GameObject("RankedPeak_RaceLive"); Object.DontDestroyOnLoad((Object)val18); val18.AddComponent(); GameObject val19 = new GameObject("RankedPeak_LiveGhosts"); Object.DontDestroyOnLoad((Object)val19); val19.AddComponent(); GameObject val20 = new GameObject("RankedPeak_UpdateCheck"); Object.DontDestroyOnLoad((Object)val20); val20.AddComponent(); 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 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 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 list = new List(); 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 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 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 span, float value) { BinaryPrimitives.WriteInt32LittleEndian(span, BitConverter.SingleToInt32Bits(value)); } private static float DecodeFloat(Span span) { return BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(span)); } private static void EncodeHalfFloat(Span span, HalfFloat half) { BinaryPrimitives.WriteUInt16LittleEndian(span, half.RawValue); } private static HalfFloat DecodeHalfFloat(Span span) { return new HalfFloat { RawValue = BinaryPrimitives.ReadUInt16LittleEndian(span) }; } private static void EncodeQuarterFloat(Span span, QuarterFloat quarter) { span[0] = quarter.RawValue; } private static QuarterFloat DecodeQuarterFloat(Span 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(); 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(); 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(); if ((Object)(object)component2 != (Object)null) { sb.AppendLine($"{text} -> Mask: showMaskGraphic={component2.showMaskGraphic}"); } Animator component3 = ((Component)node).GetComponent(); 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(true); string text2 = (((Object)(object)componentInChildren != (Object)null) ? (" text='" + ((TMP_Text)componentInChildren).text + "'") : string.Empty); Image component = ((Component)child).GetComponent(); 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(); 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 = "" + AiDisclosure.Label + "\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