Decompiled source of PEAK RANKED v1.6.0
plugins/RankedPeak.dll
Decompiled 2 days 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.IO.Compression; 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.Text.RegularExpressions; 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; using Peak.Afflictions; using Peak.Network; using Photon.Pun; using Photon.Realtime; using Photon.Voice; using Photon.Voice.PUN; using Photon.Voice.Unity; using RankedPeak.Live; using RankedPeak.Localization; using RankedPeak.Models; using RankedPeak.Patches; using RankedPeak.Replay; 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.Audio; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.ControllerSupport; using Zorro.Core; using Zorro.Core.CLI; using Zorro.Core.Serizalization; 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("NEW: Chinese, Simplified and Traditional - localization by TFJSN (ETWML). REVIVE in LIVE RACE, REPLAY your failed runs, GHOSTS V2, TRAINING with pause and rewind, ELO ladder, daily cup, 1v1 duels and a speedrun timer.")] [assembly: AssemblyFileVersion("1.6.0.0")] [assembly: AssemblyInformationalVersion("1.6.0+d9cc34fa2fac0825ca291601e0319c186985fcbc")] [assembly: AssemblyProduct("RankedPeak")] [assembly: AssemblyTitle("RankedPeak")] [assembly: AssemblyMetadata("RepositoryUrl", "https://discord.gg/nKUHvzdmVp")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.6.0.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", "1.6.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.rankedpeak.mod"; public const string PluginName = "PEAK RANKED"; public const string PluginVersion = "1.6.0"; public const string VersionLabel = ""; private Harmony _harmony; private RunStorageService _storageService; private RaceTimer _raceTimer; private ClimbStorageService _climbStorageService; private SeedService _seedService; public static string DisplayVersion { get { if (!string.IsNullOrEmpty("")) { return "1.6.0 "; } return "1.6.0"; } } 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<float> GhostItemOpacity { get; private set; } internal static ConfigEntry<bool> VoiceReverb { get; private set; } internal static ConfigEntry<KeyCode> ReplayPlayPauseKey { get; private set; } internal static ConfigEntry<KeyCode> ReplaySeekBackKey { get; private set; } internal static ConfigEntry<KeyCode> ReplaySeekForwardKey { get; private set; } internal static ConfigEntry<KeyCode> ReplaySlowerKey { get; private set; } internal static ConfigEntry<KeyCode> ReplayFasterKey { get; private set; } internal static ConfigEntry<KeyCode> ReplayDockKey { get; private set; } internal static ConfigEntry<float> ReplaySeekSeconds { get; private set; } internal static ConfigEntry<KeyCode> TrainingPauseKey { get; private set; } internal static ConfigEntry<int> ReplayKeepDnf { get; private set; } internal static ClimbStorageService ClimbStorage { get; private set; } internal static ConfigEntry<bool> GhostItemsEnabled { get; private set; } internal static ConfigEntry<int> LiveGhostCount { get; private set; } internal static ConfigEntry<KeyCode> SpectateKey { get; private set; } internal static ConfigEntry<KeyCode> ClockToggleKey { 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> TrackVanillaRuns { get; private set; } internal static ConfigEntry<bool> SummaryMinimized { get; private set; } internal static ConfigEntry<KeyCode> SettingsMenuKey { get; private set; } internal static ConfigEntry<bool> ChatEnabled { get; private set; } internal static ConfigEntry<bool> ChatOutsideRace { get; private set; } internal static ConfigEntry<bool> RacePublic { get; private set; } internal static ConfigEntry<KeyCode> ChatFocusKey { get; private set; } internal static ConfigEntry<KeyCode> ChatToggleKey { get; private set; } internal static ConfigEntry<float> ChatX { get; private set; } internal static ConfigEntry<float> ChatY { get; private set; } internal static ConfigEntry<float> ChatFadeSeconds { 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 //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Expected O, but got Unknown //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Invalid comparison between Unknown and I4 //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Expected O, but got Unknown //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Expected O, but got Unknown //IL_0697: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: 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 fuenf Stufen an (0.2 / 0.4 / 0.6 / 0.8 / 1.0); hier ist jeder Wert dazwischen erlaubt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); GhostItemOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Ranked", "GhostItemOpacity", 0.6f, new ConfigDescription("Deckkraft der Items der Live-Ghosts: was sie in der Hand halten, ihre Ballons und was sie gesetzt haben (Seile, Ketten, Anker, Haken, Ranken). Getrennt von der Figur einstellbar - ein Seil, das man kaum sieht, ist im Weg, eine Figur, die man kaum sieht, nicht. Wirkt sofort.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); SpectateKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "SpectateKey", (KeyCode)289, "Nach dem eigenen Zieleinlauf in einem Live Race: als Geist auf der Insel bleiben und den anderen zusehen, statt in den Flughafen zu gehen. Dieselbe Taste beendet das Zuschauen wieder (Escape ebenfalls). KeyCode.None = deaktiviert."); ClockToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ClockToggleKey", (KeyCode)99, "Nach dem eigenen Zieleinlauf im Live Race, waehrend man jemandem zusieht: schaltet die grosse Uhr im Timer-Panel zwischen der eigenen, eingefrorenen Zielzeit und der laufenden Zeit des Beobachteten um. KeyCode.None = deaktiviert (dann bleibt die eigene Zeit stehen)."); LiveGhostCount = ((BaseUnityPlugin)this).Config.Bind<int>("Ranked", "LiveGhostCount", 4, new ConfigDescription("Wie viele Mitstreiter im Live-Race gleichzeitig als Figur erscheinen. 0 = keine. Nur eine Anzeigeeinstellung: der Host entscheidet, OB es ueberhaupt Figuren gibt (dann verwirft schon der Server Position und Animation) - dieser Wert kann das nur weiter einschraenken, nie aufheben. Gezeichnet werden immer die naechsten in Reichweite.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), 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."); RacePublic = ((BaseUnityPlugin)this).Config.Bind<bool>("Race", "ListInLobbyBrowser", false, "true = ein neu angelegtes Live Race steht im Lobby-Browser. false = nur mit Code zu finden. Merkt sich die letzte Wahl im Renn-Fenster."); 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."); TrackVanillaRuns = ((BaseUnityPlugin)this).Config.Bind<bool>("Overlay", "TrackVanillaRuns", false, "true = auch ein Lauf ausserhalb von PEAK RANKED (PLAY OFFLINE, HOST GAME, Beitritt zu einer fremden Lobby) bekommt Timer, Splits und Ergebniskarte. Vorgabe aus: ohne diesen Schalter bleibt ein Vanilla-Lauf unberuehrt - keine Anzeige, keine Aufzeichnung, kein Eintrag in der lokalen Ablage. Gewertet wird ein solcher Lauf so oder so nicht; die Zeit bleibt lokal. Der Schalter gilt ab dem naechsten Lauf, nicht mitten im laufenden."); VoiceReverb = ((BaseUnityPlugin)this).Config.Bind<bool>("Chat", "VoiceReverb", false, "true = die Stimmen der Mitstreiter im Live Race klingen wie die einer Spielfigur: Hall in Hoehlen und Echo ab 60 m Entfernung (VoiceObscuranceFilter des Spiels). Vorgabe aus - im Rennen ist man fast immer weit auseinander, und dann liegt auf jeder Stimme ein halbsekuendiges Echo. Richtung, Entfernung und der dumpfe Klang hinter Felsen bleiben in beiden Faellen."); ReplayPlayPauseKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Replay", "PlayPauseKey", (KeyCode)112, "Replay: Abspielen/Anhalten. KeyCode.None = deaktiviert. Die Leertaste ist fuer das Hochfliegen der freien Kamera reserviert."); if ((int)ReplayPlayPauseKey.Value == 32) { ReplayPlayPauseKey.Value = (KeyCode)112; } ReplaySeekBackKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Replay", "SeekBackKey", (KeyCode)276, "Replay: um ReplaySeekSeconds zurueckspulen."); ReplaySeekForwardKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Replay", "SeekForwardKey", (KeyCode)275, "Replay: um ReplaySeekSeconds vorspulen."); ReplaySlowerKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Replay", "SlowerKey", (KeyCode)274, "Replay: langsamer (0.25x / 0.5x / 1x / 2x / 4x)."); ReplayFasterKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Replay", "FasterKey", (KeyCode)273, "Replay: schneller."); ReplayDockKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Replay", "DockKey", (KeyCode)102, "Replay: Kamera am Ghost andocken oder frei fliegen (WASD, Leertaste/Strg hoch/runter, Shift schnell)."); TrainingPauseKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Replay", "TrainingPauseKey", (KeyCode)112, "Ghost-Training: alles einfrieren (Timer, Figur, Welt) und dem Ghost auf der Zeitleiste zusehen; dieselbe Taste setzt fort. Ist sie gleich der Play/Pause-Taste, gewinnt in der Pause das Fortsetzen - der Ghost laeuft dann ueber den Knopf in der Leiste."); ReplaySeekSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Replay", "SeekSeconds", 10f, new ConfigDescription("Sprungweite beim Spulen in Sekunden.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); ReplayKeepDnf = ((BaseUnityPlugin)this).Config.Bind<int>("Replay", "KeepDnfRecordings", 10, new ConfigDescription("Wie viele nicht beendete Laeufe (gestorben, abgebrochen) samt Aufzeichnung lokal bleiben - fuer REPLAY unter MEINE LAEUFE. Die aeltesten fallen zuerst. 0 = keine. Getrennt von den beendeten Laeufen, die eigene 100 Plaetze haben.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>())); ChatEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Chat", "Enabled", true, "true = im Live Race erscheint der Text-Chat der Teilnehmer (Flughafen und Insel). Details in docs/live-chat.md."); ChatOutsideRace = ((BaseUnityPlugin)this).Config.Bind<bool>("Chat", "ShowOutsideRace", false, "true = das Chat-Fenster ist auch ohne laufendes Rennen sichtbar. Vorgabe aus - ohne Rennen gibt es keine Mitspieler zu erreichen."); ChatFocusKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ChatFocusKey", (KeyCode)121, "Holt den Chat in den Schreibmodus: Eingabefeld auf, Tastatur wird abgefangen. Enter sendet, Escape verwirft - beides gibt den Fokus wieder frei. KeyCode.None = deaktiviert."); ChatToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ChatToggleKey", (KeyCode)290, "Blendet das gesamte Chat-Fenster samt Nachrichten ein und aus. KeyCode.None = deaktiviert."); ChatX = ((BaseUnityPlugin)this).Config.Bind<float>("Chat", "PositionX", 28f, "X-Position des Chat-Fensters in Canvas-Einheiten, von links. Bequemer ueber das Einstellungsfenster zu setzen: dort haengt sich die Anzeige an die Maus."); ChatY = ((BaseUnityPlugin)this).Config.Bind<float>("Chat", "PositionY", 760f, "Y-Position des Chat-Fensters in Canvas-Einheiten, von oben."); ChatFadeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Chat", "FadeSeconds", 12f, new ConfigDescription("Wie lange eine Zeile im Lesemodus stehen bleibt, bevor sie ausblendet. Im Schreibmodus altert nichts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 60f), Array.Empty<object>())); } 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Expected O, but got Unknown //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Expected O, but got Unknown //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Expected O, but got Unknown //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: 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>(); GameObject val8 = new GameObject("RankedPeak_Spectator"); Object.DontDestroyOnLoad((Object)val8); val8.AddComponent<SpectatorService>(); _climbStorageService = new ClimbStorageService(); ClimbStorage = _climbStorageService; GameObject val9 = new GameObject("RankedPeak_Replay"); Object.DontDestroyOnLoad((Object)val9); val9.AddComponent<ReplayService>(); GameObject val10 = new GameObject("RankedPeak_Revive"); Object.DontDestroyOnLoad((Object)val10); val10.AddComponent<ReviveController>(); GameObject val11 = new GameObject("RankedPeak_ClimbTracking"); Object.DontDestroyOnLoad((Object)val11); val11.AddComponent<ClimbTrackingService>().Initialize(_raceTimer, _climbStorageService, uploadService); GameObject val12 = new GameObject("RankedPeak_GhostStatus"); Object.DontDestroyOnLoad((Object)val12); val12.AddComponent<GhostStatusPanel>(); GameObject val13 = new GameObject("RankedPeak_GhostPlayback"); Object.DontDestroyOnLoad((Object)val13); val13.AddComponent<GhostPlaybackService>().Initialize(_raceTimer, _climbStorageService); _seedService = new SeedService(); GameObject val14 = new GameObject("RankedPeak_DailySeed"); Object.DontDestroyOnLoad((Object)val14); val14.AddComponent<DailySeedService>().RefreshIfStale(); GameObject val15 = new GameObject("RankedPeak_ModAllowlist"); Object.DontDestroyOnLoad((Object)val15); val15.AddComponent<ModAllowlistService>().RefreshIfStale(); GameObject val16 = new GameObject("RankedPeak_ItemBlocklist"); Object.DontDestroyOnLoad((Object)val16); val16.AddComponent<ItemBlocklistService>().RefreshIfStale(); GameObject val17 = new GameObject("RankedPeak_RatingService"); Object.DontDestroyOnLoad((Object)val17); val17.AddComponent<RatingService>(); GameObject val18 = new GameObject("RankedPeak_DuelService"); Object.DontDestroyOnLoad((Object)val18); val18.AddComponent<DuelService>(); GameObject val19 = new GameObject("RankedPeak_RaceService"); Object.DontDestroyOnLoad((Object)val19); val19.AddComponent<RaceService>(); GameObject val20 = new GameObject("RankedPeak_RaceHud"); Object.DontDestroyOnLoad((Object)val20); val20.AddComponent<RaceHudOverlay>(); val20.AddComponent<RaceCountdownOverlay>(); GameObject val21 = new GameObject("RankedPeak_RaceLive"); Object.DontDestroyOnLoad((Object)val21); val21.AddComponent<RaceLiveConnection>(); GameObject val22 = new GameObject("RankedPeak_LiveGhosts"); Object.DontDestroyOnLoad((Object)val22); val22.AddComponent<LiveGhostManager>(); val22.AddComponent<GhostPlacements>(); GameObject val23 = new GameObject("RankedPeak_LiveChat"); Object.DontDestroyOnLoad((Object)val23); val23.AddComponent<LiveChatOverlay>(); GameObject val24 = new GameObject("RankedPeak_RaceVoice"); Object.DontDestroyOnLoad((Object)val24); val24.AddComponent<RaceVoiceService>(); val24.AddComponent<RaceVoiceMixerPanel>(); RankedRoomGuard.Install(); GameObject val25 = new GameObject("RankedPeak_UpdateCheck"); Object.DontDestroyOnLoad((Object)val25); val25.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)); _harmony.PatchAll(typeof(SpectatorPatches)); _harmony.PatchAll(typeof(RankedExitPatch)); 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(GhostPlacementPatches.VineBuiltPatch)); _harmony.PatchAll(typeof(GhostPlacementPatches.PitonHammeredPatch)); _harmony.PatchAll(typeof(WeatherSyncPatches.ZoneStartPatch)); _harmony.PatchAll(typeof(WeatherSyncPatches.ZoneTimePatch)); _harmony.PatchAll(typeof(WeatherSyncPatches.SpawnerPatch)); _harmony.PatchAll(typeof(WeatherSyncPatches.TornadoStartPatch)); _harmony.PatchAll(typeof(WeatherSyncPatches.TornadoTargetPatch)); _harmony.PatchAll(typeof(WeatherSyncPatches.DayTimePatch)); _harmony.PatchAll(typeof(ReplayCursorPatch)); _harmony.PatchAll(typeof(ReviveGuardPatches.TryCheckpointPatch)); _harmony.PatchAll(typeof(ReviveGuardPatches.DieInstantlyPatch)); _harmony.PatchAll(typeof(ReviveGuardPatches.DieInstantlyLocalPatch)); _harmony.PatchAll(typeof(ReviveGuardPatches.HandlePassedOutPatch)); _harmony.PatchAll(typeof(RaceVoicePatches.RoomNamePatch)); _harmony.PatchAll(typeof(RaceVoicePatches.RegionPatch)); _harmony.PatchAll(typeof(RaceVoicePatches.SpeakerPatch)); _harmony.PatchAll(typeof(HotbarKeyWasPressedWhileTypingPatch)); _harmony.PatchAll(typeof(HotbarKeyIsPressedWhileTypingPatch)); _harmony.PatchAll(typeof(PauseWhileTypingPatch)); _harmony.PatchAll(typeof(RunSettingsPatch)); _harmony.PatchAll(typeof(ItemBlockPatch)); _harmony.PatchAll(typeof(SteamLobbyCreatedPatch)); _harmony.PatchAll(typeof(RankedRoomPrivacyPatches.HostRoomOptionsPatch)); _harmony.PatchAll(typeof(RankedRoomPrivacyPatches.LobbyTypePatch)); _harmony.PatchAll(typeof(RankedRoomPrivacyPatches.RichPresencePatch)); 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(); ItemBlocklistService.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 = "1.6.0"; public const string Label = ""; 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 { public class CustomRunModal : MenuWindow { private enum RaceView { RoleSelect, HostSetup, JoinEntry, Board } 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 = 32; private const int ParticipantColumns = 4; private const float ParticipantRowHeight = 22f; private static readonly int[] PlayerSteps = new int[9] { 2, 3, 4, 6, 8, 12, 16, 24, 32 }; private static readonly int[] AutoEndStepsMs = new int[7] { 0, 30000, 60000, 120000, 180000, 300000, 600000 }; 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 = 300f; private const float RoleBoxHeight = 170f; private const float FooterHeight = 52f; private const float JoinBoxHeight = 170f; private const float BrowserHeight = 540f; private const float LobbyRefreshSeconds = 5f; 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 _rollSeedButton; 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 _joinButton; private Button _spectateButton; private Button _spectatorsButton; private Button _autoEndButton; private Button _voiceButton; private Button _rulesButton; private Button _visibilityButton; private RaceLobbyBrowser _browser; private bool _browserVisible; private bool _lobbyFetchInFlight; private float _nextLobbyFetch; 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 readonly List<RaceParticipant> _standings = new List<RaceParticipant>(); private PeakWindowStyle.ScrollArea _participantArea; private RaceBoardPanel _boardPanel; 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 = true; private bool _spectatorsAllowed = true; private int _autoEndMs; private bool _voiceChat; private bool _isPublic; private readonly RaceRules _rules = new RaceRules(); private GameObject _panelPlaceholder; private int _openedFrame = -1; 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() { _openedFrame = Time.frameCount; if (!_built || (Object)(object)_root == (Object)null) { BuildUi(); } if (_raceMode && RaceService.Instance?.CurrentRace == null) { _view = RaceView.RoleSelect; _isPublic = Plugin.RacePublic.Value; } else if (_raceMode && (ForcedBoardView() || _view != RaceView.HostSetup)) { _view = RaceView.Board; } _levelSlot = MapCatalog.SlotOf(MapCatalog.CurrentLevelIndex); RefreshDisplay(); ((MenuWindow)this).Open(); NativeUiFactory.EnsureTopMost(); } public void CloseModal() { ((MenuWindow)this).Close(); } public static void CloseAll() { if ((Object)(object)_raceInstance != (Object)null && ((MenuWindow)_raceInstance).isOpen) { _raceInstance.CloseModal(); } if ((Object)(object)_speedrunInstance != (Object)null && ((MenuWindow)_speedrunInstance).isOpen) { _speedrunInstance.CloseModal(); } } 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(); _boardPanel = null; _browser = null; if (isOpen) { ShowModal(); } } } private void OnRaceUpdated(RaceInfo race) { if (_raceMode) { RefreshDisplay(); if (race != null && (race.Status == "loading" || race.Status == "countdown")) { CloseModal(); } } } private static bool ForcedBoardView() { RaceInfo raceInfo = RaceService.Instance?.CurrentRace; if (raceInfo != null) { return raceInfo.Status != "lobby"; } return false; } public override void Update() { if (!((MenuWindow)this).isOpen) { return; } if ((Object)(object)_root == (Object)null) { RankedLog.Warning("[Custom] Fenster offen, aber ohne Anzeige - wird geschlossen."); ((MenuWindow)this).Close(); return; } bool flag = ((Object)(object)_seedInput != (Object)null && _seedInput.isFocused) || ((Object)(object)_codeInput != (Object)null && _codeInput.isFocused); if (Input.GetKeyDown((KeyCode)27) && !flag && Time.frameCount > _openedFrame && !RaceRulesModal.IsAnyOpen && !RacePlayersModal.IsAnyOpen) { CloseModal(); } if (_browserVisible && !_lobbyFetchInFlight && Time.unscaledTime >= _nextLobbyFetch) { FetchLobbies(); } RaceInfo raceInfo = RaceService.Instance?.CurrentRace; if (_view == RaceView.HostSetup && ForcedBoardView()) { _view = RaceView.Board; RefreshDisplay(); } if (_boardPanel != null && raceInfo != null && _view != RaceView.HostSetup) { _boardPanel.Refresh(raceInfo, RaceService.Instance?.IsHost ?? false); } } 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); BuildBrowser(body, innerWidth); BuildBoard(body, innerWidth); } BuildFooter(body, innerWidth); } private void BuildBrowser(RectTransform body, float innerWidth) { _browser = RaceLobbyBrowser.Create((Transform)(object)body, "BoxBrowser", 26f, 0f, innerWidth, 540f); _browser.RefreshRequested = delegate { _nextLobbyFetch = 0f; }; _browser.Join = delegate(RaceLobbyEntry entry) { _codeInput.text = entry.InviteCode; JoinRace(); }; _browser.Spectate = delegate(RaceLobbyEntry entry) { _codeInput.text = entry.InviteCode; SpectateRace(); }; _browser.SetActive(active: false); } private void FetchLobbies() { RaceService instance = RaceService.Instance; if (!((Object)(object)instance == (Object)null)) { _lobbyFetchInFlight = true; instance.FetchLobbies(delegate(List<RaceLobbyEntry> entries, int total) { _lobbyFetchInFlight = false; _nextLobbyFetch = Time.unscaledTime + 5f; _browser?.SetEntries(entries, total); }, delegate(string error) { _lobbyFetchInFlight = false; _nextLobbyFetch = Time.unscaledTime + 5f; _browser?.SetError(error); }); } } 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; _isPublic = Plugin.RacePublic.Value; 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Expected O, but got Unknown //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: 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_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Expected O, but got Unknown //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: 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, 300f, 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"), 336f, 50f, 130f, 52f, 19f); ((UnityEvent)_dailyButton.onClick).AddListener(new UnityAction(UseDailySeed)); _rollSeedButton = PeakWindowStyle.CreatePill((Transform)(object)_mountainBox, "BtnRollSeed", Loc.T("run.btn.rollSeed"), 476f, 50f, 150f, 52f, 19f); ((UnityEvent)_rollSeedButton.onClick).AddListener(new UnityAction(RollSeed)); _copySeedButton = PeakWindowStyle.CreatePill((Transform)(object)_mountainBox, "BtnCopySeed", Loc.T("run.btn.copySeed"), 636f, 50f, 150f, 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"), 16f, PeakWindowStyle.TextMuted, (TextAlignmentOptions)513)).transform, 800f, 50f, num - 776f, 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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Expected O, but got Unknown //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Expected O, but got Unknown //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Expected O, but got Unknown //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Expected O, but got Unknown //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Expected O, but got Unknown //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Expected O, but got Unknown //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Expected O, but got Unknown //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Expected O, but got Unknown //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_058b: Expected O, but got Unknown //IL_05d6: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Expected O, but got Unknown //IL_062b: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Expected O, but got Unknown //IL_0696: Unknown result type (might be due to invalid IL or missing references) //IL_06a0: Expected O, but got Unknown //IL_071a: Unknown result type (might be due to invalid IL or missing references) //IL_0738: Unknown result type (might be due to invalid IL or missing references) //IL_075a: Expected O, but got Unknown _raceBox = PeakWindowStyle.CreateBox((Transform)(object)body, "BoxRace", Loc.T("run.box.race"), 26f, 0f, innerWidth, 300f); float num = innerWidth - 48f; _playersPrevButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnPlayersPrev", "-", 24f, 50f, 52f, 42f); ((UnityEvent)_playersPrevButton.onClick).AddListener((UnityAction)delegate { _maxPlayers = StepPlayers(_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 = StepPlayers(_maxPlayers, 1); PushRaceConfig(); RefreshDisplay(); }); _autoStartButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnAutoStart", Loc.T("run.btn.autoStart"), 314f, 50f, 180f, 42f, 18f); ((UnityEvent)_autoStartButton.onClick).AddListener((UnityAction)delegate { _autoStart = !_autoStart; PushRaceConfig(); RefreshDisplay(); }); _rivalsButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnRivals", Loc.T("run.btn.rivals"), 504f, 50f, 240f, 42f, 16f); ((UnityEvent)_rivalsButton.onClick).AddListener((UnityAction)delegate { _showRivals = !_showRivals; PushRaceConfig(); RefreshDisplay(); }); _voiceButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnVoice", Loc.T("run.btn.voice"), 754f, 50f, 140f, 42f, 16f); ((UnityEvent)_voiceButton.onClick).AddListener((UnityAction)delegate { _voiceChat = !_voiceChat; PushRaceConfig(); RefreshDisplay(); }); _spectatorsButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnSpectators", Loc.T("run.btn.spectators"), 24f, 104f, 260f, 46f, 16f); ((UnityEvent)_spectatorsButton.onClick).AddListener((UnityAction)delegate { _spectatorsAllowed = !_spectatorsAllowed; PushRaceConfig(); RefreshDisplay(); }); _autoEndButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnAutoEnd", string.Empty, 296f, 104f, 230f, 46f, 16f); ((UnityEvent)_autoEndButton.onClick).AddListener((UnityAction)delegate { _autoEndMs = NextAutoEnd(_autoEndMs); PushRaceConfig(); RefreshDisplay(); }); _rulesButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnRules", Loc.T("run.btn.rules"), 538f, 104f, 200f, 46f, 16f); ((UnityEvent)_rulesButton.onClick).AddListener(new UnityAction(OpenRulesWindow)); _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 - 200f, 50f, 200f, 42f); _visibilityButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnVisibility", string.Empty, 24f + num - 200f, 50f, 200f, 42f, 16f); ((UnityEvent)_visibilityButton.onClick).AddListener((UnityAction)delegate { _isPublic = !_isPublic; Plugin.RacePublic.Value = _isPublic; RefreshDisplay(); }); _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)); _spectateButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnSpectate", Loc.T("run.btn.spectate"), 438f, 104f, 190f, 46f, 19f); ((UnityEvent)_spectateButton.onClick).AddListener(new UnityAction(SpectateRace)); _createButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnCreateRace", Loc.T("run.btn.create"), 24f + num - 300f, 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, 190f, 46f, 16f); ((UnityEvent)_copyCodeButton.onClick).AddListener(new UnityAction(CopyInviteCode)); _hostStartButton = PeakWindowStyle.CreatePill((Transform)(object)_raceBox, "BtnHostStart", Loc.T("run.btn.startRace"), 224f, 104f, 230f, 46f, 18f); ((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"), 914f, 104f, 190f, 46f, 18f); PeakWindowStyle.SetPillSelected(_leaveButton, selected: false); ((UnityEvent)_leaveButton.onClick).AddListener((UnityAction)delegate { RaceService.Instance?.LeaveRace(); SetSummary(Loc.T("run.msg.left")); LeaveMountain(); }); float height = 128f; float contentHeight = Mathf.Ceil(8f) * 22f; _participantArea = PeakWindowStyle.CreateScrollArea((Transform)(object)_raceBox, "Participants", 24f, 160f, num, height, contentHeight); float num2 = _participantArea.ContentWidth / 4f; for (int num3 = 0; num3 < 32; num3++) { TextMeshProUGUI val = PeakWindowStyle.CreateText((Transform)(object)_participantArea.Content, $"Participant{num3}", string.Empty, 18f, PeakWindowStyle.TextPrimary, (TextAlignmentOptions)513); NativeUiFactory.Place((RectTransform)((TMP_Text)val).transform, (float)(num3 % 4) * num2, (float)(num3 / 4) * 22f, num2, 22f); ((TMP_Text)val).textWrappingMode = (TextWrappingModes)0; ((Component)val).gameObject.SetActive(false); _participantRows.Add(val); } } private static int StepPlayers(int current, int direction) { int num = 0; for (int i = 1; i < PlayerSteps.Length; i++) { if (Mathf.Abs(PlayerSteps[i] - current) < Mathf.Abs(PlayerSteps[num] - current)) { num = i; } } if (PlayerSteps[num] == current) { num = Mathf.Clamp(num + direction, 0, PlayerSteps.Length - 1); } else if (direction > 0 && PlayerSteps[num] < current) { num = Mathf.Min(num + 1, PlayerSteps.Length - 1); } else if (direction < 0 && PlayerSteps[num] > current) { num = Mathf.Max(num - 1, 0); } return PlayerSteps[num]; } private static int NextAutoEnd(int current) { int num = Array.IndexOf(AutoEndStepsMs, current); if (num < 0) { for (int i = 0; i < AutoEndStepsMs.Length; i++) { if (AutoEndStepsMs[i] > current) { return AutoEndStepsMs[i]; } } return 0; } return AutoEndStepsMs[(num + 1) % AutoEndStepsMs.Length]; } private void OpenRulesWindow() { RaceService instance = RaceService.Instance; RaceInfo raceInfo = instance?.CurrentRace; bool editable = ((raceInfo == null) ? (_view == RaceView.HostSetup) : (instance.IsHost && raceInfo.Status == "lobby")); RaceRulesModal.OpenWindow(_rules, editable, () => _ascent, delegate { PushRaceConfig(); RefreshDisplay(); }); } private void StepLevel(int direction) { int slotCount = MapCatalog.SlotCount; if (slotCount > 0) { _levelSlot = ((_levelSlot + direction) % slotCount + slotCount) % slotCount; PushRaceConfig(); RefreshDisplay(); } } private void BuildBoard(RectTransform body, float innerWidth) { _boardPanel = RaceBoardPanel.Create((Transform)(object)body, "BoxBoard", 26f, 0f, innerWidth); _boardPanel.CopyCode = CopyInviteCode; _boardPanel.HostStart = delegate { RaceService.Instance?.StartRace(delegate(string err) { SetSummary(Loc.T("run.msg.startFailed", err)); }); }; _boardPanel.EditSettings = delegate { _view = RaceView.HostSetup; RefreshDisplay(); }; _boardPanel.Leave = delegate { SpectatorService instance = SpectatorService.Instance; RaceService instance2 = RaceService.Instance; if (instance2 != null && instance2.IsSpectator) { CloseModal(); RaceService.Instance.LeaveRace(); instance?.LeaveToMainMenu("Zuschauer verlaesst das Rennen"); } else if ((Object)(object)instance != (Object)null && instance.WorldHeld) { CloseModal(); instance.LeaveToMainMenu("Knopf im Board"); } else { RaceService.Instance?.LeaveRace(); SetSummary(Loc.T("run.msg.left")); LeaveMountain(); } }; _boardPanel.FollowParticipant = delegate(string steamId) { SpectatorService.Instance?.JumpTo(steamId); CloseModal(); }; _boardPanel.SetVisibility = delegate(bool isPublic) { Plugin.RacePublic.Value = isPublic; RaceService.Instance?.SetPublic(isPublic, delegate(string err) { SetSummary(Loc.T("run.msg.configFailed", err)); }); }; _boardPanel.ManagePlayers = RacePlayersModal.OpenWindow; _boardPanel.Spectate = delegate { CloseModal(); SpectatorService.Instance?.Begin(); }; _boardPanel.Forfeit = delegate { RaceService.Instance?.Forfeit(); SetSummary(Loc.T("board.msg.forfeited")); }; } private void LeaveMountain() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); if (!((Scene)(ref activeScene)).name.StartsWith("Level_")) { return; } CloseModal(); try { RankedLog.Info("[Custom] Rennen verlassen - zurueck ins Hauptmenue."); Player.LeaveCurrentGame(); } catch (Exception ex) { RankedLog.Error("[Custom] Rueckweg ins Hauptmenue fehlgeschlagen: " + ex.Message); } } 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 = ((RaceService.Instance?.CurrentRace != null) ? RaceView.Board : 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 RollSeed() { SetSeed(Random.Range(1000000