Decompiled source of ClimbInfoTracker v0.5.1
plugins/com.github.LengSword.ClimbInfoTracker.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ClimbInfoTracker.Compatibility; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using PLL.Library; using Peak; using Peak.Network; using Photon.Pun; using Photon.Realtime; using Portningsbolaget.Platforms; using Steamworks; using TMPro; using TerrainRandomiser; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; using Zorro.Core.Editor; using Zorro.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.LengSword.ClimbInfoTracker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.5.1.0")] [assembly: AssemblyInformationalVersion("0.5.1+26cc5347d83bd0303e058b6a80e4aac3ec44449e")] [assembly: AssemblyProduct("com.github.LengSword.ClimbInfoTracker")] [assembly: AssemblyTitle("ClimbInfoTracker")] [assembly: AssemblyMetadata("RepositoryUrl", "https://codeberg.org/yls-peak-mods/ClimbInfoTracker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.5.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer<T>.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { if (!EqualityComparer<T>.Default.Equals(_item, item)) { return -1; } return 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace ClimbInfoTracker { internal static class ClimbOutcome { internal const string InProgress = "InProgress"; internal const string Summited = "Summited"; internal const string Failed = "Failed"; internal const string Abandoned = "Abandoned"; internal static bool IsCompleted(string outcome) { switch (outcome) { case "Summited": case "Failed": case "Abandoned": return true; default: return false; } } } internal static class ClimbNetworkMode { internal const string Offline = "Offline"; internal const string Multiplayer = "Multiplayer"; } internal enum RunIdConfirmationResult { NoChange, Confirmed, Resumed, Conflict } [DataContract] internal sealed class ClimbRecord { [DataMember(Order = 1)] public string RunId { get; set; } = ""; [DataMember(Order = 2)] public string StartedAtUtc { get; set; } = ""; [DataMember(Order = 3)] public string EndedAtUtc { get; set; } = ""; [DataMember(Order = 4)] public string Outcome { get; set; } = "InProgress"; [DataMember(Order = 5)] public float DurationSeconds { get; set; } [DataMember(Order = 6)] public float CurrentHeightMeters { get; set; } [DataMember(Order = 7)] public int Ascent { get; set; } [DataMember(Order = 8)] public int PlayerCount { get; set; } = 1; [DataMember(Order = 9)] public bool IsCustomRun { get; set; } [DataMember(Order = 10)] public bool IsMiniRun { get; set; } [DataMember(Order = 11)] public string Level { get; set; } = ""; [DataMember(Order = 12)] public string Biome { get; set; } = ""; [DataMember(Order = 13)] public bool TerrainRandomiserEnabled { get; set; } [DataMember(Order = 14)] public int TerrainRandomiserSeed { get; set; } = -1; [DataMember(Order = 15)] public string TerrainRandomiserMapSettingsBrotliBase64 { get; set; } = ""; [DataMember(Order = 16)] public string NetworkMode { get; set; } = ""; [DataMember(Order = 17)] public string PhotonRoomName { get; set; } = ""; [DataMember(Order = 18)] public List<MapBiomeInfo> MapBiomes { get; set; } = new List<MapBiomeInfo>(); [DataMember(Order = 19, EmitDefaultValue = false)] public int? PLLMapSeed { get; set; } [DataMember(Order = 20)] public List<int> MapSegmentBiomeIndices { get; set; } = new List<int>(); [DataMember(Order = 21)] public List<ClimbPlayerInfo> OtherPlayers { get; set; } = new List<ClimbPlayerInfo>(); [DataMember(Order = 22)] public bool RunIdConfirmed { get; set; } [DataMember(Order = 23)] public bool TrueFinalAscentEnabled { get; set; } [DataMember(Order = 24, EmitDefaultValue = false)] public int? TFAMapSeed { get; set; } [DataMember(Order = 25)] public bool TFAApocalypseEnabled { get; set; } [DataMember(Order = 26, EmitDefaultValue = false)] public string TfaCurrentBiomeId { get; set; } = ""; [DataMember(Order = 27, EmitDefaultValue = false)] public List<ClimbSegmentTiming>? SegmentTimings { get; set; } [DataMember(Order = 28, EmitDefaultValue = false)] public string SegmentTimingMapKey { get; set; } = ""; } [DataContract] internal sealed class ClimbPlayerInfo { [DataMember(Order = 1)] public string Platform { get; set; } = ""; [DataMember(Order = 2)] public string PlatformUserId { get; set; } = ""; [DataMember(Order = 3)] public string DisplayName { get; set; } = ""; } [DataContract] internal enum TfaBiomeScaleAxis { [EnumMember] Height, [EnumMember] Length } [DataContract] internal sealed class MapBiomeInfo { [DataMember(Order = 1)] public BiomeType BiomeType { get; set; } [DataMember(Order = 2)] public string Variant { get; set; } = ""; [DataMember(Order = 3)] public bool? OpenTomb { get; set; } [DataMember(Order = 4, EmitDefaultValue = false)] public string TitleKey { get; set; } = ""; [DataMember(Order = 5, EmitDefaultValue = false)] public int? TfaSegmentIndex { get; set; } [DataMember(Order = 6, EmitDefaultValue = false)] public int? TfaChainIndex { get; set; } [DataMember(Order = 7, EmitDefaultValue = false)] public string TfaBiomeId { get; set; } = ""; [DataMember(Order = 8, EmitDefaultValue = false)] public Dictionary<string, string> TfaBiomeNames { get; set; } = new Dictionary<string, string>(); [DataMember(Order = 9, EmitDefaultValue = false)] public bool IsRouteTerminal { get; set; } [DataMember(Order = 10, EmitDefaultValue = false)] public int? TfaScalePercent { get; set; } [DataMember(Order = 11, EmitDefaultValue = false)] public TfaBiomeScaleAxis? TfaScaleAxis { get; set; } } [DataContract] internal sealed class ClimbHistoryData { [DataMember(Order = 1)] public int SchemaVersion { get; set; } = 16; [DataMember(Order = 2)] public List<ClimbRecord> Records { get; set; } = new List<ClimbRecord>(); [DataMember(Order = 3, EmitDefaultValue = false)] public ClimbRecord? ActiveRecord { get; set; } } internal sealed class ClimbHistory { private const int CurrentSchemaVersion = 16; private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings { ConstructorHandling = (ConstructorHandling)1, DateParseHandling = (DateParseHandling)0, Converters = { (JsonConverter)new StringEnumConverter() } }; private readonly ClimbHistoryStorage _storage; private ClimbHistoryData _data; internal ClimbRecord? ActiveRecord => _data.ActiveRecord; internal ClimbHistory() { string path = Path.Combine(Application.persistentDataPath, "ClimbInfoTracker", "ClimbInfoTracker.json"); _storage = new ClimbHistoryStorage(path, Deserialize); _data = _storage.Load(); } internal IReadOnlyList<ClimbRecord> GetRecords() { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord == null) { return _data.Records.ToArray(); } List<ClimbRecord> records = _data.Records; List<ClimbRecord> list = new List<ClimbRecord>(1 + records.Count); list.AddRange(records); list.Add(activeRecord); return list; } internal void Begin(ClimbRecord record) { if (_data.ActiveRecord != null) { if (_data.ActiveRecord.RunId == record.RunId) { return; } FinalizeActive("Abandoned", _data.ActiveRecord.DurationSeconds); } NormalizeRecord(record); _data.ActiveRecord = record; Save(flushToDisk: true); } internal bool TryResumeMultiplayerRun(ClimbRecord currentRecord, float? elapsedSeconds) { if (currentRecord.NetworkMode != "Multiplayer" || string.IsNullOrWhiteSpace(currentRecord.PhotonRoomName) || !currentRecord.RunIdConfirmed) { return false; } ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null && IsRunResumeCandidate(activeRecord, currentRecord.PhotonRoomName, currentRecord.RunId)) { RefreshResumedRecord(activeRecord, currentRecord, elapsedSeconds); Save(flushToDisk: true); return true; } for (int num = _data.Records.Count - 1; num >= 0; num--) { ClimbRecord climbRecord = _data.Records[num]; if (IsRunResumeCandidate(climbRecord, currentRecord.PhotonRoomName, currentRecord.RunId)) { if (_data.ActiveRecord != null) { FinalizeActive("Abandoned", _data.ActiveRecord.DurationSeconds); } _data.Records.Remove(climbRecord); RefreshResumedRecord(climbRecord, currentRecord, elapsedSeconds); _data.ActiveRecord = climbRecord; Save(flushToDisk: true); return true; } } return false; } internal void Snapshot(float durationSeconds, float currentHeightMeters, string biome, int playerCount, string networkMode, string photonRoomName, string? tfaCurrentBiomeId = null) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null) { activeRecord.DurationSeconds = durationSeconds; activeRecord.CurrentHeightMeters = Math.Max(activeRecord.CurrentHeightMeters, currentHeightMeters); UpdateBiome(activeRecord, biome, tfaCurrentBiomeId); activeRecord.PlayerCount = Math.Max(activeRecord.PlayerCount, Math.Max(1, playerCount)); UpdateNetworkState(activeRecord, networkMode, photonRoomName); Save(); } } internal void ObservePlayers(IReadOnlyList<ClimbPlayerInfo> players, int playerCount) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null) { bool flag = false; int num = Math.Max(activeRecord.PlayerCount, Math.Max(1, playerCount)); if (num != activeRecord.PlayerCount) { activeRecord.PlayerCount = num; flag = true; } ClimbRecord climbRecord = activeRecord; if (climbRecord.OtherPlayers == null) { List<ClimbPlayerInfo> list = (climbRecord.OtherPlayers = new List<ClimbPlayerInfo>()); } if (flag | MergePlayers(activeRecord.OtherPlayers, players)) { Save(); } } } internal void EnsureActiveMapBiomeCapture(MapBiomeCapture capture) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null && capture.MapBiomes.Count != 0) { bool flag = false; if (activeRecord.MapBiomes == null || activeRecord.MapBiomes.Count == 0) { activeRecord.MapBiomes = CopyMapBiomes(capture.MapBiomes); flag = true; } if ((activeRecord.MapSegmentBiomeIndices == null || activeRecord.MapSegmentBiomeIndices.Count == 0) && SameTfaRoute(activeRecord.MapBiomes, capture.MapBiomes)) { activeRecord.MapSegmentBiomeIndices = CopyMapSegmentBiomeIndices(capture.SegmentBiomeIndices); flag = true; } if (flag) { Save(); } } } internal bool UpdateActiveMapBiomeDetails(int index, MapBiomeInfo details) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord == null || activeRecord.MapBiomes == null || index < 0 || index >= activeRecord.MapBiomes.Count) { return false; } MapBiomeInfo mapBiomeInfo = activeRecord.MapBiomes[index]; if (mapBiomeInfo.BiomeType != details.BiomeType) { return false; } bool flag = false; if (!string.IsNullOrWhiteSpace(details.Variant) && !string.Equals(mapBiomeInfo.Variant, details.Variant, StringComparison.Ordinal)) { mapBiomeInfo.Variant = details.Variant; flag = true; } if (details.OpenTomb.HasValue && mapBiomeInfo.OpenTomb != details.OpenTomb) { mapBiomeInfo.OpenTomb = details.OpenTomb; flag = true; } if (flag) { Save(); } return true; } internal void UpdateActiveTerrainRandomiser(bool enabled, int seed, string mapSettingsBrotliBase64) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null) { activeRecord.TerrainRandomiserEnabled = enabled; activeRecord.TerrainRandomiserSeed = (enabled ? seed : (-1)); activeRecord.TerrainRandomiserMapSettingsBrotliBase64 = (enabled ? mapSettingsBrotliBase64 : ""); Save(); } } internal void EnsureActivePLLMapSeed(int seed) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null && !activeRecord.PLLMapSeed.HasValue) { activeRecord.PLLMapSeed = seed; Save(); } } internal void EnsureActiveTfaApocalypseEnabled() { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null && !activeRecord.TFAApocalypseEnabled) { activeRecord.TFAApocalypseEnabled = true; Save(); } } internal void SetActiveTfaEnabled(bool enabled) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null && activeRecord.TrueFinalAscentEnabled != enabled) { activeRecord.TrueFinalAscentEnabled = enabled; if (enabled) { activeRecord.PLLMapSeed = null; activeRecord.TerrainRandomiserEnabled = false; activeRecord.TerrainRandomiserSeed = -1; activeRecord.TerrainRandomiserMapSettingsBrotliBase64 = ""; } Save(); } } internal void UpdateActiveTfaRoute(int seed, IReadOnlyList<MapBiomeInfo> route) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord == null || route.Count == 0) { return; } List<MapBiomeInfo> list = CopyMapBiomes(route); bool flag = activeRecord.TrueFinalAscentEnabled && activeRecord.TFAMapSeed == seed && SameTfaRoute(activeRecord.MapBiomes, list); if (!flag) { List<ClimbSegmentTiming>? segmentTimings = activeRecord.SegmentTimings; if (segmentTimings != null && segmentTimings.Count > 0) { activeRecord.SegmentTimings = new List<ClimbSegmentTiming>(); } } if (flag) { PreserveTfaTerminalEntries(activeRecord.MapBiomes, list); bool flag2 = false; for (int i = 0; i < Math.Min(activeRecord.MapBiomes.Count, list.Count); i++) { list[i].Variant = activeRecord.MapBiomes[i].Variant; list[i].OpenTomb = activeRecord.MapBiomes[i].OpenTomb; MergeTfaBiomeNames(activeRecord.MapBiomes[i], list[i]); PreserveTfaScale(activeRecord.MapBiomes[i], list[i]); flag2 |= !SameTfaBiomeNames(activeRecord.MapBiomes[i], list[i]); } if (!flag2 && SameMapBiomeRoute(activeRecord.MapBiomes, list)) { return; } } activeRecord.TrueFinalAscentEnabled = true; activeRecord.TFAMapSeed = seed; activeRecord.MapBiomes = list; activeRecord.MapSegmentBiomeIndices.Clear(); activeRecord.PLLMapSeed = null; activeRecord.TerrainRandomiserEnabled = false; activeRecord.TerrainRandomiserSeed = -1; activeRecord.TerrainRandomiserMapSettingsBrotliBase64 = ""; Save(); } internal void SaveSegmentTimings() { Save(flushToDisk: true); } internal void EnsureRouteTerminal(BiomeType biomeType) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord == null || activeRecord.MapBiomes.Exists((MapBiomeInfo biome) => biome.IsRouteTerminal && biome.BiomeType == biomeType)) { return; } MapBiomeInfo item = new MapBiomeInfo { BiomeType = biomeType, TitleKey = (((int)biomeType == 5) ? "PEAK" : "AREA_VOID"), IsRouteTerminal = true }; int num = activeRecord.MapBiomes.FindIndex((MapBiomeInfo biome) => biome.IsRouteTerminal && (int)biome.BiomeType == 17); if ((int)biomeType == 5 && num >= 0) { activeRecord.MapBiomes.Insert(num, item); for (int num2 = 0; num2 < activeRecord.MapSegmentBiomeIndices.Count; num2++) { if (activeRecord.MapSegmentBiomeIndices[num2] >= num) { activeRecord.MapSegmentBiomeIndices[num2]++; } } } else { activeRecord.MapBiomes.Add(item); } } internal RunIdConfirmationResult ConfirmActiveRunId(string runId, float? elapsedSeconds) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord == null || string.IsNullOrWhiteSpace(runId)) { return RunIdConfirmationResult.NoChange; } if (activeRecord.RunIdConfirmed) { if (!string.Equals(activeRecord.RunId, runId, StringComparison.OrdinalIgnoreCase)) { return RunIdConfirmationResult.Conflict; } return RunIdConfirmationResult.NoChange; } if (string.Equals(activeRecord.RunId, runId, StringComparison.OrdinalIgnoreCase)) { activeRecord.RunIdConfirmed = true; Save(flushToDisk: true); return RunIdConfirmationResult.Confirmed; } if (activeRecord.NetworkMode == "Multiplayer" && !string.IsNullOrWhiteSpace(activeRecord.PhotonRoomName)) { for (int num = _data.Records.Count - 1; num >= 0; num--) { ClimbRecord climbRecord = _data.Records[num]; if (IsRunResumeCandidate(climbRecord, activeRecord.PhotonRoomName, runId)) { activeRecord.RunId = runId; activeRecord.RunIdConfirmed = true; _data.Records.RemoveAt(num); RefreshResumedRecord(climbRecord, activeRecord, elapsedSeconds); _data.ActiveRecord = climbRecord; Save(flushToDisk: true); return RunIdConfirmationResult.Resumed; } } } activeRecord.RunId = runId; activeRecord.RunIdConfirmed = true; Save(flushToDisk: true); return RunIdConfirmationResult.Confirmed; } internal bool DeleteRecord(string runId) { if (string.IsNullOrWhiteSpace(runId)) { return false; } bool flag = _data.Records.RemoveAll((ClimbRecord record) => record.RunId == runId) > 0; if (_data.ActiveRecord?.RunId == runId) { _data.ActiveRecord = null; flag = true; } if (flag) { Save(flushToDisk: true); } return flag; } internal bool TryDeleteRecords(IReadOnlyCollection<string> runIds, out int deletedCount) { //IL_00b1: Expected O, but got Unknown deletedCount = 0; HashSet<string> candidates = new HashSet<string>(runIds, StringComparer.OrdinalIgnoreCase); List<ClimbRecord> list = _data.Records.FindAll((ClimbRecord record) => !candidates.Contains(record.RunId) || !ClimbOutcome.IsCompleted(record.Outcome) || string.Equals(record.RunId, _data.ActiveRecord?.RunId, StringComparison.OrdinalIgnoreCase)); int num = _data.Records.Count - list.Count; if (num == 0) { return true; } ClimbHistoryData climbHistoryData = new ClimbHistoryData { SchemaVersion = _data.SchemaVersion, Records = list, ActiveRecord = _data.ActiveRecord }; try { string json = JsonConvert.SerializeObject((object)climbHistoryData, (Formatting)0, JsonSettings); if (!_storage.Save(json, flushToDisk: true)) { return false; } } catch (JsonException ex) { JsonException arg = ex; Plugin.Logger.LogError((object)$"Failed to serialize climb history: {arg}"); return false; } _data.Records = list; deletedCount = num; return true; } internal void Complete(string outcome, float durationSeconds, float currentHeightMeters, string biome, int playerCount, string networkMode, string photonRoomName, string? tfaCurrentBiomeId = null) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null) { activeRecord.CurrentHeightMeters = Math.Max(activeRecord.CurrentHeightMeters, currentHeightMeters); UpdateBiome(activeRecord, biome, tfaCurrentBiomeId); activeRecord.PlayerCount = Math.Max(activeRecord.PlayerCount, Math.Max(1, playerCount)); UpdateNetworkState(activeRecord, networkMode, photonRoomName); FinalizeActive(outcome, durationSeconds); } } internal void CorrectCompletedRunTime(ClimbRecord record, string runId, float time, ClimbTimingStop stop) { if (_data.Records.Contains(record) && !(record.RunId != runId) && ClimbOutcome.IsCompleted(record.Outcome)) { record.DurationSeconds = time; stop.Correct(record, time); Save(flushToDisk: true); } } private static void UpdateBiome(ClimbRecord record, string biome, string? tfaCurrentBiomeId) { if (!string.IsNullOrWhiteSpace(biome)) { record.Biome = biome; if (tfaCurrentBiomeId != null) { record.TfaCurrentBiomeId = tfaCurrentBiomeId; } } } private static bool IsRunResumeCandidate(ClimbRecord? record, string photonRoomName, string runId) { if (record != null && record.NetworkMode == "Multiplayer" && string.Equals(record.PhotonRoomName, photonRoomName, StringComparison.Ordinal) && string.Equals(record.RunId, runId, StringComparison.OrdinalIgnoreCase)) { if (!(record.Outcome == "InProgress")) { return record.Outcome == "Abandoned"; } return true; } return false; } private static void RefreshResumedRecord(ClimbRecord record, ClimbRecord currentRecord, float? elapsedSeconds) { string runId = record.RunId; string startedAtUtc = record.StartedAtUtc; bool runIdConfirmed = record.RunIdConfirmed || currentRecord.RunIdConfirmed; float currentHeightMeters = record.CurrentHeightMeters; int playerCount = record.PlayerCount; IReadOnlyList<MapBiomeInfo> mapBiomes = record.MapBiomes; List<MapBiomeInfo> list = CopyMapBiomes(currentRecord.MapBiomes); List<int> list2 = CopyMapSegmentBiomeIndices(currentRecord.MapSegmentBiomeIndices); IReadOnlyList<int> mapSegmentBiomeIndices = record.MapSegmentBiomeIndices; IReadOnlyList<ClimbPlayerInfo> otherPlayers = record.OtherPlayers; bool flag = SameTfaRoute(mapBiomes, list); bool flag2 = record.TrueFinalAscentEnabled && currentRecord.TrueFinalAscentEnabled && !currentRecord.TFAMapSeed.HasValue && currentRecord.MapBiomes.Count == 0; if (record.TrueFinalAscentEnabled || currentRecord.TrueFinalAscentEnabled) { flag = record.TrueFinalAscentEnabled && currentRecord.TrueFinalAscentEnabled && record.TFAMapSeed.HasValue && record.TFAMapSeed == currentRecord.TFAMapSeed && SameTfaRoute(mapBiomes, list); if (flag) { PreserveTfaTerminalEntries(mapBiomes, list, list2); } } else if (flag) { PreserveTfaTerminalEntries(mapBiomes, list, list2); } bool flag3 = flag || flag2; bool flag4 = flag3; if (flag4) { string segmentTimingMapKey = currentRecord.SegmentTimingMapKey; bool flag5 = (((segmentTimingMapKey != null && segmentTimingMapKey.Length == 0) || segmentTimingMapKey == "pending") ? true : false); flag4 = flag5 || record.SegmentTimingMapKey.Length == 0 || record.SegmentTimingMapKey == currentRecord.SegmentTimingMapKey; } bool flag6 = flag4; record.SegmentTimings = (flag6 ? ClimbSegmentTimer.Merge(record.SegmentTimings, currentRecord.SegmentTimings) : ClimbSegmentTimer.Copy(currentRecord.SegmentTimings)); bool flag7 = !flag6; bool flag8 = flag7; if (!flag8) { string segmentTimingMapKey = currentRecord.SegmentTimingMapKey; bool flag5 = (((segmentTimingMapKey != null && segmentTimingMapKey.Length == 0) || segmentTimingMapKey == "pending") ? true : false); flag8 = !flag5; } if (flag8) { record.SegmentTimingMapKey = currentRecord.SegmentTimingMapKey; } record.RunId = runId; record.RunIdConfirmed = runIdConfirmed; record.StartedAtUtc = startedAtUtc; record.EndedAtUtc = ""; record.Outcome = "InProgress"; record.DurationSeconds = elapsedSeconds ?? record.DurationSeconds; record.CurrentHeightMeters = Math.Max(currentHeightMeters, currentRecord.CurrentHeightMeters); record.Ascent = currentRecord.Ascent; record.PlayerCount = Math.Max(playerCount, currentRecord.PlayerCount); record.IsCustomRun = currentRecord.IsCustomRun; record.IsMiniRun = currentRecord.IsMiniRun; record.Level = currentRecord.Level; if (!flag2) { record.Biome = currentRecord.Biome; record.TfaCurrentBiomeId = currentRecord.TfaCurrentBiomeId; } record.MapBiomes = (flag2 ? CopyMapBiomes(mapBiomes) : (flag ? MergeResumedMapBiomes(mapBiomes, list) : list)); record.MapSegmentBiomeIndices = ((flag && IsValidMapSegmentBiomeMapping(mapSegmentBiomeIndices, mapBiomes.Count) && (currentRecord.MapSegmentBiomeIndices.Count == 0 || mapSegmentBiomeIndices.Count == currentRecord.MapSegmentBiomeIndices.Count)) ? CopyMapSegmentBiomeIndices(mapSegmentBiomeIndices) : list2); record.TerrainRandomiserEnabled = false; record.TerrainRandomiserSeed = -1; record.TerrainRandomiserMapSettingsBrotliBase64 = ""; record.PLLMapSeed = currentRecord.PLLMapSeed; record.TrueFinalAscentEnabled = currentRecord.TrueFinalAscentEnabled; record.TFAApocalypseEnabled |= currentRecord.TFAApocalypseEnabled; if (!flag2) { record.TFAMapSeed = currentRecord.TFAMapSeed; } record.NetworkMode = currentRecord.NetworkMode; record.PhotonRoomName = currentRecord.PhotonRoomName; record.OtherPlayers = CopyPlayers(otherPlayers); MergePlayers(record.OtherPlayers, currentRecord.OtherPlayers); } private static void UpdateNetworkState(ClimbRecord record, string networkMode, string photonRoomName) { if (!string.IsNullOrWhiteSpace(networkMode)) { record.NetworkMode = networkMode; record.PhotonRoomName = ((networkMode == "Multiplayer") ? photonRoomName : ""); } } internal void RecoverInterrupted() { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord != null) { FinalizeActive("Abandoned", activeRecord.DurationSeconds); } } private void FinalizeActive(string outcome, float durationSeconds) { ClimbRecord activeRecord = _data.ActiveRecord; if (activeRecord == null) { return; } if (outcome == "Abandoned") { foreach (ClimbRecord record in _data.Records) { if (string.Equals(record.RunId, activeRecord.RunId, StringComparison.OrdinalIgnoreCase) && IsCompletedOutcome(record.Outcome)) { _data.ActiveRecord = null; Save(flushToDisk: true); return; } } } DateTimeOffset utcNow = DateTimeOffset.UtcNow; activeRecord.Outcome = outcome; ClimbSegmentTimer.Freeze(activeRecord.SegmentTimings, (outcome == "Summited") ? "RunEnded" : outcome); activeRecord.DurationSeconds = durationSeconds; activeRecord.EndedAtUtc = utcNow.ToString("O", CultureInfo.InvariantCulture); _data.Records.RemoveAll((ClimbRecord record) => string.Equals(record.RunId, activeRecord.RunId, StringComparison.OrdinalIgnoreCase)); _data.Records.Add(activeRecord); _data.ActiveRecord = null; Save(flushToDisk: true); } private static bool IsCompletedOutcome(string outcome) { if (!(outcome == "Summited")) { return outcome == "Failed"; } return true; } private static ClimbHistoryData Deserialize(string json) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) JObject val = JsonConvert.DeserializeObject<JObject>(json, JsonSettings) ?? throw new JsonSerializationException("Climb history must be a JSON object."); JToken val2 = default(JToken); if (!val.TryGetValue("Records", StringComparison.OrdinalIgnoreCase, ref val2) || !(val2 is JArray)) { throw new JsonSerializationException("Climb history must contain a Records array."); } ClimbHistoryData climbHistoryData = ((JToken)val).ToObject<ClimbHistoryData>(JsonSerializer.Create(JsonSettings)); if (climbHistoryData == null || climbHistoryData.Records == null || climbHistoryData.Records.Exists((ClimbRecord record) => record == null)) { throw new JsonSerializationException("Climb history contains invalid records."); } climbHistoryData.SchemaVersion = 16; NormalizeRecords(climbHistoryData.Records); if (climbHistoryData.ActiveRecord != null) { NormalizeRecord(climbHistoryData.ActiveRecord); } return climbHistoryData; } private void Save(bool flushToDisk = false) { //IL_0023: Expected O, but got Unknown try { string json = JsonConvert.SerializeObject((object)_data, (Formatting)0, JsonSettings); _storage.Save(json, flushToDisk); } catch (JsonException ex) { JsonException arg = ex; Plugin.Logger.LogError((object)$"Failed to serialize climb history: {arg}"); } } private static List<MapBiomeInfo> CopyMapBiomes(IReadOnlyList<MapBiomeInfo> mapBiomes) { List<MapBiomeInfo> list = new List<MapBiomeInfo>(mapBiomes.Count); foreach (MapBiomeInfo mapBiome in mapBiomes) { list.Add(CopyMapBiome(mapBiome)); } return list; } private static MapBiomeInfo CopyMapBiome(MapBiomeInfo biome) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return new MapBiomeInfo { BiomeType = biome.BiomeType, Variant = biome.Variant, OpenTomb = biome.OpenTomb, TitleKey = biome.TitleKey, TfaSegmentIndex = biome.TfaSegmentIndex, TfaChainIndex = biome.TfaChainIndex, TfaBiomeId = biome.TfaBiomeId, TfaBiomeNames = CopyTfaBiomeNames(biome.TfaBiomeNames), IsRouteTerminal = biome.IsRouteTerminal, TfaScalePercent = biome.TfaScalePercent, TfaScaleAxis = biome.TfaScaleAxis }; } private static List<MapBiomeInfo> MergeResumedMapBiomes(IReadOnlyList<MapBiomeInfo> existingMapBiomes, IReadOnlyList<MapBiomeInfo> currentMapBiomes) { List<MapBiomeInfo> list = CopyMapBiomes(currentMapBiomes); for (int i = 0; i < existingMapBiomes.Count; i++) { MapBiomeInfo mapBiomeInfo = existingMapBiomes[i]; MapBiomeInfo mapBiomeInfo2 = list[i]; if (!string.IsNullOrWhiteSpace(mapBiomeInfo.Variant)) { mapBiomeInfo2.Variant = mapBiomeInfo.Variant; } if (mapBiomeInfo.OpenTomb.HasValue) { mapBiomeInfo2.OpenTomb = mapBiomeInfo.OpenTomb; } MergeTfaBiomeNames(mapBiomeInfo, mapBiomeInfo2); PreserveTfaScale(mapBiomeInfo, mapBiomeInfo2); } return list; } private static bool SameMapBiomeRoute(IReadOnlyList<MapBiomeInfo> first, IReadOnlyList<MapBiomeInfo> second) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (first.Count != second.Count) { return false; } for (int i = 0; i < first.Count; i++) { if (first[i].BiomeType != second[i].BiomeType || first[i].TitleKey != second[i].TitleKey || first[i].IsRouteTerminal != second[i].IsRouteTerminal || first[i].TfaBiomeId != second[i].TfaBiomeId || first[i].TfaSegmentIndex != second[i].TfaSegmentIndex || first[i].TfaChainIndex != second[i].TfaChainIndex || first[i].TfaScalePercent != second[i].TfaScalePercent || first[i].TfaScaleAxis != second[i].TfaScaleAxis) { return false; } } return true; } private static bool SameTfaRoute(IReadOnlyList<MapBiomeInfo> first, IReadOnlyList<MapBiomeInfo> second) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) int num = first.Count; int num2 = second.Count; while (num > 0 && IsTfaTerminalEntry(first[num - 1])) { num--; } while (num2 > 0 && IsTfaTerminalEntry(second[num2 - 1])) { num2--; } if (num == 0 || num != num2) { return false; } for (int i = 0; i < num; i++) { if (first[i].BiomeType != second[i].BiomeType || first[i].TitleKey != second[i].TitleKey || first[i].TfaBiomeId != second[i].TfaBiomeId || first[i].TfaSegmentIndex != second[i].TfaSegmentIndex || first[i].TfaChainIndex != second[i].TfaChainIndex || ConflictingTfaScale(first[i], second[i])) { return false; } } return true; } private static bool ConflictingTfaScale(MapBiomeInfo first, MapBiomeInfo second) { if (first.TfaScalePercent.HasValue && first.TfaScaleAxis.HasValue && second.TfaScalePercent.HasValue && second.TfaScaleAxis.HasValue) { if (first.TfaScalePercent == second.TfaScalePercent) { return first.TfaScaleAxis != second.TfaScaleAxis; } return true; } return false; } private static void PreserveTfaScale(MapBiomeInfo existing, MapBiomeInfo current) { if (!current.TfaScalePercent.HasValue || !current.TfaScaleAxis.HasValue) { current.TfaScalePercent = existing.TfaScalePercent; current.TfaScaleAxis = existing.TfaScaleAxis; } } private static bool IsTfaTerminalEntry(MapBiomeInfo biome) { return biome.IsRouteTerminal; } private static void PreserveTfaTerminalEntries(IReadOnlyList<MapBiomeInfo> existing, List<MapBiomeInfo> current, List<int>? mapping = null) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 foreach (MapBiomeInfo biome in existing) { if (!IsTfaTerminalEntry(biome) || current.Exists((MapBiomeInfo mapBiomeInfo) => IsTfaTerminalEntry(mapBiomeInfo) && mapBiomeInfo.BiomeType == biome.BiomeType)) { continue; } MapBiomeInfo item = CopyMapBiome(biome); int num = current.FindIndex((MapBiomeInfo mapBiomeInfo) => IsTfaTerminalEntry(mapBiomeInfo) && (int)mapBiomeInfo.BiomeType == 17); if ((int)biome.BiomeType == 5 && num >= 0) { current.Insert(num, item); if (mapping == null) { continue; } for (int num2 = 0; num2 < mapping.Count; num2++) { if (mapping[num2] >= num) { mapping[num2]++; } } } else { current.Add(item); } } } private static Dictionary<string, string> CopyTfaBiomeNames(IReadOnlyDictionary<string, string>? names) { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); if (names == null) { return dictionary; } string[] array = new string[2] { "en", "cn" }; foreach (string key in array) { if (names.TryGetValue(key, out string value) && !string.IsNullOrWhiteSpace(value)) { dictionary.Add(key, value); } } return dictionary; } private static void MergeTfaBiomeNames(MapBiomeInfo existing, MapBiomeInfo current) { foreach (KeyValuePair<string, string> tfaBiomeName in existing.TfaBiomeNames) { current.TfaBiomeNames.TryAdd(tfaBiomeName.Key, tfaBiomeName.Value); } } private static bool SameTfaBiomeNames(MapBiomeInfo first, MapBiomeInfo second) { if (first.TfaBiomeNames.Count != second.TfaBiomeNames.Count) { return false; } foreach (KeyValuePair<string, string> tfaBiomeName in first.TfaBiomeNames) { if (!second.TfaBiomeNames.TryGetValue(tfaBiomeName.Key, out string value) || tfaBiomeName.Value != value) { return false; } } return true; } private static bool IsValidMapSegmentBiomeMapping(IReadOnlyList<int> mapping, int mapBiomeCount) { if (mapping.Count == 0 || mapBiomeCount == 0) { return false; } bool result = false; foreach (int item in mapping) { if (item < -1 || item >= mapBiomeCount) { return false; } if (item >= 0) { result = true; } } return result; } private static List<int> CopyMapSegmentBiomeIndices(IReadOnlyList<int> mapping) { return new List<int>(mapping); } private static List<ClimbPlayerInfo> CopyPlayers(IReadOnlyList<ClimbPlayerInfo> players) { List<ClimbPlayerInfo> list = new List<ClimbPlayerInfo>(players.Count); MergePlayers(list, players); foreach (ClimbPlayerInfo player in players) { if (PlayerIdentityCollector.TryNormalizeIdentity(player.Platform, player.PlatformUserId, out string platform, out string platformUserId) && PlayerIdentityCollector.IsLegacySteamIdentity(player) && PlayerIdentityCollector.IsValidSteamName(player.DisplayName)) { int index = list.FindIndex((ClimbPlayerInfo item) => PlayerIdentityCollector.MatchesIdentity(item, platform, platformUserId)); list[index].DisplayName = player.DisplayName; } } return list; } private static bool MergePlayers(List<ClimbPlayerInfo> activeRecordPlayers, IReadOnlyList<ClimbPlayerInfo> observedPlayers) { bool result = false; foreach (ClimbPlayerInfo observedPlayer in observedPlayers) { if (PlayerIdentityCollector.TryNormalizeIdentity(observedPlayer.Platform, observedPlayer.PlatformUserId, out string platform, out string platformUserId)) { string validDisplayName = PlayerIdentityCollector.GetValidDisplayName(observedPlayer); ClimbPlayerInfo climbPlayerInfo = activeRecordPlayers.Find((ClimbPlayerInfo player) => PlayerIdentityCollector.MatchesIdentity(player, platform, platformUserId)); if (climbPlayerInfo == null) { activeRecordPlayers.Add(new ClimbPlayerInfo { Platform = platform, PlatformUserId = platformUserId, DisplayName = validDisplayName }); result = true; } else if (validDisplayName.Length > 0 && !string.Equals(climbPlayerInfo.DisplayName, validDisplayName, StringComparison.Ordinal)) { climbPlayerInfo.DisplayName = validDisplayName; result = true; } } } return result; } private static void NormalizeRecords(List<ClimbRecord> records) { foreach (ClimbRecord record in records) { NormalizeRecord(record); } } private static void NormalizeRecord(ClimbRecord record) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Invalid comparison between Unknown and I4 //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Invalid comparison between Unknown and I4 ClimbRecord climbRecord = record; if (climbRecord.TfaCurrentBiomeId == null) { string text = (climbRecord.TfaCurrentBiomeId = ""); } climbRecord = record; if (climbRecord.SegmentTimingMapKey == null) { string text = (climbRecord.SegmentTimingMapKey = ""); } climbRecord = record; if (climbRecord.MapBiomes == null) { List<MapBiomeInfo> list = (climbRecord.MapBiomes = new List<MapBiomeInfo>()); } foreach (MapBiomeInfo mapBiome in record.MapBiomes) { MapBiomeInfo mapBiomeInfo = mapBiome; if (mapBiomeInfo.TitleKey == null) { string text = (mapBiomeInfo.TitleKey = ""); } mapBiomeInfo = mapBiome; if (mapBiomeInfo.TfaBiomeId == null) { string text = (mapBiomeInfo.TfaBiomeId = ""); } mapBiome.TfaBiomeNames = CopyTfaBiomeNames(mapBiome.TfaBiomeNames); bool flag = record.TrueFinalAscentEnabled && !mapBiome.TfaSegmentIndex.HasValue; bool flag2 = flag; if (flag2) { BiomeType biomeType = mapBiome.BiomeType; bool flag3 = (((int)biomeType == 5 || (int)biomeType == 17) ? true : false); flag2 = flag3; } if (flag2) { mapBiome.IsRouteTerminal = true; } } climbRecord = record; if (climbRecord.MapSegmentBiomeIndices == null) { List<int> list3 = (climbRecord.MapSegmentBiomeIndices = new List<int>()); } record.OtherPlayers = ((record.OtherPlayers != null) ? CopyPlayers(record.OtherPlayers) : new List<ClimbPlayerInfo>()); } } internal sealed class ClimbHistoryPage : UIPage, IHaveParentPage { internal UIPage ParentPage { get; set; } internal Action? OnOpened { get; set; } internal Action? OnClosing { get; set; } internal Func<UIPage>? ResolveBackTarget { get; set; } public override void OnPageEnter() { ((UIPage)this).OnPageEnter(); OnOpened?.Invoke(); } public override void OnPageExit() { OnClosing?.Invoke(); ((PageBase)this).OnPageExit(); } private void OnDisable() { OnClosing?.Invoke(); } public (UIPage, PageTransistion) GetParentPage() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (ResolveBackTarget != null) { return (ResolveBackTarget(), (PageTransistion)new SetActivePageTransistion()); } return (ParentPage, (PageTransistion)new SetActivePageTransistion()); } } internal sealed class ClimbHistoryDetailsPage : UIPage, IHaveParentPage { internal UIPage ParentPage { get; set; } internal Action? OnOpened { get; set; } internal Action? OnClosing { get; set; } public override void OnPageEnter() { ((UIPage)this).OnPageEnter(); OnOpened?.Invoke(); } public override void OnPageExit() { OnClosing?.Invoke(); ((PageBase)this).OnPageExit(); } public (UIPage, PageTransistion) GetParentPage() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown return (ParentPage, (PageTransistion)new SetActivePageTransistion()); } } internal sealed class ClimbHistoryModalPage : UIPage, IHaveParentPage { internal UIPage ParentPage { get; set; } internal Action? OnOpened { get; set; } internal Action? OnClosing { get; set; } public override void OnPageEnter() { ((UIPage)this).OnPageEnter(); OnOpened?.Invoke(); } public override void OnPageExit() { OnClosing?.Invoke(); ((PageBase)this).OnPageExit(); } private void OnDisable() { OnClosing?.Invoke(); } public (UIPage, PageTransistion) GetParentPage() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown return (ParentPage, (PageTransistion)new SetActivePageTransistion()); } } internal sealed class OverlayPageTransistion : PageTransistion { public override void Transistion(PageBase oldSubPage, PageBase newSubPage) { oldSubPage.OnPageExit(); ((Component)newSubPage).gameObject.SetActive(true); newSubPage.OnPageEnter(); newSubPage.OnPageEntered(); } } internal sealed class ClimbHistoryButton { private readonly Image? _panel; private readonly Image? _borderTop; private readonly Image? _borderBottom; internal GameObject GameObject { get; } internal RectTransform RectTransform { get; } internal Button Button { get; } internal TextMeshProUGUI Text { get; } private ClimbHistoryButton(GameObject gameObject) { GameObject = gameObject; RectTransform = gameObject.GetComponent<RectTransform>(); Button = gameObject.GetComponent<Button>(); Text = gameObject.GetComponentInChildren<TextMeshProUGUI>(true); Transform obj = gameObject.transform.Find("Panel"); _panel = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null); Transform val = gameObject.transform.Find("Border"); _borderTop = ((val != null) ? ((Component)val).GetComponent<Image>() : null); _borderBottom = (((Object)(object)val != (Object)null && val.GetSiblingIndex() + 1 < gameObject.transform.childCount) ? ((Component)gameObject.transform.GetChild(val.GetSiblingIndex() + 1)).GetComponent<Image>() : null); } internal static ClimbHistoryButton Create(GameObject template, string objectName, Transform parent) { GameObject val = Object.Instantiate<GameObject>(template, parent, false); ((Object)val).name = objectName; LocalizedText componentInChildren = val.GetComponentInChildren<LocalizedText>(true); if ((Object)(object)componentInChildren != (Object)null) { Object.DestroyImmediate((Object)(object)componentInChildren); } ClimbHistoryButton climbHistoryButton = new ClimbHistoryButton(val); ((UnityEventBase)climbHistoryButton.Button.onClick).RemoveAllListeners(); return climbHistoryButton; } internal void SetText(string value) { ((TMP_Text)Text).text = value; } internal void SetColor(Color color) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel != (Object)null) { ((Graphic)_panel).color = color; } float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(color, ref num, ref num2, ref num3); float num4 = ((num3 > 0.5f) ? Mathf.Clamp01(num3 - 0.2f) : Mathf.Clamp01(num3 + 0.2f)); Color color2 = Color.HSVToRGB(num, num2, num4); if ((Object)(object)_borderTop != (Object)null) { ((Graphic)_borderTop).color = color2; } if ((Object)(object)_borderBottom != (Object)null) { ((Graphic)_borderBottom).color = color2; } } } internal sealed class ClimbHistoryScrollSelection : MonoBehaviour, ISelectHandler, IEventSystemHandler { internal ScrollRect? Scroll { get; set; } internal RectTransform? Row { get; set; } public void OnSelect(BaseEventData eventData) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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_00ca: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Scroll == (Object)null || (Object)(object)Row == (Object)null || (Object)(object)Scroll.content == (Object)null || (Object)(object)Scroll.viewport == (Object)null) { return; } Rect rect = Scroll.viewport.rect; Bounds val = RectTransformUtility.CalculateRelativeRectTransformBounds((Transform)(object)Scroll.viewport, (Transform)(object)Row); float num; if (((Bounds)(ref val)).size.y > ((Rect)(ref rect)).height || ((Bounds)(ref val)).max.y > ((Rect)(ref rect)).yMax) { num = ((Rect)(ref rect)).yMax - ((Bounds)(ref val)).max.y; } else { if (!(((Bounds)(ref val)).min.y < ((Rect)(ref rect)).yMin)) { return; } num = ((Rect)(ref rect)).yMin - ((Bounds)(ref val)).min.y; } Scroll.StopMovement(); Vector2 anchoredPosition = Scroll.content.anchoredPosition; float num2 = anchoredPosition.y + num; Rect rect2 = Scroll.content.rect; anchoredPosition.y = Mathf.Clamp(num2, 0f, Mathf.Max(0f, ((Rect)(ref rect2)).height - ((Rect)(ref rect)).height)); Scroll.content.anchoredPosition = anchoredPosition; } } internal sealed class ClimbHistoryStorage { private enum ReadStatus { Missing, Valid, Invalid, Unavailable } private readonly string _path; private readonly Func<string, ClimbHistoryData> _deserialize; private bool _archiveMain; private bool _archiveBackup; private bool _readUnavailable; internal ClimbHistoryStorage(string path, Func<string, ClimbHistoryData> deserialize) { _path = path; _deserialize = deserialize; } internal ClimbHistoryData Load() { ClimbHistoryData data; string json; ReadStatus readStatus = Read(_path, out data, out json); if (readStatus == ReadStatus.Valid) { return data; } ClimbHistoryData data2; string json2; ReadStatus readStatus2 = Read(_path + ".bak", out data2, out json2); _archiveMain = readStatus == ReadStatus.Invalid; _archiveBackup = readStatus2 == ReadStatus.Invalid; _readUnavailable = readStatus == ReadStatus.Unavailable || readStatus2 == ReadStatus.Unavailable; if (_readUnavailable) { Plugin.Logger.LogError((object)"Climb history could not be read; existing files will not be overwritten this session."); return data2 ?? new ClimbHistoryData(); } if (readStatus2 == ReadStatus.Valid) { if (Save(json2, flushToDisk: true)) { Plugin.Logger.LogWarning((object)"Restored climb history from its backup."); } return data2; } if (_archiveMain || _archiveBackup) { try { ArchiveInvalidFiles(); Plugin.Logger.LogError((object)"No readable climb history or backup remains; preserved the invalid files and started a new history."); } catch (Exception ex) when (IsFileException(ex)) { Plugin.Logger.LogError((object)$"Failed to preserve invalid climb history files: {ex}"); } } return new ClimbHistoryData(); } internal bool Save(string json, bool flushToDisk) { if (_readUnavailable) { return false; } try { string directoryName = Path.GetDirectoryName(_path); if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } ArchiveInvalidFiles(); string text = _path + ".tmp"; byte[] bytes = Encoding.UTF8.GetBytes(json); using (FileStream fileStream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.None)) { fileStream.Write(bytes, 0, bytes.Length); fileStream.Flush(flushToDisk); } if (File.Exists(_path)) { File.Replace(text, _path, _path + ".bak"); } else { File.Move(text, _path); } return true; } catch (Exception ex) when (IsFileException(ex)) { Plugin.Logger.LogError((object)$"Failed to save climb history: {ex}"); return false; } } private ReadStatus Read(string path, out ClimbHistoryData? data, out string? json) { //IL_002c: Expected O, but got Unknown data = null; json = null; try { json = File.ReadAllText(path); data = _deserialize(json); return ReadStatus.Valid; } catch (FileNotFoundException) { return ReadStatus.Missing; } catch (DirectoryNotFoundException) { return ReadStatus.Missing; } catch (JsonException ex3) { JsonException ex4 = ex3; Plugin.Logger.LogWarning((object)("Invalid climb history file '" + path + "': " + ((Exception)(object)ex4).Message)); return ReadStatus.Invalid; } catch (Exception ex5) when (IsFileException(ex5)) { Plugin.Logger.LogError((object)$"Failed to read climb history file '{path}': {ex5}"); return ReadStatus.Unavailable; } } private void ArchiveInvalidFiles() { if (_archiveMain) { Archive(_path); _archiveMain = false; } if (_archiveBackup) { Archive(_path + ".bak"); _archiveBackup = false; } } private static void Archive(string path) { if (File.Exists(path)) { string text = path + ".load-failed." + DateTimeOffset.UtcNow.ToString("yyyyMMddTHHmmssfffZ", CultureInfo.InvariantCulture); string text2 = text; int num = 1; while (File.Exists(text2)) { text2 = text + "_" + num.ToString(CultureInfo.InvariantCulture); num++; } File.Move(path, text2); Plugin.Logger.LogWarning((object)("Preserved invalid climb history at '" + text2 + "'.")); } } private static bool IsFileException(Exception exception) { if (exception is IOException || exception is UnauthorizedAccessException || exception is NotSupportedException) { return true; } return false; } } internal static class ClimbHistoryUi { private sealed class RecordRowView { internal string RunId { get; } internal GameObject GameObject { get; } internal ClimbHistoryButton DeleteButton { get; } internal ClimbHistoryButton? DetailsButton { get; } internal RecordRowView(string runId, GameObject gameObject, ClimbHistoryButton deleteButton, ClimbHistoryButton? detailsButton) { RunId = runId; GameObject = gameObject; DeleteButton = deleteButton; DetailsButton = detailsButton; } } private enum RowAction { Back, Details, Delete, StatusFilter, MapFilter, ResetFilters, BulkDelete, ExitPlayerQuery, FellowPlayers, PlayerProfile } private sealed class BrowseState { internal int SceneHandle { get; init; } internal string? AnchorRunId { get; init; } internal float AnchorOffset { get; init; } internal List<string> RecordOrder { get; init; } = new List<string>(); internal string? FocusRunId { get; init; } internal RowAction FocusAction { get; init; } } private enum FellowSort { MostRecent, RecordCount } private enum FellowFocus { Search, Sort, Records, PlayerDetails, Scrollbar, Back } private sealed class FellowSummary { internal string Platform { get; init; } = ""; internal string UserId { get; init; } = ""; internal string DisplayPlatform { get; init; } = ""; internal string DisplayName { get; set; } = ""; internal DateTimeOffset NameDate { get; set; } = DateTimeOffset.MinValue; internal DateTimeOffset LatestDate { get; set; } = DateTimeOffset.MinValue; internal HashSet<string> Names { get; } = new HashSet<string>(StringComparer.Ordinal); internal int Count { get; set; } internal string Key => Platform + ":" + UserId; internal PlayerQuery ToQuery() { return new PlayerQuery { Platform = Platform, UserId = UserId, DisplayPlatform = DisplayPlatform, DisplayName = DisplayName }; } } private sealed class FellowRow { internal string Key { get; init; } = ""; internal RectTransform Rect { get; init; } internal ClimbHistoryButton Button { get; init; } internal ClimbHistoryButton DetailsButton { get; init; } } private sealed class FellowBrowseState { internal int SceneHandle { get; init; } internal string? Anchor { get; init; } internal float Offset { get; init; } internal List<string> Order { get; init; } = new List<string>(); internal string? FocusKey { get; init; } internal FellowFocus Focus { get; init; } } private enum MapSource { All, Vanilla, PLL, TFA, TerrainRandomiser } private enum ModalKind { None, ConfirmDelete, DeleteFailed } private sealed class PlayerQuery { internal string Platform { get; init; } = ""; internal string UserId { get; init; } = ""; internal string DisplayName { get; init; } = ""; internal string DisplayPlatform { get; init; } = ""; } private sealed class PlayerQueryContext { internal int SceneHandle { get; init; } internal string? Outcome { get; init; } internal MapSource Map { get; init; } internal BrowseState Browse { get; init; } internal bool FromFellowPlayers { get; init; } } [CompilerGenerated] private static class <>O { public static Action <0>__OnLanguageChanged; public static Action <1>__CaptureBrowseState; public static Func<UIPage> <2>__ResolveHistoryBackTarget; public static Action <3>__OnDetailsPageClosing; public static UnityAction <4>__CloseDetailsPage; public static UnityAction <5>__LoadSelectedMapSettings; public static UnityAction <6>__SaveSelectedMapSettings; public static Func<ClimbRecord, bool> <7>__MatchesFilters; public static Func<string, string> <8>__LocalizeBiomeTextId; public static Func<UIPage> <9>__ResolveFellowPlayersBackTarget; public static Func<string, string> <10>__OutcomeFilterName; public static Func<MapSource, string> <11>__MapFilterName; public static Action <12>__ResetFilters; public static Action <13>__OpenFellowPlayersPage; public static Action <14>__OpenDeleteConfirmation; public static Func<ClimbRecord, bool> <15>__CanBulkDelete; public static Action <16>__OnModalPageClosing; public static Action <17>__CloseModalPage; public static Action <18>__ConfirmBulkDelete; public static Func<UIPage> <19>__ResolvePlayerProfileBackTarget; public static Action <20>__OnPlayerProfileClosing; public static UnityAction<Scene, Scene> <21>__OnPlayerProfileSceneChanged; public static DispatchDelegate<PersonaStateChange_t> <22>__OnProfilePersonaChanged; public static DispatchDelegate<AvatarImageLoaded_t> <23>__OnProfileAvatarLoaded; public static DispatchDelegate<GameOverlayActivated_t> <24>__OnProfileOverlayChanged; public static Action <25>__ClosePlayerProfile; public static Action <26>__ExitPlayerQuery; } private static readonly List<RecordRowView> Rows = new List<RecordRowView>(); private static readonly List<GameObject> DetailRouteRows = new List<GameObject>(); private static readonly List<GameObject> DetailPlayerRows = new List<GameObject>(); private static readonly Dictionary<string, RecordRowView> RowsByRunId = new Dictionary<string, RecordRowView>(); private static bool _registered; private static bool _languageSubscribed; private static Transform? _pauseMenuParent; private static PauseMenuHandler? _pauseMenuHandler; private static PauseMenuMainPage? _parentPage; private static ClimbHistoryPage? _historyPage; private static ClimbHistoryDetailsPage? _detailsPage; private static CanvasGroup? _historyCanvasGroup; private static ClimbHistoryButton? _openButton; private static ClimbHistoryButton? _backButton; private static ClimbHistoryButton? _detailsCloseButton; private static ClimbHistoryButton? _detailsLoadButton; private static ClimbHistoryButton? _detailsSaveButton; private static RectTransform? _rowsContent; private static ScrollRect? _rowsScrollRect; private static RectTransform? _rowsDivider; private static RectTransform? _detailsRouteContent; private static ScrollRect? _detailsRouteScrollRect; private static RectTransform? _detailsPlayersContent; private static ScrollRect? _detailsPlayersScrollRect; private static TextMeshProUGUI? _titleText; private static TextMeshProUGUI? _summaryText; private static TextMeshProUGUI? _emptyText; private static TextMeshProUGUI? _detailsTitleText; private static TextMeshProUGUI? _detailsMetadataText; private static TextMeshProUGUI? _detailsRouteTitleText; private static TextMeshProUGUI? _detailsPlayersTitleText; private static TextMeshProUGUI? _detailsRouteEmptyText; private static TextMeshProUGUI? _detailsPlayersEmptyText; private static ClimbRecord? _selectedDetailsRecord; private static string? _pendingFocusRunId; private static BrowseState? _browseState; private static int _rowsSceneHandle = -1; private static TMP_FontAsset? _vanillaFont; private static GameObject? _menuButtonTemplate; private const float RowHeight = 132f; private const float RowActionRightPadding = 24f; private const float RowActionSpacing = 8f; private const float RowActionHeight = 44f; private const float RowDetailsActionWidth = 86f; private const float RowDeleteActionWidth = 92f; private const float RowActionFontSize = 20f; private const float PauseMenuButtonWidth = 277f; private static readonly IReadOnlyDictionary<BiomeType, string[]> BiomeTextIds = new Dictionary<BiomeType, string[]> { [(BiomeType)0] = new string[1] { "SHORE" }, [(BiomeType)1] = new string[1] { "TROPICS" }, [(BiomeType)2] = new string[1] { "ALPINE" }, [(BiomeType)3] = new string[2] { "CALDERA", "THE KILN" }, [(BiomeType)5] = new string[1] { "PEAK" }, [(BiomeType)6] = new string[1] { "MESA" }, [(BiomeType)7] = new string[1] { "ROOTS" }, [(BiomeType)8] = new string[2] { "GLOOM", "THE CITADEL" }, [(BiomeType)17] = new string[1] { "AREA_VOID" } }; private static readonly HashSet<BiomeType> HasVariants = new HashSet<BiomeType> { (BiomeType)0, (BiomeType)1, (BiomeType)2, (BiomeType)6, (BiomeType)7 }; private static readonly IReadOnlyDictionary<BiomeType, IReadOnlyDictionary<string, string>> SimplifiedChineseVariantNames = new Dictionary<BiomeType, IReadOnlyDictionary<string, string>> { [(BiomeType)0] = new Dictionary<string, string> { ["Default"] = "默认", ["SnakeBeach"] = "蛇岩", ["RedBeach"] = "赤沙", ["BlueBeach"] = "蓝沙", ["JellyHell"] = "水母地狱", ["BlackSand"] = "黑沙" }, [(BiomeType)1] = new Dictionary<string, string> { ["Default"] = "默认", ["Lava"] = "熔岩管", ["Pillars"] = "巨柱", ["Thorny"] = "巨棘藤", ["Bombs"] = "爆菇", ["Ivy"] = "紫毒藤", ["SkyJungle"] = "浮岛" }, [(BiomeType)7] = new Dictionary<string, string> { ["Default"] = "默认", ["CaveMania"] = "洞窟丛生", ["DeepWater"] = "赤水孢泽", ["BombBeetle"] = "爆菇甲虫", ["DeepWoods"] = "幽深密林", ["Clearcut"] = "皆伐菌原" }, [(BiomeType)2] = new Dictionary<string, string> { ["Default"] = "默认", ["Lava"] = "熔岩管", ["Spiky"] = "冰刺", ["GeyserHell"] = "间歇泉地狱" }, [(BiomeType)6] = new Dictionary<string, string> { ["Default"] = "默认", ["ScorpionsHell"] = "毒蝎地狱", ["CactusHell"] = "峭壁仙人掌地狱", ["CactusForest"] = "高原仙人掌林", ["DynamiteHell"] = "炸药地狱", ["TornadoHell"] = "龙卷风地狱", ["TumblerHell"] = "风滚草地狱" } }; private static ClimbHistoryPage? _fellowPlayersPage; private static TextMeshProUGUI? _fellowTitle; private static TextMeshProUGUI? _fellowSummaryText; private static TextMeshProUGUI? _fellowEmpty; private static TMP_InputField? _fellowSearchField; private static TMP_Dropdown? _fellowSortDropdown; private static ClimbHistoryButton? _fellowBackButton; private static RectTransform? _fellowPanel; private static RectTransform? _fellowContent; private static ScrollRect? _fellowScroll; private static readonly List<FellowRow> FellowRows = new List<FellowRow>(); private static readonly List<FellowSummary> FellowSummaries = new List<FellowSummary>(); private static string _fellowSearch = ""; private static FellowSort _fellowSort; private static FellowBrowseState? _fellowBrowse; private static BrowseState? _fellowHistoryBrowse; private static int _fellowHistoryScene = -1; private static int _fellowRowsScene = -1; private static int _fellowEditEndedFrame = -1; private static bool _fellowFocusSearch; private static readonly string?[] OutcomeOptions = new string[5] { null, "InProgress", "Summited", "Failed", "Abandoned" }; private static readonly MapSource[] MapOptions = new MapSource[5] { MapSource.All, MapSource.Vanilla, MapSource.PLL, MapSource.TFA, MapSource.TerrainRandomiser }; private static readonly List<ClimbHistoryButton> ModalButtons = new List<ClimbHistoryButton>(); private static string? _outcomeFilter; private static MapSource _mapFilter; private static TMP_Dropdown? _statusFilterDropdown; private static TMP_Dropdown? _mapFilterDropdown; private static ClimbHistoryButton? _resetFiltersButton; private static ClimbHistoryButton? _bulkDeleteButton; private static ClimbHistoryButton? _fellowPlayersButton; private static RectTransform? _filterPanel; private static ClimbHistoryModalPage? _modalPage; private static RectTransform? _modalPanel; private static TextMeshProUGUI? _modalTitle; private static TextMeshProUGUI? _modalBody; private static ScrollRect? _modalBodyScroll; private static ModalKind _modalKind; private static int _modalInitialFocusIndex; private static RowAction? _pendingToolbarFocus; private static bool _resetBrowseOnRefresh; private static bool _skipNextSnapshot; private static string[]? _pendingDeleteRunIds; private static string? _pendingDeleteOutcome; private static MapSource _pendingDeleteMap; private static PlayerQuery? _pendingDeletePlayer; private static ClimbHistoryPage? _playerProfilePage; private static RectTransform? _playerProfilePanel; private static TextMeshProUGUI? _playerProfileTitle; private static TextMeshProUGUI? _playerProfileBody; private static TextMeshProUGUI? _playerProfileAvatarText; private static RectTransform? _playerProfileAvatarRect; private static RawImage? _playerProfileAvatar; private static ScrollRect? _playerProfileScroll; private static ClimbHistoryButton? _playerProfileCloseButton; private static ClimbHistoryButton? _playerProfileSteamButton; private static ClimbHistoryButton? _playerProfileFriendButton; private static PlayerQuery? _profilePlayer; private static readonly List<string> ProfileRecordedNames = new List<string>(); private static CanvasGroup? _profileSourceGroup; private static bool _profileSourceInteractable; private static bool _profileSourceRaycasts; private static CSteamID? _profileSteamId; private static string _profileSteamName = ""; private static EFriendRelationship _profileRelationship; private static int _profileAvatarHandle; private static Texture2D? _profileAvatarTexture; private static Callback<PersonaStateChange_t>? _profilePersonaCallback; private static Callback<AvatarImageLoaded_t>? _profileAvatarCallback; private static Callback<GameOverlayActivated_t>? _profileOverlayCallback; private static bool _profileSteamOverlayActive; private static int _profileSteamOverlayClosedFrame = -1; private static readonly List<ClimbHistoryButton> DetailPlayerButtons = new List<ClimbHistoryButton>(); private static PlayerQuery? _playerFilter; private static PlayerQueryContext? _playerQueryContext; private static BrowseState? _playerQueryReturnBrowse; private static bool _restorePlayerQueryBrowse; private static RectTransform? _playerQueryBanner; private static ClimbHistoryButton? _exitPlayerQueryButton; private static ClimbHistoryButton? _queryPlayerProfileButton; private static bool IsPlayerProfileOpen => _profilePlayer != null; private static bool SteamProfileAvailable { get { if ((Object)(object)SteamManager.Instance != (Object)null && SteamManager.Initialized && SteamAPI.IsSteamRunning()) { return SteamUser.BLoggedOn(); } return false; } } internal static void Register() { Plugin.Logger.LogDebug((object)($"Registering climb history UI. registered={_registered}, " + $"languageSubscribed={_languageSubscribed}, frame={Time.frameCount}.")); if (!_registered) { _registered = true; Plugin.Logger.LogDebug((object)"Climb history pause menu builder registered."); } if (!_languageSubscribed) { LocalizedText.OnLangugageChanged = (Action)Delegate.Combine(LocalizedText.OnLangugageChanged, new Action(OnLanguageChanged)); _languageSubscribed = true; } } internal static void Dispose() { ResetPlayerProfileUi(); if (_languageSubscribed) { LocalizedText.OnLangugageChanged = (Action)Delegate.Remove(LocalizedText.OnLangugageChanged, new Action(OnLanguageChanged)); _languageSubscribed = false; } } internal static void BuildPauseMenu(PauseMenuMainPage parentPage) { Transform transform = ((Component)parentPage).transform; if ((Object)(object)_pauseMenuParent == (Object)null || (Object)(object)_pauseMenuParent != (Object)(object)transform) { ResetBuiltUi(); } _pauseMenuParent = transform; Plugin.Logger.LogDebug((object)("Building climb history pause menu. parent=" + DescribeTransform(transform) + ", " + $"existingPage={DescribeObject((Object?)(object)_historyPage)}, frame={Time.frameCount}.")); _pauseMenuHandler = ((Component)transform).GetComponentInParent<PauseMenuHandler>(); _parentPage = parentPage; Plugin.Logger.LogDebug((object)("Resolved pause menu references. handler=" + DescribeObject((Object?)(object)_pauseMenuHandler) + ", parentPage=" + DescribeObject((Object?)(object)_parentPage) + ".")); if ((Object)(object)_pauseMenuHandler == (Object)null || (Object)(object)_parentPage == (Object)null) { Plugin.Logger.LogError((object)"Failed to create climb history page: pause menu references missing."); return; } BuildOpenButton(); Plugin.Logger.LogDebug((object)("Finished building climb history pause menu entry. openButton=" + DescribeObject((Object?)(object)_openButton?.GameObject) + ", deferredPage=" + DescribeObject((Object?)(object)_historyPage) + ".")); } private static bool EnsureHistoryPage() { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_historyPage != (Object)null && Object.op_Implicit((Object)(object)_historyPage)) { Plugin.Logger.LogDebug((object)"Skipped climb history page build because it already exists."); return true; } if ((Object)(object)_parentPage == (Object)null || (Object)(object)_pauseMenuHandler == (Object)null) { Plugin.Logger.LogError((object)"Failed to create climb history page: pause menu references missing."); return false; } EnsureFonts(); Plugin.Logger.LogDebug((object)("Creating deferred climb history child page. parentPage=" + DescribeObject((Object?)(object)_parentPage) + ", " + $"frame={Time.frameCount}.")); GameObject val = new GameObject("ClimbInfoTracker_HistoryPage", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)_parentPage).transform.parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; _historyPage = val.AddComponent<ClimbHistoryPage>(); _historyPage.ParentPage = (UIPage)(object)_parentPage; _historyCanvasGroup = val.AddComponent<CanvasGroup>(); Plugin.Logger.LogDebug((object)("Created climb history child page. " + DescribePageState() + ", " + $"frame={Time.frameCount}.")); CreatePageBackground(((Component)_historyPage).transform, new Color(0f, 0f, 0f, 0.87f)); _historyPage.OnOpened = delegate { Plugin.Logger.LogDebug((object)("Climb history page OnOpen fired. " + DescribePageState() + ", " + $"frame={Time.frameCount}.")); RefreshPage(); }; _historyPage.OnClosing = CaptureBrowseState; _historyPage.ResolveBackTarget = ResolveHistoryBackTarget; BuildHeader(); BuildContent(); BuildBackButton(); BuildDetailsPage(); BuildModalPage(); BuildFellowPlayersPage(); BuildPlayerProfilePage(); Plugin.Logger.LogDebug((object)("Built climb history controls. title=" + DescribeObject((Object?)(object)_titleText) + ", rowsContent=" + DescribeRect(_rowsContent) + ", backButton=" + DescribeObject((Object?)(object)_backButton?.GameObject) + ".")); ((Component)_historyPage).gameObject.SetActive(false); Plugin.Logger.LogDebug((object)("Finished building climb history page and deactivated it. " + DescribePageState() + ".")); return true; } private static void BuildHeader() { //IL_002e: 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_0058: 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_0082: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_historyPage == (Object)null)) { RectTransform val = CreateRectObject("Header", ((Component)_historyPage).transform); val.anchorMin = new Vector2(0.5f, 1f); val.anchorMax = new Vector2(0.5f, 1f); val.anchoredPosition = new Vector2(0f, -32f); val.pivot = new Vector2(0.5f, 1f); val.sizeDelta = new Vector2(900f, 120f); _titleText = CreateText((Transform)(object)val, "Title", 54f, (TextAlignmentOptions)514); StretchToParent(((TMP_Text)_titleText).rectTransform); ((TMP_Text)_titleText).enableAutoSizing = true; ((TMP_Text)_titleText).fontSizeMin = 30f; ((TMP_Text)_titleText).fontSizeMax = 54f; } } private static void BuildContent() { //IL_002e: 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_0058: 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_0082: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: 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) if (!((Object)(object)_historyPage == (Object)null)) { RectTransform val = CreateRectObject("Content", ((Component)_historyPage).transform); val.pivot = new Vector2(0.5f, 1f); val.anchorMin = new Vector2(0.5f, 1f); val.anchorMax = new Vector2(0.5f, 1f); val.anchoredPosition = new Vector2(0f, -140f); val.sizeDelta = new Vector2(1420f, 840f); RectTransform val2 = CreateRectObject("HistoryPanel", (Transform)(object)val); StretchToParent(val2); ((Graphic)((Component)val2).gameObject.AddComponent<Image>()).color = new Color(0.11f, 0.09f, 0.08f, 0.76f); _summaryText = CreateText((Transform)(object)val2, "Summary", 32f, (TextAlignmentOptions)514); ((TMP_Text)_summaryText).enableAutoSizing = true; ((TMP_Text)_summaryText).fontSizeMin = 20f; ((TMP_Text)_summaryText).fontSizeMax = 32f; ConfigureTopText(((TMP_Text)_summaryText).rectTransform, 90f, -24f, -90f, -70f); _filterPanel = val2; RectTransform val3 = (_rowsDivider = CreateRectObject("Divider", (Transform)(object)val2)); val3.anchorMin = new Vector2(0f, 1f); val3.anchorMax = new Vector2(1f, 1f); val3.pivot = new Vector2(0.5f, 1f); val3.anchoredPosition = new Vector2(0f, -132f); val3.sizeDelta = new Vector2(-120f, 2f); ((Graphic)((Component)val3).gameObject.AddComponent<Image>()).color = new Color(0.78f, 0.63f, 0.35f, 0.9f); ScrollRect val4 = (_rowsScrollRect = CreateScrollableContent((Transform)(object)val2, out _rowsContent)); RectTransform component = ((Component)val4).GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = new Vector2(56f, 84f); component.offsetMax = new Vector2(-80f, -156f); val4.verticalScrollbar = CreateRowsScrollbar(((Component)val2).transform); val4.verticalScrollbarVisibility = (ScrollbarVisibility)0; _emptyText = CreateText((Transform)(object)val2, "Empty", 30f, (TextAlignmentOptions)514); ((Graphic)_emptyText).color = new Color(0.94f, 0.9f, 0.82f, 0.95f); ((TMP_Text)_emptyText).rectTransform.anchorMin = Vector2.zero; ((TMP_Text)_emptyText).rectTransform.anchorMax = Vector2.one; ((TMP_Text)_emptyText).rectTransform.offsetMin = new Vector2(120f, 160f); ((TMP_Text)_emptyText).rectTransform.offsetMax = new Vector2(-120f, -170f); } } private static void CreatePageBackground(Transform parent, Color color) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) RectTransform val = CreateRectObject("Background", parent); StretchToParent(val); ((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = color; ((Transform)val).SetAsFirstSibling(); } private static RectTransform CreateRectObject(string objectName, Transform parent) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown GameObject val = new GameObject(objectName, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); return val.GetComponent<RectTransform>(); } private static ScrollRect CreateScrollableContent(Transform parent, out RectTransform content) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ClimbHistoryRows", new Type[3] { typeof(RectTransform), typeof(RectMask2D), typeof(ScrollRect) }); val.transform.SetParent(parent, false); ScrollRect component = val.GetComponent<ScrollRect>(); component.scrollSensitivity = 50f; component.elasticity = 0f; component.vertical = true; component.horizontal = false; component.movementType = (MovementType)2; GameObject val2 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); val2.transform.SetParent(val.transform, false); content = val2.GetComponent<RectTransform>(); content.pivot = new Vector2(0.5f, 1f); StretchToParent(content); VerticalLayoutGroup component2 = val2.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; ContentSizeFitter component3 = val2.GetComponent<ContentSizeFitter>(); component3.verticalFit = (FitMode)2; component.content = content; return component; } private static Scrollbar CreateRowsScrollbar(Transform parent) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ClimbHistoryScrollbar", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Scrollbar) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 0f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 0.5f); component.offsetMin = new Vector2(-72f, 84f); component.offsetMax = new Vector2(-56f, -156f); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0.04f, 0.035f, 0.03f, 0.55f); GameObject val2 = new GameObject("Sliding Area", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = new Vector2(2f, 2f); component3.offsetMax = new Vector2(-2f, -2f); GameObject val3 = new GameObject("Handle", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val2.transform, false); RectTransform component4 = val3.GetComponent<RectTransform>(); component4.anchorMin = Vector2.zero; component4.anchorMax = Vector2.one; component4.offsetMin = Vector2.zero; component4.offsetMax = Vector2.zero; Image component5 = val3.GetComponent<Image>(); ((Graphic)component5).color = new Color(0.78f, 0.63f, 0.35f, 0.95f); Scrollbar component6 = val.GetComponent<Scrollbar>(); component6.direction = (Direction)2; ((Selectable)component6).targetGraphic = (Graphic)(object)component5; component6.handleRect = component4; return component6; } private static void BuildBackButton() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown if (!((Object)(object)_historyPage == (Object)null) && !((Object)(object)_pauseMenuHandler == (Object)null) && !((Object)(object)_parentPage == (Object)null)) { PauseMenuHandler pauseMenuHandler = _pauseMenuHandler; _backButton = CreateMenuButton("Back", ((Component)_historyPage).transform); _backButton.SetText(GetGameLocalizedText("BACK")); _backButton.SetColor(new Color(0.5189f, 0.1297f, 0.1718f)); _backButton.RectTransform.anchorMin = new Vector2(0.5f, 0f); _backButton.RectTransform.anchorMax = new Vector2(0.5f, 0f); _backButton.RectTransform.pivot = new Vector2(0.5f, 0f); _backButton.RectTransform.anchoredPosition = new Vector2(0f, 36f); _backButton.RectTransform.sizeDelta = new Vector2(220f, _backButton.RectTransform.sizeDelta.y); ((UnityEvent)_backButton.Button.onClick).AddListener((UnityAction)delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ((UIPageHandler)pauseMenuHandler).TransistionToPage(ResolveHistoryBackTarget(), (PageTransistion)new SetActivePageTransistion()); }); } } private static void BuildDetailsPage() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05cf: Unknown result type (might be due to invalid IL or missing references) //IL_05e5: Unknown result type (might be due to invalid IL or missing references) //IL_060f: Unknown result type (might be due to invalid IL or missing references) //IL_0633: Unknown result type (might be due to invalid IL or missing references) //IL_0649: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_0675: Unknown result type (might be due to invalid IL or missing references) //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_0725: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_078f: Unknown result type (might be due to invalid IL or missing references) //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_075d: Unknown result type (might be due to invalid IL or missing references) //IL_0763: Expected O, but got Unknown //IL_07c2: Unknown result type (might be due to invalid IL or missing references) //IL_07c7: Unknown result type (might be due to invalid IL or missing references) //IL_07cd: Expected O, but got Unknown if (!((Object)(object)_historyPage == (Object)null) && !((Object)(object)_pauseMenuHandler == (Object)null)) { GameObject val = new GameObject("ClimbInfoTracker_DetailsPage", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)_historyPage).transform.parent, false); RectTransform component = val.GetComponent<RectTransform>(); StretchToParent(component); _detailsPage = val.AddComponent<ClimbHistoryDetailsPage>(); _detailsPage.ParentPage = (UIPage)(object)_historyPage; _detailsPage.OnOpened = delegate { RebuildDetailsLayout(); ConfigureDetailsPlayerNavigation(); FocusDetailsCloseButton(); }; _detailsPage.OnClosing = OnDetailsPageClosing; RectTransform val2 = CreateRectObject("Backdrop", ((Component)_detailsPage).transform); StretchToParent(val2); Image val3 = ((Component)val2).gameObject.AddComponent<Image>(); ((Graphic)val3).color = new Color(0f, 0f, 0f, 0.62f); ((Graphic)val3).raycastTarget = true; RectTransform val4 = CreateRectObject("DetailsPanel", ((Component)_detailsPage).transform); val4.anchorMin = new Vector2(0.14f, 0.14f); val4.anchorMax = new Vector2(0.86f, 0.86f); val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; Image val5 = ((Component)val4).gameObject.AddComponent<Image>(); ((Graphic)val5).color = new Color(0.11f, 0.09f, 0.08f, 0.97f); _detailsTitleText = CreateText((Transform)(object)val4, "DetailsTitle", 38f, (TextAlignmentOptions)514); ((TMP_Text)_detailsTitleText).enableAutoSizing = true; ((TMP_Text)_detailsTitleText).fontSizeMin = 24f; ((TMP_Text)_detailsTitleText).fontSizeMax = 38f; ((TMP_Text)_detailsTitleText).rectTransform.anchorMin = new Vector2(0.18f, 0.89f); ((TMP_Text)_detailsTitleText).rectTransform.anchorMax = new Vector2(0.82f, 0.98f); ((TMP_Text)_detailsTitleText).rectTransform.offsetMin = Vector2.zero; ((TMP_Text)_detailsTitleText).rectTransform.offsetMax = Vector2.zero; _detailsCloseButton = CreateMenuButton(ClimbLocalization.Get(ClimbText.Close), (Transform)(object)val4); _detailsCloseButton.SetColor(new Color(0.5189f, 0.1297f, 0.1718f)); _detailsCloseButton.RectTransform.anchorMin = new Vector2(1f, 1f); _detailsCloseButton.RectTransform.anchorMax = new Vector2(1f, 1f); _detailsCloseButton.RectTransform.pivot = new Vector2(1f, 1f); _detailsCloseButton.RectTransform.anchoredPosition = new Vector2(-20f, -16f); _detailsCloseButton.RectTransform.sizeDelta = new Vector2(112f, 46f); ConfigureRowActionButtonText(_detailsCloseButton); ButtonClickedEvent onClick = _detailsCloseButton.Button.onClick; object obj = <>O.<4>__CloseDetailsPage; if (obj == null) { UnityAction val6 = CloseDetailsPage; <>O.<4>__CloseDetailsPage = val6; obj = (object)val6; } ((UnityEvent)onClick).AddListener((UnityAction)obj); _detailsMetadataText = CreateText((Transform)(object)val4, "DetailsMetadata", 28f, (TextAlignmentOptions)257); ((TMP_Text)_detailsMetadataText).richText = true; ((TMP_Text)_detailsMetadataText).textWrappingMode = (TextWrappingModes)1; ((TMP_Text)_detailsMetadataText).overflowMode = (TextOverflowModes)0; ((TMP_Text)_detailsMetadataText).lineSpacing = 4f; ((TMP_Text)_detailsMetadataText).rectTransform.anchorMin = new Vector2(0f, 0.68f); ((TMP_Text)_detailsMetadataText).rectTransform.anchorMax = new Vector2(1f, 0.86f); ((TMP_Text)_detailsMetadataText).rectTransform.offsetMin = new Vector2(36f, 0f); ((TMP_Text)_detailsMetadataText).rectTransform.offsetMax = new Vector2(-36f, 0f); RectTransform val7 = CreateRectObject("DetailsDivider", (Transform)(object)val4); val7.anchorMin = new Vector2(0f, 0.66f); val7.anchorMax = new Vector2(1f, 0.66f); val7.pivot = new Vector2(0.5f, 0.5f); val7.offsetMin = new Vector2(36f, -1f); val7.offsetMax = new Vector2(-36f, 1f); ((Graphic)((Component)val7).gameObject.AddComponent<Image>()).color = new Color(0.78f, 0.63f, 0.35f, 0.9f); RectTransform val8 = CreateRectObject("MapRouteColumn", (Transform)(object)val4); val8.anchorMin = new Vector2(0f, 0.13f); val8.anchorMax = new Vector2(0.62f, 0.64f); val8.offsetMin = new Vector2(36f, 0f); val8.offsetMax = new Vector2(-18f, 0f); _detailsRouteTitleText = CreateDetailsColumnTitle((Transform)(object)val8, "MapRouteTitle"); _detailsRouteScrollRect = CreateDetailsListScroll((Transform)(object)val8, "DetailsRoute", out _detailsRouteContent); _detailsRouteEmptyText = CreateText((Transform)(object)val8, "MapRouteEmpty", 24f, (TextAlignmentOptions)514); ((Graphic)_detailsRouteEmptyText).color = new Color(0.88f, 0.84f, 0.76f, 0.92f); ConfigureDetailsColumnBody(((TMP_Text)_detailsRouteEmptyText).rectTransform); RectTransform val9 = CreateRectObject("DetailsColumnDivider", (Transform)(object)val4); val9.anchorMin = new Vector2(0.62f, 0.13f); val9.anchorMax = new Vector2(0.62f, 0.64f); val9.offsetMin = new Vector2(-1f, 0f); val9.offsetMax = new Vector2(1f, 0f); ((Graphic)((Component)val9).gameObject.AddComponent<Image>()).color = new Color(0.78f, 0.63f, 0.35f, 0.65f); RectTransform val10 = CreateRectObject("OtherPlayersColumn", (Transform)(object)val4); val10.anchorMin = new Vector2(0.62f, 0.13f); val10.anchorMax = new Vector2(1f, 0.64f); val10.offsetMin = new Vector2(18f, 0f); val10.offsetMax = new Vector2(-36f, 0f); _detailsPlayersTitleText = CreateDetailsColumnTitle((Transform)(object)val10, "OtherPlayersTitle"); _detailsPlayersScrollRect = CreateDetailsListScroll((Transform)(object)val10, "DetailsPlayers", out _detailsPlayersContent); _detailsPlayersEmptyText = CreateText((Transform)(object)val10, "OtherPlayersEmpty", 22f, (TextAlignmentOptions)514); ((Graphic)_detailsPlayersEmptyText).color = new Color(0.88f, 0.84f, 0.76f, 0.92f); ((TMP_Text)_detailsPlayersEmptyText).textWrappingMode = (TextWrappingModes)1; ConfigureDetailsColumnBody(((TMP_Text)_detailsPlayersEmptyText).rectTransform); _detailsLoadButton = CreateMenuButton(ClimbLocalization.Get(ClimbText.LoadMapSettings), (Transform)(object)val4);