using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Steamworks; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PeakMapBrowser { internal sealed class MapsResponse { public bool success; public List data; public PaginationInfo pagination; public string error_code; public string error; public string error_message; } internal sealed class ModVersionsResponse { public bool success; public List data; public string error_code; public string error; public string error_message; } internal sealed class AuthResponse { public bool success; public string access_token; public string refresh_token; public long expires_at; public int expires_in; public AccountUser user; public string error; public string error_message; } internal sealed class AccountUser { public string id; public string email; public string nickname; } internal sealed class LikeResponse { public bool success; public bool liked; public int likes; public string error; public string error_message; } internal sealed class BasicResponse { public bool success; public string message; public string error; public string error_message; } internal sealed class PeakMapSession { public string access_token; public string refresh_token; public long expires_at; public string user_id; public string email; public string nickname; public string guest_id; public bool HasUser => !string.IsNullOrEmpty(access_token) && !string.IsNullOrEmpty(refresh_token); public bool HasRefreshToken => !string.IsNullOrEmpty(refresh_token); public string DisplayName { get { if (!string.IsNullOrWhiteSpace(nickname)) { return nickname; } if (!string.IsNullOrWhiteSpace(email)) { return email; } return string.Empty; } } } internal sealed class MapEntry { public string id; public string name; public string author; public string mod_version; public string description; public int downloads; public int likes; public string created_at; public string updated_at; public int revision; public bool liked_by_me; public string image_url; public string thumbnail_url; public string json_file_url; public string download_url; } internal sealed class PaginationInfo { public int page; public int page_size; public int total; public int total_pages; public bool has_next; public bool has_prev; } internal sealed class ModVersionEntry { public string id; public string version_name; public string created_at; } internal static class MapImageCache { private const long MaxCacheBytes = 268435456L; private const int MaxCacheFiles = 300; private static readonly object Sync = new object(); private static string CacheDirectory => Path.Combine(Application.persistentDataPath, "PeakMapBrowser", "ImageCache"); public static string GetExistingPath(string url) { if (string.IsNullOrEmpty(url)) { return null; } lock (Sync) { try { string cachePath = GetCachePath(url); if (!File.Exists(cachePath) || new FileInfo(cachePath).Length == 0) { return null; } Touch(cachePath); return cachePath; } catch { return null; } } } public static void Remove(string url) { if (string.IsNullOrEmpty(url)) { return; } lock (Sync) { try { string cachePath = GetCachePath(url); if (File.Exists(cachePath)) { File.Delete(cachePath); } } catch { } } } public static void Save(string url, byte[] bytes) { if (string.IsNullOrEmpty(url) || bytes == null || bytes.Length == 0) { return; } lock (Sync) { try { Directory.CreateDirectory(CacheDirectory); string cachePath = GetCachePath(url); if (File.Exists(cachePath)) { Touch(cachePath); return; } string text = cachePath + ".tmp-" + Guid.NewGuid().ToString("N"); try { File.WriteAllBytes(text, bytes); File.Move(text, cachePath); } finally { if (File.Exists(text)) { File.Delete(text); } } PruneCache(); } catch { } } } private static string GetCachePath(string url) { Directory.CreateDirectory(CacheDirectory); return Path.Combine(CacheDirectory, "image-" + Hash(url) + ".cache"); } private static string Hash(string value) { using SHA256 sHA = SHA256.Create(); byte[] array = sHA.ComputeHash(Encoding.UTF8.GetBytes(value)); StringBuilder stringBuilder = new StringBuilder(array.Length * 2); for (int i = 0; i < array.Length; i++) { stringBuilder.Append(array[i].ToString("x2")); } return stringBuilder.ToString(); } private static void Touch(string path) { try { File.SetLastAccessTimeUtc(path, DateTime.UtcNow); } catch { } } private static void PruneCache() { string[] files = Directory.GetFiles(CacheDirectory, "*.cache", SearchOption.TopDirectoryOnly); Array.Sort(files, (string a, string b) => File.GetLastAccessTimeUtc(a).CompareTo(File.GetLastAccessTimeUtc(b))); long num = 0L; for (int num2 = 0; num2 < files.Length; num2++) { num += new FileInfo(files[num2]).Length; } int num3 = Mathf.Max(0, files.Length - 300); for (int num4 = 0; num4 < files.Length && (num > 268435456 || num4 < num3); num4++) { try { long length = new FileInfo(files[num4]).Length; File.Delete(files[num4]); num -= length; } catch { } } } } internal static class MapSaveService { public static string SavePath => Path.Combine(Application.persistentDataPath, "TerrainCustomiser", "Map Saves"); public static string CoverPath => Path.Combine(SavePath, "Covers"); public static string BackupPath => Path.Combine(SavePath, "Backups"); private static string IndexPath => Path.Combine(Application.persistentDataPath, "PeakMapBrowser", "map-index.json"); public static string PicturesPath => Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); public static string[] GetLocalJsonFiles() { EnsureSaveDirectory(); string[] files = Directory.GetFiles(SavePath, "*.json"); Array.Sort(files, (string a, string b) => File.GetLastWriteTimeUtc(b).CompareTo(File.GetLastWriteTimeUtc(a))); return files; } public static string[] GetLocalImageFiles() { EnsureSaveDirectory(); string[] imageRootPaths = GetImageRootPaths(); List list = new List(); for (int i = 0; i < imageRootPaths.Length; i++) { if (!Directory.Exists(imageRootPaths[i])) { continue; } string[] files = Directory.GetFiles(imageRootPaths[i], "*.*", SearchOption.TopDirectoryOnly); for (int j = 0; j < files.Length; j++) { if (IsSupportedImage(files[j])) { list.Add(files[j]); } } } list.Sort((string a, string b) => File.GetLastWriteTimeUtc(b).CompareTo(File.GetLastWriteTimeUtc(a))); return list.ToArray(); } public static void EnsureSaveDirectory() { Directory.CreateDirectory(SavePath); Directory.CreateDirectory(CoverPath); Directory.CreateDirectory(BackupPath); } public static string[] GetImageRootPaths() { EnsureSaveDirectory(); if (string.IsNullOrEmpty(PicturesPath)) { return new string[2] { SavePath, CoverPath }; } return new string[3] { SavePath, CoverPath, PicturesPath }; } public static string GetImageRootLabel(string root) { string a = NormalizePath(root); if (string.Equals(a, NormalizePath(SavePath), StringComparison.OrdinalIgnoreCase)) { return "Map Saves"; } if (string.Equals(a, NormalizePath(CoverPath), StringComparison.OrdinalIgnoreCase)) { return "Covers"; } if (!string.IsNullOrEmpty(PicturesPath) && string.Equals(a, NormalizePath(PicturesPath), StringComparison.OrdinalIgnoreCase)) { return "Pictures"; } return DisplayName(root); } public static bool TryNormalizeWhitelistedDirectory(string path, out string normalized) { normalized = null; if (string.IsNullOrEmpty(path) || IsNetworkPath(path)) { return false; } string text; try { text = NormalizePath(path); } catch { return false; } if (!Directory.Exists(text) || IsHiddenOrSystem(text)) { return false; } string[] imageRootPaths = GetImageRootPaths(); for (int i = 0; i < imageRootPaths.Length; i++) { if (IsInsideRoot(text, imageRootPaths[i])) { normalized = text; return true; } } return false; } public static bool TryNormalizeWhitelistedImage(string path, out string normalized) { normalized = null; if (string.IsNullOrEmpty(path) || IsNetworkPath(path) || !IsSupportedImage(path)) { return false; } string text; try { text = NormalizePath(path); } catch { return false; } if (!File.Exists(text)) { return false; } string directoryName = Path.GetDirectoryName(text); if (!TryNormalizeWhitelistedDirectory(directoryName, out var _)) { return false; } normalized = text; return true; } public static string[] GetChildDirectories(string directory) { if (!TryNormalizeWhitelistedDirectory(directory, out var normalized)) { return new string[0]; } string[] directories = Directory.GetDirectories(normalized, "*", SearchOption.TopDirectoryOnly); List list = new List(); for (int i = 0; i < directories.Length; i++) { if (TryNormalizeWhitelistedDirectory(directories[i], out var normalized2)) { list.Add(normalized2); } } list.Sort(StringComparer.OrdinalIgnoreCase); return list.ToArray(); } public static string[] GetImageFilesInDirectory(string directory) { if (!TryNormalizeWhitelistedDirectory(directory, out var normalized)) { return new string[0]; } string[] files = Directory.GetFiles(normalized, "*.*", SearchOption.TopDirectoryOnly); List list = new List(); for (int i = 0; i < files.Length; i++) { if (TryNormalizeWhitelistedImage(files[i], out var normalized2)) { list.Add(normalized2); } } list.Sort((string a, string b) => File.GetLastWriteTimeUtc(b).CompareTo(File.GetLastWriteTimeUtc(a))); return list.ToArray(); } public static string SaveDownloadedMap(MapEntry map, byte[] bytes) { return SaveDownloadedMap(map, bytes, allowOverwriteLocalChanges: false); } public static string SaveDownloadedMap(MapEntry map, byte[] bytes, bool allowOverwriteLocalChanges) { if (map == null) { throw new ArgumentNullException("map"); } if (bytes == null) { throw new ArgumentNullException("bytes"); } EnsureSaveDirectory(); MapDownloadInfo downloadInfo = GetDownloadInfo(map); if (downloadInfo.Status == MapDownloadStatus.UpToDate) { return downloadInfo.Path; } if (downloadInfo.Status == MapDownloadStatus.LocalModified && !allowOverwriteLocalChanges) { throw new MapSaveException(MapDownloadStatus.LocalModified, "LOCAL_MODIFIED"); } string value = (string.IsNullOrWhiteSpace(map.name) ? "peak-map" : map.name.Trim()); string text = SanitizeFileName(value); if (string.IsNullOrEmpty(text)) { text = "peak-map"; } string text2 = FindRecord(map.id)?.path; if (string.IsNullOrEmpty(text2) || !IsInsideRoot(text2, SavePath)) { text2 = Path.Combine(SavePath, text + ".json"); int num = 2; while (File.Exists(text2)) { text2 = Path.Combine(SavePath, text + "-" + num + ".json"); num++; } } string text3 = text2 + ".tmp-" + Guid.NewGuid().ToString("N"); try { File.WriteAllBytes(text3, bytes); if (File.Exists(text2)) { string destFileName = Path.Combine(BackupPath, Path.GetFileNameWithoutExtension(text2) + "-" + DateTime.UtcNow.ToString("yyyyMMddHHmmssfff") + ".json"); File.Copy(text2, destFileName, overwrite: false); File.Replace(text3, text2, null); } else { File.Move(text3, text2); } SaveRecord(map, text2, ComputeSha256(bytes)); } finally { if (File.Exists(text3)) { File.Delete(text3); } } return text2; } public static MapDownloadInfo GetDownloadInfo(MapEntry map) { MapDownloadInfo mapDownloadInfo = new MapDownloadInfo(); if (map == null || string.IsNullOrEmpty(map.id)) { mapDownloadInfo.Status = MapDownloadStatus.New; return mapDownloadInfo; } LocalMapRecord localMapRecord = FindRecord(map.id); if (localMapRecord == null || string.IsNullOrEmpty(localMapRecord.path) || !File.Exists(localMapRecord.path)) { mapDownloadInfo.Status = MapDownloadStatus.New; mapDownloadInfo.CurrentRevision = map.revision; return mapDownloadInfo; } mapDownloadInfo.Path = localMapRecord.path; mapDownloadInfo.LocalRevision = localMapRecord.revision; mapDownloadInfo.CurrentRevision = map.revision; mapDownloadInfo.LocalHash = localMapRecord.sha256; string a = ComputeSha256(localMapRecord.path); if (!string.Equals(a, localMapRecord.sha256, StringComparison.OrdinalIgnoreCase)) { mapDownloadInfo.Status = MapDownloadStatus.LocalModified; } else if (map.revision > localMapRecord.revision) { mapDownloadInfo.Status = MapDownloadStatus.UpdateAvailable; } else { mapDownloadInfo.Status = MapDownloadStatus.UpToDate; } return mapDownloadInfo; } private static LocalMapRecord FindRecord(string mapId) { if (string.IsNullOrEmpty(mapId)) { return null; } LocalMapIndex localMapIndex = LoadIndex(); for (int i = 0; i < localMapIndex.maps.Count; i++) { if (string.Equals(localMapIndex.maps[i].map_id, mapId, StringComparison.Ordinal)) { return localMapIndex.maps[i]; } } return null; } private static void SaveRecord(MapEntry map, string path, string sha256) { LocalMapIndex localMapIndex = LoadIndex(); LocalMapRecord localMapRecord = null; for (int i = 0; i < localMapIndex.maps.Count; i++) { if (string.Equals(localMapIndex.maps[i].map_id, map.id, StringComparison.Ordinal)) { localMapRecord = localMapIndex.maps[i]; break; } } if (localMapRecord == null) { localMapRecord = new LocalMapRecord(); localMapRecord.map_id = map.id; localMapIndex.maps.Add(localMapRecord); } localMapRecord.path = path; localMapRecord.name = map.name ?? string.Empty; localMapRecord.revision = map.revision; localMapRecord.sha256 = sha256; SaveIndex(localMapIndex); } private static LocalMapIndex LoadIndex() { try { if (!File.Exists(IndexPath)) { return new LocalMapIndex(); } LocalMapIndex localMapIndex = JsonConvert.DeserializeObject(File.ReadAllText(IndexPath)); return localMapIndex ?? new LocalMapIndex(); } catch { return new LocalMapIndex(); } } private static void SaveIndex(LocalMapIndex index) { string directoryName = Path.GetDirectoryName(IndexPath); Directory.CreateDirectory(directoryName); string text = IndexPath + ".tmp-" + Guid.NewGuid().ToString("N"); try { File.WriteAllText(text, JsonConvert.SerializeObject((object)index, (Formatting)1), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(IndexPath)) { File.Replace(text, IndexPath, null); } else { File.Move(text, IndexPath); } } finally { if (File.Exists(text)) { File.Delete(text); } } } private static string ComputeSha256(string path) { using FileStream inputStream = File.OpenRead(path); using SHA256 sHA = SHA256.Create(); return ToHex(sHA.ComputeHash(inputStream)); } private static string ComputeSha256(byte[] bytes) { using SHA256 sHA = SHA256.Create(); return ToHex(sHA.ComputeHash(bytes)); } private static string ToHex(byte[] bytes) { StringBuilder stringBuilder = new StringBuilder(bytes.Length * 2); for (int i = 0; i < bytes.Length; i++) { stringBuilder.Append(bytes[i].ToString("x2")); } return stringBuilder.ToString(); } public static string SanitizeFileName(string value) { char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); StringBuilder stringBuilder = new StringBuilder(value.Length); foreach (char c in value) { bool flag = false; for (int j = 0; j < invalidFileNameChars.Length; j++) { if (c == invalidFileNameChars[j]) { flag = true; break; } } if (!flag) { stringBuilder.Append(c); } } return stringBuilder.ToString().Trim(); } public static string DisplayName(string path) { return string.IsNullOrEmpty(path) ? string.Empty : Path.GetFileName(path); } public static bool IsSupportedImage(string path) { string text = Path.GetExtension(path).ToLowerInvariant(); int result; switch (text) { default: result = ((text == ".gif") ? 1 : 0); break; case ".png": case ".jpg": case ".jpeg": case ".webp": result = 1; break; } return (byte)result != 0; } private static bool IsHiddenOrSystem(string path) { try { FileAttributes attributes = File.GetAttributes(path); return (attributes & FileAttributes.Hidden) != FileAttributes.None || (attributes & FileAttributes.System) != 0; } catch { return true; } } private static bool IsNetworkPath(string path) { return path.StartsWith("\\\\", StringComparison.Ordinal) || path.StartsWith("//", StringComparison.Ordinal); } private static bool IsInsideRoot(string candidate, string root) { string text = NormalizePath(candidate); string text2 = NormalizePath(root); if (string.Equals(text, text2, StringComparison.OrdinalIgnoreCase)) { return true; } string text3 = text2.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); char directorySeparatorChar = Path.DirectorySeparatorChar; string value = text3 + directorySeparatorChar; return text.StartsWith(value, StringComparison.OrdinalIgnoreCase); } private static string NormalizePath(string path) { return Path.GetFullPath(path).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); } public static string FindMatchingImage(string jsonPath, string[] imageFiles) { if (string.IsNullOrEmpty(jsonPath) || imageFiles == null || imageFiles.Length == 0) { return null; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(jsonPath); for (int i = 0; i < imageFiles.Length; i++) { string fileNameWithoutExtension2 = Path.GetFileNameWithoutExtension(imageFiles[i]); if (string.Equals(fileNameWithoutExtension, fileNameWithoutExtension2, StringComparison.OrdinalIgnoreCase)) { return imageFiles[i]; } } return null; } } internal enum MapDownloadStatus { New, UpToDate, UpdateAvailable, LocalModified } internal sealed class MapDownloadInfo { public MapDownloadStatus Status; public string Path; public int LocalRevision; public int CurrentRevision; public string LocalHash; } internal sealed class LocalMapIndex { public List maps = new List(); } internal sealed class LocalMapRecord { public string map_id; public string path; public string name; public int revision; public string sha256; } internal sealed class MapSaveException : Exception { public readonly MapDownloadStatus Status; public MapSaveException(MapDownloadStatus status, string message) : base(message) { Status = status; } } internal sealed class PeakMapApiClient { private readonly MonoBehaviour _runner; private readonly ManualLogSource _log; private readonly string _baseUrl; private string _language; public PeakMapSession Session { get; private set; } public bool IsSignedIn => Session != null && Session.HasUser; public bool ShouldRefreshSession { get { if (Session == null || !Session.HasRefreshToken) { return false; } if (string.IsNullOrEmpty(Session.access_token)) { return true; } if (Session.expires_at <= 0) { return false; } long num = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); return Session.expires_at - num < 300; } } public PeakMapApiClient(MonoBehaviour runner, ManualLogSource log, string baseUrl, string language) { _runner = runner; _log = log; _baseUrl = (baseUrl ?? "https://peakmap.top").TrimEnd(new char[1] { '/' }); _language = (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) ? "en" : "zh"); Session = PeakMapSessionStore.Load(log); } public void SetLanguage(string language) { _language = (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) ? "en" : "zh"); } public void SignOut() { PeakMapSessionStore.ClearUser(Session, _log); } public void SignOut(Action done) { _runner.StartCoroutine(SignOutRoutine(done)); } public void SignIn(string email, string password, Action done) { _runner.StartCoroutine(SignInRoutine(email, password, done)); } public void RefreshSession(Action done) { _runner.StartCoroutine(RefreshSessionRoutine(done)); } public void FetchMaps(int page, int pageSize, string query, string sort, string modVersion, Action done) { _runner.StartCoroutine(FetchMapsRoutine(page, pageSize, query, sort, modVersion, done)); } public void FetchAccountMaps(Action done) { _runner.StartCoroutine(FetchAccountMapsRoutine(done)); } public void FetchModVersions(Action done) { _runner.StartCoroutine(FetchModVersionsRoutine(done)); } public void ToggleLike(MapEntry map, Action done) { _runner.StartCoroutine(ToggleLikeRoutine(map, done)); } public void DownloadMap(MapEntry map, Action done) { DownloadMap(map, allowOverwriteLocalChanges: false, done); } public void DownloadMap(MapEntry map, bool allowOverwriteLocalChanges, Action done) { _runner.StartCoroutine(DownloadMapRoutine(map, allowOverwriteLocalChanges, done)); } public MapDownloadInfo GetDownloadInfo(MapEntry map) { return MapSaveService.GetDownloadInfo(map); } public void UploadMap(string mapName, string author, string version, string description, string jsonPath, string imagePath, Action done) { _runner.StartCoroutine(UploadMapRoutine(mapName, author, version, description, jsonPath, imagePath, done)); } public void UpdateMap(string mapId, string mapName, string author, string version, string description, string jsonPath, string imagePath, bool removeImage, Action done) { _runner.StartCoroutine(UpdateMapRoutine(mapId, mapName, author, version, description, jsonPath, imagePath, removeImage, done)); } public void DeleteMap(string mapId, Action done) { _runner.StartCoroutine(DeleteMapRoutine(mapId, done)); } public void DownloadTexture(string url, Action done) { string existingPath = MapImageCache.GetExistingPath(url); if (!string.IsNullOrEmpty(existingPath)) { _runner.StartCoroutine(LoadCachedTextureRoutine(url, existingPath, done)); } else { _runner.StartCoroutine(DownloadTextureRoutine(url, done)); } } private IEnumerator SignInRoutine(string email, string password, Action done) { UnityWebRequest request = JsonRequest(json: JsonConvert.SerializeObject((object)new { email = ((email == null) ? string.Empty : email.Trim()), password = (password ?? string.Empty) }), url: _baseUrl + "/api/auth/sign-in", method: "POST"); try { yield return request.SendWebRequest(); AuthResponse response = Parse(Body(request)); if (HasError(request) || response == null || !response.success) { done(response, ResponseError(response, Text("登录失败", "Sign in failed"))); yield break; } ApplyAuthResponse(response); done(response, null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator RefreshSessionRoutine(Action done) { if (Session == null || string.IsNullOrEmpty(Session.refresh_token)) { done(arg1: false, Text("没有可刷新的登录状态", "No refreshable session")); yield break; } UnityWebRequest request = JsonRequest(json: JsonConvert.SerializeObject((object)new { Session.refresh_token }), url: _baseUrl + "/api/auth/refresh", method: "POST"); try { yield return request.SendWebRequest(); AuthResponse response = Parse(Body(request)); if (HasError(request) || response == null || !response.success) { PeakMapSessionStore.ClearUser(Session, _log); done(arg1: false, ResponseError(response, Text("登录状态已过期", "Session expired"))); yield break; } ApplyAuthResponse(response); done(arg1: true, null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator SignOutRoutine(Action done) { bool serverRevoked = false; string error = null; if (Session != null && !string.IsNullOrEmpty(Session.access_token)) { UnityWebRequest request = JsonRequest(_baseUrl + "/api/auth/sign-out", "POST", "{}"); try { ApplySessionHeaders(request); yield return request.SendWebRequest(); BasicResponse response = Parse(Body(request)); serverRevoked = !HasError(request) && response != null && response.success; if (!serverRevoked) { error = ResponseError(response, Text("服务端退出登录失败", "Server sign-out failed")); } } finally { ((IDisposable)request)?.Dispose(); } } else { serverRevoked = true; } PeakMapSessionStore.ClearUser(Session, _log); done(serverRevoked, error); } private IEnumerator FetchMapsRoutine(int page, int pageSize, string query, string sort, string modVersion, Action done) { string url = _baseUrl + "/api/maps?page=" + page + "&page_size=" + pageSize + "&sort=" + Escape(sort) + "&lang=" + _language; if (!string.IsNullOrWhiteSpace(query)) { url = url + "&q=" + Escape(query.Trim()); } if (!string.IsNullOrWhiteSpace(modVersion)) { url = url + "&mod_version=" + Escape(modVersion.Trim()); } UnityWebRequest request = UnityWebRequest.Get(url); try { ApplySessionHeaders(request); yield return request.SendWebRequest(); CaptureGuestCookie(request); if (HasError(request)) { done(null, Text("获取地图列表失败: ", "Failed to fetch maps: ") + ErrorText(request)); yield break; } MapsResponse response = Parse(Body(request)); if (response == null || !response.success) { done(response, ResponseError(response, Text("获取地图列表失败", "Failed to fetch maps"))); yield break; } done(response, null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator FetchAccountMapsRoutine(Action done) { if (!IsSignedIn) { done(null, Text("请先登录", "Please sign in first")); yield break; } UnityWebRequest request = UnityWebRequest.Get(_baseUrl + "/api/account/maps"); try { ApplySessionHeaders(request); yield return request.SendWebRequest(); if (HasError(request)) { MapsResponse failed = Parse(Body(request)); done(failed, ResponseError(failed, Text("获取我的地图失败", "Failed to fetch my maps"))); yield break; } MapsResponse response = Parse(Body(request)); if (response == null || !response.success) { done(response, ResponseError(response, Text("获取我的地图失败", "Failed to fetch my maps"))); yield break; } done(response, null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator FetchModVersionsRoutine(Action done) { UnityWebRequest request = UnityWebRequest.Get(_baseUrl + "/api/mod-versions?lang=" + _language); try { yield return request.SendWebRequest(); if (HasError(request)) { done(null, Text("获取 MOD 版本失败: ", "Failed to fetch MOD versions: ") + ErrorText(request)); yield break; } ModVersionsResponse response = Parse(Body(request)); if (response == null || !response.success) { done(response, ResponseError(response, Text("获取 MOD 版本失败", "Failed to fetch MOD versions"))); yield break; } done(response, null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator ToggleLikeRoutine(MapEntry map, Action done) { if (map == null || string.IsNullOrEmpty(map.id)) { done(null, Text("地图缺少 ID", "Map is missing an ID")); yield break; } UnityWebRequest request = JsonRequest(_baseUrl + "/api/maps/" + Escape(map.id) + "/like", "POST", "{}"); try { ApplySessionHeaders(request); yield return request.SendWebRequest(); CaptureGuestCookie(request); LikeResponse response = Parse(Body(request)); if (HasError(request) || response == null || !response.success) { done(response, ResponseError(response, Text("点赞失败", "Like failed"))); yield break; } map.liked_by_me = response.liked; map.likes = response.likes; done(response, null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator DownloadMapRoutine(MapEntry map, bool allowOverwriteLocalChanges, Action done) { if (map == null || string.IsNullOrEmpty(map.download_url)) { done(null, Text("地图缺少下载地址", "Map is missing a download URL")); yield break; } MapDownloadInfo localInfo = MapSaveService.GetDownloadInfo(map); if (localInfo.Status == MapDownloadStatus.UpToDate) { done(null, Text("地图已经是最新版本", "This map is already up to date")); yield break; } if ((localInfo.Status == MapDownloadStatus.LocalModified || localInfo.Status == MapDownloadStatus.UpdateAvailable) && !allowOverwriteLocalChanges) { done(null, (localInfo.Status == MapDownloadStatus.LocalModified) ? Text("本地 JSON 已被修改,请确认覆盖", "The local JSON was modified; confirm overwrite") : Text("发现地图新版本,请确认更新", "A newer map version is available; confirm update")); yield break; } UnityWebRequest request = UnityWebRequest.Get(map.download_url); try { yield return request.SendWebRequest(); if (HasError(request)) { done(null, Text("下载失败: ", "Download failed: ") + ErrorText(request)); yield break; } try { string saved = MapSaveService.SaveDownloadedMap(map, request.downloadHandler.data, allowOverwriteLocalChanges); done(saved, null); } catch (MapSaveException ex) { done(null, (ex.Status == MapDownloadStatus.LocalModified) ? Text("本地 JSON 已被修改,请确认覆盖", "The local JSON was modified; confirm overwrite") : (Text("保存失败: ", "Save failed: ") + ex.Message)); } catch (Exception ex2) { done(null, Text("保存失败: ", "Save failed: ") + ex2.Message); } } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator UploadMapRoutine(string mapName, string author, string version, string description, string jsonPath, string imagePath, Action done) { List form; string error = BuildMapForm(mapName, author, version, description, jsonPath, imagePath, jsonOptional: false, out form); if (!string.IsNullOrEmpty(error)) { done(error); yield break; } UnityWebRequest request = UnityWebRequest.Post(_baseUrl + "/api/upload", form); try { ApplySessionHeaders(request); _log.LogInfo((object)("Sending upload request to " + _baseUrl + "/api/upload")); yield return request.SendWebRequest(); if (HasError(request)) { string body = Body(request); _log.LogWarning((object)("Upload request failed. Code=" + request.responseCode + ", error=" + request.error + ", body=" + body)); done(Text("上传失败: ", "Upload failed: ") + ((!string.IsNullOrEmpty(body)) ? ExtractError(body) : ErrorText(request))); yield break; } _log.LogInfo((object)("Upload request succeeded. Code=" + request.responseCode)); done(null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator UpdateMapRoutine(string mapId, string mapName, string author, string version, string description, string jsonPath, string imagePath, bool removeImage, Action done) { if (!IsSignedIn) { done(Text("请先登录", "Please sign in first")); yield break; } if (string.IsNullOrEmpty(mapId)) { done(Text("地图缺少 ID", "Map is missing an ID")); yield break; } List form; string error = BuildMapForm(mapName, author, version, description, jsonPath, imagePath, jsonOptional: true, out form); if (!string.IsNullOrEmpty(error)) { done(error); yield break; } form.Add((IMultipartFormSection)new MultipartFormDataSection("remove_image", removeImage ? "true" : "false")); UnityWebRequest request = UnityWebRequest.Post(_baseUrl + "/api/maps/" + Escape(mapId), form); try { request.method = "PUT"; ApplySessionHeaders(request); yield return request.SendWebRequest(); if (HasError(request)) { done(Text("保存失败: ", "Save failed: ") + ExtractError(Body(request), ErrorText(request))); yield break; } done(null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator DeleteMapRoutine(string mapId, Action done) { if (!IsSignedIn) { done(Text("请先登录", "Please sign in first")); yield break; } if (string.IsNullOrEmpty(mapId)) { done(Text("地图缺少 ID", "Map is missing an ID")); yield break; } UnityWebRequest request = UnityWebRequest.Delete(_baseUrl + "/api/maps/" + Escape(mapId)); try { ApplySessionHeaders(request); yield return request.SendWebRequest(); if (HasError(request)) { done(Text("删除失败: ", "Delete failed: ") + ExtractError(Body(request), ErrorText(request))); yield break; } done(null); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator DownloadTextureRoutine(string url, Action done) { if (string.IsNullOrEmpty(url)) { done(null); yield break; } UnityWebRequest request = UnityWebRequestTexture.GetTexture(url); try { yield return request.SendWebRequest(); if (HasError(request)) { _log.LogWarning((object)("Thumbnail failed: " + request.error)); done(null); yield break; } MapImageCache.Save(url, request.downloadHandler.data); done(DownloadHandlerTexture.GetContent(request)); } finally { ((IDisposable)request)?.Dispose(); } } private IEnumerator LoadCachedTextureRoutine(string url, string path, Action done) { string fileUrl; try { fileUrl = new Uri(path).AbsoluteUri; } catch { MapImageCache.Remove(url); fileUrl = null; } if (string.IsNullOrEmpty(fileUrl)) { yield return _runner.StartCoroutine(DownloadTextureRoutine(url, done)); yield break; } UnityWebRequest request = UnityWebRequestTexture.GetTexture(fileUrl); try { yield return request.SendWebRequest(); if (HasError(request)) { _log.LogWarning((object)("Cached thumbnail failed, downloading again: " + request.error)); MapImageCache.Remove(url); yield return _runner.StartCoroutine(DownloadTextureRoutine(url, done)); yield break; } done(DownloadHandlerTexture.GetContent(request)); } finally { ((IDisposable)request)?.Dispose(); } } private string BuildMapForm(string mapName, string author, string version, string description, string jsonPath, string imagePath, bool jsonOptional, out List form) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown form = new List(); if (string.IsNullOrWhiteSpace(mapName) || string.IsNullOrWhiteSpace(author) || string.IsNullOrWhiteSpace(version)) { return Text("地图名称、作者和版本不能为空", "Map name, author, and version are required"); } if (!jsonOptional && (string.IsNullOrEmpty(jsonPath) || !File.Exists(jsonPath))) { return Text("请选择本地 JSON 地图文件", "Please select a local JSON map file"); } form.Add((IMultipartFormSection)new MultipartFormDataSection("name", mapName.Trim())); form.Add((IMultipartFormSection)new MultipartFormDataSection("author", author.Trim())); form.Add((IMultipartFormSection)new MultipartFormDataSection("mod_version", version.Trim())); form.Add((IMultipartFormSection)new MultipartFormDataSection("description", (description == null) ? string.Empty : description.Trim())); if (!string.IsNullOrEmpty(jsonPath) && File.Exists(jsonPath)) { form.Add((IMultipartFormSection)new MultipartFormFileSection("json_file", File.ReadAllBytes(jsonPath), Path.GetFileName(jsonPath), "application/json")); } if (!string.IsNullOrEmpty(imagePath) && File.Exists(imagePath)) { object obj; switch (Path.GetExtension(imagePath).ToLowerInvariant()) { default: obj = "image/png"; break; case ".gif": obj = "image/gif"; break; case ".webp": obj = "image/webp"; break; case ".jpg": case ".jpeg": obj = "image/jpeg"; break; } string text = (string)obj; form.Add((IMultipartFormSection)new MultipartFormFileSection("image_file", File.ReadAllBytes(imagePath), Path.GetFileName(imagePath), text)); } return null; } private UnityWebRequest JsonRequest(string url, string method, string json) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown byte[] bytes = Encoding.UTF8.GetBytes(json ?? "{}"); UnityWebRequest val = new UnityWebRequest(url, method); val.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes); val.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); val.SetRequestHeader("Content-Type", "application/json; charset=utf-8"); val.SetRequestHeader("Accept", "application/json"); return val; } private void ApplySessionHeaders(UnityWebRequest request) { if (request != null && Session != null) { if (!string.IsNullOrEmpty(Session.access_token)) { request.SetRequestHeader("Authorization", "Bearer " + Session.access_token); } if (!string.IsNullOrEmpty(Session.guest_id)) { request.SetRequestHeader("Cookie", "peak_guest_id=" + Session.guest_id); } } } private void CaptureGuestCookie(UnityWebRequest request) { if (request == null || Session == null) { return; } string responseHeader = request.GetResponseHeader("Set-Cookie"); if (string.IsNullOrEmpty(responseHeader)) { return; } int num = responseHeader.IndexOf("peak_guest_id=", StringComparison.OrdinalIgnoreCase); if (num >= 0) { num += "peak_guest_id=".Length; int num2 = responseHeader.IndexOf(';', num); string text = ((num2 >= 0) ? responseHeader.Substring(num, num2 - num) : responseHeader.Substring(num)); if (!string.IsNullOrEmpty(text) && !string.Equals(Session.guest_id, text, StringComparison.Ordinal)) { Session.guest_id = text; PeakMapSessionStore.Save(Session, _log); } } } private void ApplyAuthResponse(AuthResponse response) { if (Session == null) { Session = new PeakMapSession(); } Session.access_token = response.access_token; Session.refresh_token = response.refresh_token; Session.expires_at = response.expires_at; if (response.user != null) { Session.user_id = response.user.id; Session.email = response.user.email; Session.nickname = response.user.nickname; } PeakMapSessionStore.Save(Session, _log); } private T Parse(string json) where T : class { try { return JsonConvert.DeserializeObject(json); } catch (Exception ex) { _log.LogWarning((object)("API JSON parse failed: " + ex.Message)); return null; } } private static bool HasError(UnityWebRequest request) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 return (int)request.result != 1; } private static string Body(UnityWebRequest request) { return (request != null && request.downloadHandler != null) ? request.downloadHandler.text : string.Empty; } private static string ErrorText(UnityWebRequest request) { return (request != null && !string.IsNullOrEmpty(request.error)) ? request.error : ("HTTP " + ((request != null) ? request.responseCode.ToString() : "0")); } private static string ResponseError(MapsResponse response, string fallback) { return (response != null && !string.IsNullOrEmpty(response.error_message)) ? response.error_message : ((response != null && !string.IsNullOrEmpty(response.error)) ? response.error : fallback); } private static string ResponseError(ModVersionsResponse response, string fallback) { return (response != null && !string.IsNullOrEmpty(response.error_message)) ? response.error_message : ((response != null && !string.IsNullOrEmpty(response.error)) ? response.error : fallback); } private static string ResponseError(AuthResponse response, string fallback) { return (response != null && !string.IsNullOrEmpty(response.error_message)) ? response.error_message : ((response != null && !string.IsNullOrEmpty(response.error)) ? response.error : fallback); } private static string ResponseError(BasicResponse response, string fallback) { return (response != null && !string.IsNullOrEmpty(response.error_message)) ? response.error_message : ((response != null && !string.IsNullOrEmpty(response.error)) ? response.error : fallback); } private static string ResponseError(LikeResponse response, string fallback) { return (response != null && !string.IsNullOrEmpty(response.error_message)) ? response.error_message : ((response != null && !string.IsNullOrEmpty(response.error)) ? response.error : fallback); } private string ExtractError(string json) { return ExtractError(json, Text("服务器错误", "Server error")); } private string ExtractError(string json, string fallback) { BasicResponse basicResponse = Parse(json); if (basicResponse != null) { if (!string.IsNullOrEmpty(basicResponse.error_message)) { return basicResponse.error_message; } if (!string.IsNullOrEmpty(basicResponse.error)) { return basicResponse.error; } } return string.IsNullOrEmpty(json) ? fallback : json; } private static string Escape(string value) { return UnityWebRequest.EscapeURL(value ?? string.Empty); } private string Text(string zh, string en) { return string.Equals(_language, "en", StringComparison.OrdinalIgnoreCase) ? en : zh; } } internal static class PeakMapLanguage { public static string Resolve(string mode, ManualLogSource log) { return ResolveDetailed(mode, log).Language; } public static PeakMapLanguageResult ResolveDetailed(string mode, ManualLogSource log) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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) string text = NormalizeMode(mode); if (text == "zh" || text == "en") { return new PeakMapLanguageResult(text, "Config", text, text); } if (TryGetGameLocalizedTextLanguage(out var language)) { return new PeakMapLanguageResult(IsChineseGameLanguage(language) ? "zh" : "en", "Game.LocalizedText.CURRENT_LANGUAGE", language, text); } if (TryGetUnityLocalizationCode(out var code, out var source)) { return new PeakMapLanguageResult(IsChineseCode(code) ? "zh" : "en", source, code, text); } string rawValue = ((object)Application.systemLanguage/*cast due to .constrained prefix*/).ToString(); return new PeakMapLanguageResult(IsChineseSystemLanguage(Application.systemLanguage) ? "zh" : "en", "SystemLanguageFallback", rawValue, text); } public static string NormalizeMode(string mode) { if (string.IsNullOrWhiteSpace(mode)) { return "auto"; } string text = mode.Trim().ToLowerInvariant(); switch (text) { default: if (!(text == "chinese")) { if (text == "en" || text == "en-us" || text == "english") { return "en"; } return "auto"; } goto case "zh"; case "zh": case "cn": case "zh-cn": return "zh"; } } private static bool TryGetUnityLocalizationCode(out string code, out string source) { code = null; source = null; try { Type type = Type.GetType("UnityEngine.Localization.Settings.LocalizationSettings, Unity.Localization"); if (type == null) { return false; } PropertyInfo property = type.GetProperty("SelectedLocale", BindingFlags.Static | BindingFlags.Public); object locale = ((property != null) ? property.GetValue(null, null) : null); if (TryExtractLocaleCode(locale, out code)) { source = "UnityLocalization.SelectedLocale"; return true; } PropertyInfo property2 = type.GetProperty("SelectedLocaleAsync", BindingFlags.Static | BindingFlags.Public); object selectedLocaleAsync = ((property2 != null) ? property2.GetValue(null, null) : null); if (TryExtractAsyncLocaleCode(selectedLocaleAsync, out code)) { source = "UnityLocalization.SelectedLocaleAsync"; return true; } MethodInfo method = type.GetMethod("GetSelectedLocale", BindingFlags.Static | BindingFlags.Public); object locale2 = ((method != null) ? method.Invoke(null, null) : null); if (TryExtractLocaleCode(locale2, out code)) { source = "UnityLocalization.GetSelectedLocale"; return true; } } catch { return false; } return false; } private static bool TryGetGameLocalizedTextLanguage(out string language) { language = null; try { Type type = FindType("LocalizedText", "Assembly-CSharp"); if (type == null) { return false; } FieldInfo field = type.GetField("CURRENT_LANGUAGE", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); object obj = ((field != null) ? field.GetValue(null) : null); if (obj == null) { return false; } language = obj.ToString(); if (string.IsNullOrWhiteSpace(language)) { language = Convert.ToInt32(obj).ToString(); } return !string.IsNullOrWhiteSpace(language); } catch { return false; } } private static bool TryExtractAsyncLocaleCode(object selectedLocaleAsync, out string code) { code = null; if (selectedLocaleAsync == null) { return false; } try { PropertyInfo property = selectedLocaleAsync.GetType().GetProperty("IsDone", BindingFlags.Instance | BindingFlags.Public); object obj = ((property != null) ? property.GetValue(selectedLocaleAsync, null) : null); if (obj is bool && !(bool)obj) { return false; } PropertyInfo property2 = selectedLocaleAsync.GetType().GetProperty("Result", BindingFlags.Instance | BindingFlags.Public); object locale = ((property2 != null) ? property2.GetValue(selectedLocaleAsync, null) : null); return TryExtractLocaleCode(locale, out code); } catch { return false; } } private static bool TryExtractLocaleCode(object locale, out string code) { code = null; if (locale == null) { return false; } try { PropertyInfo property = locale.GetType().GetProperty("Identifier", BindingFlags.Instance | BindingFlags.Public); object obj = ((property != null) ? property.GetValue(locale, null) : null); if (obj != null) { PropertyInfo property2 = obj.GetType().GetProperty("Code", BindingFlags.Instance | BindingFlags.Public); object obj2 = ((property2 != null) ? property2.GetValue(obj, null) : null); if (obj2 != null && !string.IsNullOrWhiteSpace(obj2.ToString())) { code = obj2.ToString(); return true; } } PropertyInfo property3 = locale.GetType().GetProperty("LocaleName", BindingFlags.Instance | BindingFlags.Public); object obj3 = ((property3 != null) ? property3.GetValue(locale, null) : null); if (obj3 != null && !string.IsNullOrWhiteSpace(obj3.ToString())) { code = obj3.ToString(); return true; } string text = locale.ToString(); if (!string.IsNullOrWhiteSpace(text)) { code = text; return true; } } catch { return false; } return false; } private static Type FindType(string typeName, string assemblyName) { Type type = Type.GetType(typeName + ", " + assemblyName); if (type != null) { return type; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { AssemblyName name = assemblies[i].GetName(); if (string.Equals(name.Name, assemblyName, StringComparison.OrdinalIgnoreCase)) { Type type2 = assemblies[i].GetType(typeName, throwOnError: false); if (type2 != null) { return type2; } } } return null; } private static bool IsChineseCode(string code) { return !string.IsNullOrWhiteSpace(code) && code.Trim().StartsWith("zh", StringComparison.OrdinalIgnoreCase); } private static bool IsChineseGameLanguage(string language) { if (string.IsNullOrWhiteSpace(language)) { return false; } string a = language.Trim(); return string.Equals(a, "SimplifiedChinese", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Chinese", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "ChineseSimplified", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "9", StringComparison.OrdinalIgnoreCase); } private static bool IsChineseSystemLanguage(SystemLanguage language) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 return (int)language == 6 || (int)language == 40 || (int)language == 41; } } internal sealed class PeakMapLanguageResult { public readonly string Language; public readonly string Source; public readonly string RawValue; public readonly string Mode; public PeakMapLanguageResult(string language, string source, string rawValue, string mode) { Language = language; Source = source; RawValue = rawValue; Mode = mode; } } internal static class PeakMapSessionStore { private sealed class PersistedSession { public int version; public string protected_refresh_token; public string user_id; public string email; public string nickname; public string guest_id; } private static readonly byte[] Entropy = Encoding.UTF8.GetBytes("com.wuyachiyu.peakmapbrowser.session.v2"); private static string DirectoryPath => Path.Combine(Application.persistentDataPath, "PeakMapBrowser"); private static string FilePath => Path.Combine(DirectoryPath, "session.json"); public static PeakMapSession Load(ManualLogSource log) { try { if (!File.Exists(FilePath)) { return new PeakMapSession(); } string text = File.ReadAllText(FilePath); PersistedSession persistedSession = JsonConvert.DeserializeObject(text); if (persistedSession != null && persistedSession.version >= 2) { PeakMapSession peakMapSession = new PeakMapSession { user_id = persistedSession.user_id, email = persistedSession.email, nickname = persistedSession.nickname, guest_id = persistedSession.guest_id }; if (!string.IsNullOrEmpty(persistedSession.protected_refresh_token)) { peakMapSession.refresh_token = Unprotect(persistedSession.protected_refresh_token); } return peakMapSession; } PeakMapSession peakMapSession2 = JsonConvert.DeserializeObject(text); if (peakMapSession2 != null) { Save(peakMapSession2, log); return peakMapSession2; } return new PeakMapSession(); } catch (Exception ex) { log.LogWarning((object)("Failed to load PeakMapBrowser session: " + ex.Message)); return new PeakMapSession(); } } public static void Save(PeakMapSession session, ManualLogSource log) { try { Directory.CreateDirectory(DirectoryPath); PeakMapSession peakMapSession = session ?? new PeakMapSession(); PersistedSession persistedSession = new PersistedSession { version = 2, protected_refresh_token = (string.IsNullOrEmpty(peakMapSession.refresh_token) ? string.Empty : Protect(peakMapSession.refresh_token)), user_id = (peakMapSession.user_id ?? string.Empty), email = (peakMapSession.email ?? string.Empty), nickname = (peakMapSession.nickname ?? string.Empty), guest_id = (peakMapSession.guest_id ?? string.Empty) }; string text = FilePath + ".tmp-" + Guid.NewGuid().ToString("N"); try { File.WriteAllText(text, JsonConvert.SerializeObject((object)persistedSession, (Formatting)1), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(FilePath)) { File.Replace(text, FilePath, null); } else { File.Move(text, FilePath); } } finally { if (File.Exists(text)) { File.Delete(text); } } } catch (Exception ex) { log.LogWarning((object)("Failed to save PeakMapBrowser session: " + ex.Message)); } } public static void ClearUser(PeakMapSession session, ManualLogSource log) { if (session == null) { session = new PeakMapSession(); } session.access_token = string.Empty; session.refresh_token = string.Empty; session.expires_at = 0L; session.user_id = string.Empty; session.email = string.Empty; session.nickname = string.Empty; Save(session, log); } private static string Protect(string value) { byte[] bytes = Encoding.UTF8.GetBytes(value ?? string.Empty); byte[] inArray = ProtectedData.Protect(bytes, Entropy, (DataProtectionScope)0); return Convert.ToBase64String(inArray); } private static string Unprotect(string value) { byte[] array = Convert.FromBase64String(value); byte[] bytes = ProtectedData.Unprotect(array, Entropy, (DataProtectionScope)0); return Encoding.UTF8.GetString(bytes); } } internal sealed class PeakMapWindow { private readonly MonoBehaviour _runner; private readonly ManualLogSource _log; private readonly PeakMapApiClient _api; private readonly int _pageSize; private readonly Dictionary _thumbnails = new Dictionary(); private readonly Dictionary _downloadInfoCache = new Dictionary(); private bool _visible; private bool _cursorCaptured; private bool _previousCursorVisible; private CursorLockMode _previousCursorLockMode; private GameObject _inputBlocker; private bool _stylesReady; private bool _loadingMaps; private bool _loadingVersions; private bool _downloading; private bool _uploading; private bool _liking; private bool _uploadOpen; private bool _loginOpen; private bool _accountOpen; private bool _communityDetailOpen; private bool _downloadConfirmOpen; private bool _loadingAccountMaps; private bool _savingAccountMap; private bool _deletingAccountMap; private bool _refreshingSession; private bool _loadedOnce; private int _topLayerOpenedFrame = -1; private float _nextSessionRefreshCheckTime; private Rect _windowRect; private Vector2 _mapScroll; private Vector2 _uploadSaveScroll; private Vector2 _detailScroll; private Vector2 _accountScroll; private Vector2 _accountDescriptionScroll; private List _maps = new List(); private List _accountMaps = new List(); private List _versions = new List(); private PaginationInfo _pagination; private int _selectedMapIndex; private int _selectedAccountMapIndex = -1; private int _page = 1; private string _query = string.Empty; private string _sort = "newest"; private string _versionFilter = string.Empty; private string _languageMode; private string _language; private string _languageSource; private string _languageRawValue; private string _toggleKeyLabel; private float _nextLanguageCheckTime; private string _status = string.Empty; private string _toast = string.Empty; private float _toastUntil; private float _downloadInfoCacheUntil; private string[] _localSaves = new string[0]; private readonly List _filteredLocalSaveIndexes = new List(); private int _selectedLocalSave; private string _localSaveFilter = string.Empty; private string _localSaveError = string.Empty; private float _nextLocalSaveScanTime; private int _selectedUploadVersion; private bool _uploadVersionDropdownOpen; private Vector2 _uploadVersionScroll; private bool _uploadSaveDropdownOpen; private string[] _localImages = new string[0]; private readonly List _filteredLocalImageIndexes = new List(); private int _selectedLocalImage = -1; private string _localImageFilter = string.Empty; private string _localImageError = string.Empty; private bool _uploadImageDropdownOpen; private Vector2 _uploadImageScroll; private bool _imagePickerOpen; private string[] _imageRootPaths = new string[0]; private int _imagePickerRootIndex; private string _imagePickerDirectory = string.Empty; private string[] _imagePickerDirs = new string[0]; private string[] _imagePickerFiles = new string[0]; private string _imagePickerSelected = string.Empty; private string _imagePickerError = string.Empty; private Vector2 _imagePickerScroll; private string _uploadName = string.Empty; private string _uploadAuthor = string.Empty; private string _uploadDescription = string.Empty; private string _loginEmail = string.Empty; private string _loginPassword = string.Empty; private string _editName = string.Empty; private string _editAuthor = string.Empty; private string _editVersion = string.Empty; private string _editDescription = string.Empty; private bool _editReplaceJson; private bool _accountJsonDropdownOpen; private bool _accountVersionDropdownOpen; private Vector2 _accountVersionScroll; private bool _editReplaceImage; private bool _editRemoveImage; private string _deleteConfirmMapId = string.Empty; private string _downloadConfirmMapId = string.Empty; private GUIStyle _rootStyle; private GUIStyle _panelStyle; private GUIStyle _panelStrongStyle; private GUIStyle _detailMetaStyle; private GUIStyle _detailDescriptionStyle; private GUIStyle _cardStyle; private GUIStyle _buttonStyle; private GUIStyle _primaryButtonStyle; private GUIStyle _iconButtonStyle; private GUIStyle _inputStyle; private GUIStyle _textAreaStyle; private GUIStyle _titleStyle; private GUIStyle _h2Style; private GUIStyle _labelStyle; private GUIStyle _statLabelStyle; private GUIStyle _statValueStyle; private GUIStyle _cardStatsStyle; private GUIStyle _mutedStyle; private GUIStyle _cardDescStyle; private GUIStyle _detailTextStyle; private GUIStyle _detailTitleStyle; private GUIStyle _tinyStyle; private GUIStyle _badgeStyle; private GUIStyle _apiBadgeStyle; private GUIStyle _pagePillStyle; private GUIStyle _toastStyle; private GUIStyle _thumbStyle; private GUIStyle _sidebarButtonStyle; private GUIStyle _sidebarSelectedStyle; private GUIStyle _statBoxStyle; private GUIStyle _modalBackdropStyle; private GUIStyle _dangerStyle; private Texture2D _placeholderThumb; private Font _uiFont; private string SelectedLocalSavePath => (_selectedLocalSave >= 0 && _selectedLocalSave < _localSaves.Length) ? _localSaves[_selectedLocalSave] : null; private string SelectedLocalImagePath => (_selectedLocalImage >= 0 && _selectedLocalImage < _localImages.Length) ? _localImages[_selectedLocalImage] : null; private MapEntry SelectedMap => (_maps != null && _maps.Count > 0 && _selectedMapIndex >= 0 && _selectedMapIndex < _maps.Count) ? _maps[_selectedMapIndex] : null; private MapEntry SelectedAccountMap => (_accountMaps != null && _accountMaps.Count > 0 && _selectedAccountMapIndex >= 0 && _selectedAccountMapIndex < _accountMaps.Count) ? _accountMaps[_selectedAccountMapIndex] : null; public PeakMapWindow(MonoBehaviour runner, ManualLogSource log, string apiBaseUrl, string language, int pageSize, string toggleKeyLabel) { //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) _runner = runner; _log = log; _toggleKeyLabel = (string.IsNullOrWhiteSpace(toggleKeyLabel) ? "/" : toggleKeyLabel); _languageMode = language; PeakMapLanguageResult peakMapLanguageResult = PeakMapLanguage.ResolveDetailed(language, log); _language = peakMapLanguageResult.Language; _languageSource = peakMapLanguageResult.Source; _languageRawValue = peakMapLanguageResult.RawValue; _api = new PeakMapApiClient(runner, log, apiBaseUrl, _language); _pageSize = pageSize; _windowRect = new Rect(0f, 0f, 960f, 640f); _status = T("按 " + _toggleKeyLabel + " 打开或关闭地图库", "Press " + _toggleKeyLabel + " to open or close the map browser"); _log.LogInfo((object)("PEAK Map Browser language resolved: lang=" + _language + ", mode=" + peakMapLanguageResult.Mode + ", source=" + _languageSource + ", raw=" + _languageRawValue)); } public void Toggle() { SetVisible(!_visible); if (_visible && !_loadedOnce) { RefreshAll(); } } private void SetVisible(bool visible) { if (_visible != visible) { _visible = visible; if (visible) { _log.LogInfo((object)"Map browser opened."); CaptureCursor(); EnsureInputBlocker(); return; } _log.LogInfo((object)"Map browser closed."); RestoreCursor(); SetInputBlockerActive(active: false); _uploadOpen = false; _imagePickerOpen = false; _loginOpen = false; _accountOpen = false; _communityDetailOpen = false; _uploadVersionDropdownOpen = false; _uploadImageDropdownOpen = false; _uploadSaveDropdownOpen = false; } } private void CaptureCursor() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!_cursorCaptured) { _previousCursorVisible = Cursor.visible; _previousCursorLockMode = Cursor.lockState; _cursorCaptured = true; } Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } private void RestoreCursor() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (_cursorCaptured) { Cursor.visible = _previousCursorVisible; Cursor.lockState = _previousCursorLockMode; _cursorCaptured = false; } } private void EnsureInputBlocker() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_inputBlocker == (Object)null) { _inputBlocker = new GameObject("PeakMapBrowser_InputBlocker"); Object.DontDestroyOnLoad((Object)(object)_inputBlocker); Canvas val = _inputBlocker.AddComponent(); val.renderMode = (RenderMode)0; val.sortingOrder = 32767; _inputBlocker.AddComponent(); GameObject val2 = new GameObject("Blocker"); val2.transform.SetParent(_inputBlocker.transform, false); Image val3 = val2.AddComponent(); ((Graphic)val3).color = new Color(0f, 0f, 0f, 0f); ((Graphic)val3).raycastTarget = true; RectTransform rectTransform = ((Graphic)val3).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; } SetInputBlockerActive(active: true); } private void SetInputBlockerActive(bool active) { if ((Object)(object)_inputBlocker != (Object)null && _inputBlocker.activeSelf != active) { _inputBlocker.SetActive(active); } } public void Update() { RefreshLanguageIfNeeded(); RefreshSessionIfNeeded(); if (_visible) { CaptureCursor(); EnsureInputBlocker(); Input.ResetInputAxes(); } } private void RefreshLanguageIfNeeded() { if (Time.unscaledTime < _nextLanguageCheckTime) { return; } _nextLanguageCheckTime = Time.unscaledTime + 2f; PeakMapLanguageResult peakMapLanguageResult = PeakMapLanguage.ResolveDetailed(_languageMode, _log); bool flag = !string.Equals(peakMapLanguageResult.Language, _language, StringComparison.OrdinalIgnoreCase); bool flag2 = !string.Equals(peakMapLanguageResult.Source, _languageSource, StringComparison.Ordinal) || !string.Equals(peakMapLanguageResult.RawValue, _languageRawValue, StringComparison.Ordinal); if (flag || flag2) { string language = _language; string languageSource = _languageSource; string languageRawValue = _languageRawValue; _language = peakMapLanguageResult.Language; _languageSource = peakMapLanguageResult.Source; _languageRawValue = peakMapLanguageResult.RawValue; if (flag) { _api.SetLanguage(_language); _status = T("语言已切换为中文", "Language switched to English"); ShowToast(_status); } _log.LogInfo((object)("PEAK Map Browser language resolved: lang=" + _language + ", mode=" + peakMapLanguageResult.Mode + ", source=" + _languageSource + ", raw=" + _languageRawValue + " (previous lang=" + language + ", source=" + languageSource + ", raw=" + languageRawValue + ")")); } } public void Dispose() { SetVisible(visible: false); if ((Object)(object)_inputBlocker != (Object)null) { Object.Destroy((Object)(object)_inputBlocker); _inputBlocker = null; } } public void Draw() { //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_00a2: Unknown result type (might be due to invalid IL or missing references) if (!_visible) { return; } Color color = GUI.color; Color contentColor = GUI.contentColor; Color backgroundColor = GUI.backgroundColor; bool enabled = GUI.enabled; int depth = GUI.depth; GUI.color = Color.white; GUI.contentColor = Color.white; GUI.backgroundColor = Color.white; GUI.enabled = true; try { EnsureStyles(); CenterWindow(); GUI.depth = -100; DrawDimBackground(); DrawSolidBackground(_windowRect, new Color(0.01f, 0.016f, 0.012f, 1f)); GUI.Box(_windowRect, GUIContent.none, _rootStyle); bool flag = _communityDetailOpen || _downloadConfirmOpen; bool enabled2 = GUI.enabled; if (flag) { GUI.enabled = false; } if (!_uploadOpen && !_imagePickerOpen && !_loginOpen) { DrawHeader(); DrawSidebar(); if (_accountOpen) { DrawAccountPage(); } else { DrawContent(); } DrawFooter(); } GUI.enabled = enabled2; if (_communityDetailOpen && !_downloadConfirmOpen && !_imagePickerOpen && !_loginOpen && !_uploadOpen) { DrawCommunityDetailModal(); } if (_downloadConfirmOpen && !_imagePickerOpen && !_loginOpen && !_uploadOpen) { DrawDownloadConfirmModal(); } if (_uploadOpen && !_imagePickerOpen) { DrawUploadModal(); } if (_loginOpen && !_imagePickerOpen) { DrawLoginModal(); } if (_imagePickerOpen) { DrawImagePickerModal(); } DrawToast(); ConsumeOverlayEvents(); } finally { GUI.color = color; GUI.contentColor = contentColor; GUI.backgroundColor = backgroundColor; GUI.enabled = enabled; GUI.depth = depth; } } private void ConsumeOverlayEvents() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 Event current = Event.current; if (current != null && ((int)current.type == 0 || (int)current.type == 1 || (int)current.type == 3 || (int)current.type == 6)) { current.Use(); } } private void BlockTopLayerInputThisFrame() { _topLayerOpenedFrame = Time.frameCount; } private bool IsTopLayerInputBlocked() { return _topLayerOpenedFrame == Time.frameCount; } private void CenterWindow() { //IL_0062: 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) float num = Mathf.Round(Mathf.Min(1160f, (float)Screen.width - 24f)); float num2 = Mathf.Round(Mathf.Min(720f, (float)Screen.height - 24f)); _windowRect = new Rect(Mathf.Round(((float)Screen.width - num) * 0.5f), Mathf.Round(((float)Screen.height - num2) * 0.5f), num, num2); } private void DrawDimBackground() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.42f); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; } private void DrawSolidBackground(Rect rect, Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0); GUI.color = color2; } private void DrawHeader() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Invalid comparison between Unknown and I4 //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Invalid comparison between Unknown and I4 Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).x, ((Rect)(ref _windowRect)).y, ((Rect)(ref _windowRect)).width, 64f); GUI.Box(val, GUIContent.none, _panelStrongStyle); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).y + 17f, 30f, 30f); GUI.Box(val2, GUIContent.none, _badgeStyle); GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y - 2f, 22f, 28f), "/", _titleStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 62f, ((Rect)(ref val)).y + 11f, 190f, 16f), T("远征数据库", "EXPEDITION DATABASE"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 62f, ((Rect)(ref val)).y + 27f, 210f, 30f), T("PEAK 地图库", "PEAK Maps"), _titleStyle); float num = ((Rect)(ref val)).y + 17f; float num2 = 38f; float num3 = 118f; float num4 = 112f; float num5 = 38f; float num6 = 8f; float num7 = ((Rect)(ref val)).xMax - num2 - num4 - num3 - num5 - num6 * 4f - 22f; if (GUI.Button(new Rect(num7, num, num3, 34f), T("上传地图", "Upload"), _primaryButtonStyle)) { OpenUpload(); } num7 += num3 + num6; if (GUI.Button(new Rect(num7, num, num5, 34f), "↻", _iconButtonStyle)) { RefreshAll(); } num7 += num5 + num6; string text = (_api.IsSignedIn ? ShortAccountName(_api.Session.DisplayName) : T("登录", "Sign in")); if (GUI.Button(new Rect(num7, num, num4, 34f), text, _buttonStyle)) { if (_api.IsSignedIn) { OpenAccount(); } else { OpenLogin(); } } num7 += num4 + num6; if (GUI.Button(new Rect(num7, num, num2, 34f), "×", _iconButtonStyle)) { SetVisible(visible: false); } Event current = Event.current; if ((int)current.type == 4 && (int)current.keyCode == 13 && GUI.GetNameOfFocusedControl() == "PeakMapSearch") { _page = 1; FetchMaps(); current.Use(); } } private void DrawSidebar() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).x, ((Rect)(ref _windowRect)).y + 64f, 230f, ((Rect)(ref _windowRect)).height - 92f); GUI.Box(val, GUIContent.none, _panelStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).y + 22f, 160f, 16f), T("导航", "NAVIGATION"), _tinyStyle); float num = ((Rect)(ref val)).y + 58f; DrawNavButton(new Rect(((Rect)(ref val)).x + 22f, num, ((Rect)(ref val)).width - 44f, 42f), T("⌂ 主页", "⌂ Home"), !_accountOpen, delegate { _accountOpen = false; }); num += 50f; DrawNavButton(new Rect(((Rect)(ref val)).x + 22f, num, ((Rect)(ref val)).width - 44f, 42f), T("▣ 我的地图", "▣ My Maps"), _accountOpen, delegate { if (_api.IsSignedIn) { OpenAccount(); } else { OpenLogin(); } }); num += 50f; DrawNavButton(new Rect(((Rect)(ref val)).x + 22f, num, ((Rect)(ref val)).width - 44f, 42f), T("◎ 社区地图", "◎ Database"), !_accountOpen, delegate { _accountOpen = false; }); num += 50f; DrawNavButton(new Rect(((Rect)(ref val)).x + 22f, num, ((Rect)(ref val)).width - 44f, 42f), T("⚙ 设置", "⚙ Settings"), selected: false, OpenAccountWebsite); if (GUI.Button(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).yMax - 84f, ((Rect)(ref val)).width - 44f, 40f), T("上传地图", "Upload Map"), _primaryButtonStyle)) { OpenUpload(); } if (_api.IsSignedIn && GUI.Button(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).yMax - 38f, ((Rect)(ref val)).width - 44f, 30f), T("退出登录", "Logout"), _buttonStyle)) { _accountOpen = false; _api.SignOut(delegate(bool serverRevoked, string error) { _status = (string.IsNullOrEmpty(error) ? T("已退出登录", "Signed out") : T("已退出本地登录,但服务端撤销失败", "Signed out locally, but server revocation failed")); ShowToast(_status); FetchMaps(); }); } } private void DrawNavButton(Rect rect, string label, bool selected, Action clicked) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (GUI.Button(rect, label, selected ? _sidebarSelectedStyle : _sidebarButtonStyle)) { clicked(); } } private void DrawFooter() { //IL_0034: 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_00af: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).x, ((Rect)(ref _windowRect)).yMax - 28f, ((Rect)(ref _windowRect)).width, 28f); GUI.Box(val, GUIContent.none, _panelStrongStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 16f, ((Rect)(ref val)).y + 7f, 360f, 16f), T("● 在线 © 2024 PEAK 地图库", "● ONLINE © 2024 PEAK MAP DATABASE"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref val)).xMax - 360f, ((Rect)(ref val)).y + 7f, 340f, 16f), "API: peakmap.top", _mutedStyle); } private void DrawContent() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) Rect rect = default(Rect); ((Rect)(ref rect))..ctor(((Rect)(ref _windowRect)).x + 248f, ((Rect)(ref _windowRect)).y + 84f, ((Rect)(ref _windowRect)).width - 270f, ((Rect)(ref _windowRect)).height - 128f); DrawMapList(rect); } private void DrawMapList(Rect rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) GUI.Box(rect, GUIContent.none, _panelStyle); string text = ((_pagination != null) ? _pagination.total.ToString() : ((_maps != null) ? _maps.Count.ToString() : "0")); GUI.Label(new Rect(((Rect)(ref rect)).x + 18f, ((Rect)(ref rect)).y + 16f, 260f, 16f), T("共 " + text + " 张地图", "TOTAL " + text + " MAPS FOUND"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref rect)).x + 18f, ((Rect)(ref rect)).y + 32f, 260f, 34f), T("社区地图", "Community Maps"), _titleStyle); GUI.Label(new Rect(((Rect)(ref rect)).xMax - 142f, ((Rect)(ref rect)).y + 18f, 124f, 26f), "API: peakmap.top", _apiBadgeStyle); float num = ((Rect)(ref rect)).y + 72f; float num2 = 8f; float num3 = Mathf.Max(180f, ((Rect)(ref rect)).width - 36f - 96f - 92f - 104f - num2 * 3f); GUI.SetNextControlName("PeakMapSearch"); string text2 = GUI.TextField(new Rect(((Rect)(ref rect)).x + 18f, num, num3, 34f), _query, _inputStyle); if (text2 != _query) { _query = text2; } float num4 = ((Rect)(ref rect)).x + 18f + num3 + num2; if (GUI.Button(new Rect(num4, num, 96f, 34f), ShortVersion(_versionFilter), _buttonStyle)) { CycleVersionFilter(); } num4 += 96f + num2; if (GUI.Button(new Rect(num4, num, 92f, 34f), (_sort == "downloads") ? T("下载量", "Popular") : T("最新", "Newest"), _buttonStyle)) { _sort = ((_sort == "downloads") ? "newest" : "downloads"); _page = 1; FetchMaps(); } num4 += 92f + num2; if (GUI.Button(new Rect(num4, num, 104f, 34f), T("搜索", "Search"), _primaryButtonStyle)) { _page = 1; FetchMaps(); } Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 18f, ((Rect)(ref rect)).y + 118f, ((Rect)(ref rect)).width - 36f, ((Rect)(ref rect)).height - 174f); if (_loadingMaps) { GUI.Label(val, T("正在从 peakmap.top 获取地图列表...", "Fetching maps from peakmap.top..."), _labelStyle); } else if (_maps == null || _maps.Count == 0) { GUI.Label(val, string.IsNullOrEmpty(_query) ? T("暂无地图。", "No maps yet.") : T("没有找到匹配的地图。", "No matching maps found."), _labelStyle); } else { DrawCards(val); } DrawPagination(new Rect(((Rect)(ref rect)).x + 18f, ((Rect)(ref rect)).yMax - 46f, ((Rect)(ref rect)).width - 36f, 34f)); } private void DrawCards(Rect rect) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) int num = ((!(((Rect)(ref rect)).width > 560f)) ? 1 : 2); float num2 = 14f; float num3 = (((Rect)(ref rect)).width - (float)(num - 1) * num2 - 10f) / (float)num; float num4 = 290f; int num5 = Mathf.CeilToInt((float)_maps.Count / (float)num); Rect val = default(Rect); ((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref rect)).width - 18f, (float)num5 * (num4 + num2)); _mapScroll = GUI.BeginScrollView(rect, _mapScroll, val, false, true); Rect rect2 = default(Rect); for (int i = 0; i < _maps.Count; i++) { int num6 = i % num; int num7 = i / num; ((Rect)(ref rect2))..ctor((float)num6 * (num3 + num2), (float)num7 * (num4 + num2), num3, num4); DrawCard(rect2, i, _maps[i]); } GUI.EndScrollView(); } private void DrawCard(Rect rect, int index, MapEntry map) { //IL_000b: 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) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) bool flag = index == _selectedMapIndex; GUI.Box(rect, GUIContent.none, _cardStyle); if (flag) { DrawCardSelectionOutline(rect); } Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 1f, ((Rect)(ref rect)).y + 1f, ((Rect)(ref rect)).width - 2f, ((Rect)(ref rect)).height - 2f); Rect rect2 = default(Rect); ((Rect)(ref rect2))..ctor(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, 130f); DrawThumbnail(rect2, map); GUI.Label(new Rect(((Rect)(ref rect2)).x + 10f, ((Rect)(ref rect2)).y + 10f, 86f, 22f), ShortVersion(map.mod_version), _badgeStyle); if (map.revision > 1) { GUI.Label(new Rect(((Rect)(ref rect2)).xMax - 78f, ((Rect)(ref rect2)).y + 10f, 66f, 22f), "v" + map.revision, _badgeStyle); } float num = ((Rect)(ref val)).y + 146f; GUI.Label(new Rect(((Rect)(ref val)).x + 14f, num, ((Rect)(ref val)).width - 28f, 30f), CleanUiText(Safe(map.name, T("未命名地图", "Untitled map"))), _h2Style); GUI.Label(new Rect(((Rect)(ref val)).x + 14f, num + 34f, ((Rect)(ref val)).width - 28f, 18f), "♙ " + CleanUiText(Safe(map.author, T("未知", "Unknown"))), _mutedStyle); float num2 = ((Rect)(ref val)).yMax - 42f; float num3 = Mathf.Max(28f, num2 - (num + 58f) - 6f); string text = CompactCardDescription(CleanUiText(Safe(map.description, T("没有描述", "No description"))), ((Rect)(ref val)).width - 28f); GUI.Label(new Rect(((Rect)(ref val)).x + 14f, num + 58f, ((Rect)(ref val)).width - 28f, num3), text, _cardDescStyle); string text2 = T("下载 " + map.downloads + " 点赞 " + map.likes, "Downloads " + map.downloads + " Likes " + map.likes); GUI.Label(new Rect(((Rect)(ref val)).x + 14f, num2, ((Rect)(ref val)).width - 104f, 26f), text2, _cardStatsStyle); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).xMax - 82f, ((Rect)(ref val)).yMax - 46f, 68f, 34f); if (GUI.Button(val2, DownloadButtonLabel(map), _primaryButtonStyle)) { SelectMap(index); DownloadSelected(); } if (GUI.enabled && (int)Event.current.type == 0 && ((Rect)(ref rect)).Contains(Event.current.mousePosition) && !((Rect)(ref val2)).Contains(Event.current.mousePosition)) { SelectMap(index); _communityDetailOpen = true; BlockTopLayerInputThisFrame(); Event.current.Use(); } } private void DrawCardSelectionOutline(Rect rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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) //IL_00da: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = new Color(0.2f, 0.86f, 0.46f, 1f); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, 2f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - 2f, ((Rect)(ref rect)).width, 2f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, 2f, ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 2f, ((Rect)(ref rect)).y, 2f, ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; } private void DrawThumbnail(Rect rect, MapEntry map) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) DrawThumbnail(rect, map, (ScaleMode)1); } private void DrawThumbnail(Rect rect, MapEntry map, ScaleMode scaleMode) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) Texture2D thumbnail = GetThumbnail(map); GUI.DrawTexture(rect, (Texture)(object)(((Object)(object)thumbnail != (Object)null) ? thumbnail : _placeholderThumb), scaleMode); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.2f); GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(0f, 0f, 0f, 0.5f); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - 34f, ((Rect)(ref rect)).width, 34f), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; } private Texture2D GetThumbnail(MapEntry map) { string url = ((!string.IsNullOrEmpty(map.thumbnail_url)) ? map.thumbnail_url : map.image_url); if (string.IsNullOrEmpty(url)) { return _placeholderThumb; } if (_thumbnails.TryGetValue(url, out var value)) { return ((Object)(object)value != (Object)null) ? value : _placeholderThumb; } _thumbnails[url] = null; _api.DownloadTexture(url, delegate(Texture2D loaded) { if ((Object)(object)loaded != (Object)null) { _thumbnails[url] = loaded; } }); return _placeholderThumb; } private void DrawDetail(Rect rect) { //IL_0001: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: 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_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) GUI.Box(rect, GUIContent.none, _panelStyle); MapEntry selectedMap = SelectedMap; if (selectedMap == null) { GUI.Label(new Rect(((Rect)(ref rect)).x + 16f, ((Rect)(ref rect)).y + 16f, ((Rect)(ref rect)).width - 32f, 40f), T("选择一张地图查看详情", "Select a map to view details"), _labelStyle); return; } Rect rect2 = default(Rect); ((Rect)(ref rect2))..ctor(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 14f, ((Rect)(ref rect)).width - 28f, 150f); DrawThumbnail(rect2, selectedMap); GUI.Label(new Rect(((Rect)(ref rect2)).x + 12f, ((Rect)(ref rect2)).yMax - 58f, ((Rect)(ref rect2)).width - 24f, 16f), T("当前地图", "SELECTED MAP"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref rect2)).x + 12f, ((Rect)(ref rect2)).yMax - 40f, ((Rect)(ref rect2)).width - 24f, 34f), CleanUiText(Safe(selectedMap.name, T("未命名地图", "Untitled map"))), _detailTitleStyle); float num = ((Rect)(ref rect2)).yMax + 16f; DrawDetailMeta(new Rect(((Rect)(ref rect)).x + 14f, num, ((Rect)(ref rect)).width - 28f, 88f), selectedMap); num += 102f; GUI.Label(new Rect(((Rect)(ref rect)).x + 16f, num, ((Rect)(ref rect)).width - 32f, 18f), T("描述", "DESCRIPTION"), _tinyStyle); num += 24f; float num2 = ((Rect)(ref rect)).yMax - 48f; Rect rect3 = default(Rect); ((Rect)(ref rect3))..ctor(((Rect)(ref rect)).x + 14f, num, ((Rect)(ref rect)).width - 28f, Mathf.Max(110f, num2 - num - 12f)); DrawScrollableDescription(rect3, FormatDetailDescription(CleanUiText(Safe(selectedMap.description, T("没有描述", "No description"))))); float num3 = 8f; float num4 = (((Rect)(ref rect)).width - 32f - num3 * 2f) / 3f; GUI.enabled = !_downloading; if (GUI.Button(new Rect(((Rect)(ref rect)).x + 16f, num2, num4, 36f), _downloading ? T("下载中", "Loading") : DownloadButtonLabel(selectedMap), _primaryButtonStyle)) { DownloadSelected(); } GUI.enabled = true; GUI.enabled = !_liking; if (GUI.Button(new Rect(((Rect)(ref rect)).x + 16f + num4 + num3, num2, num4, 36f), selectedMap.liked_by_me ? T("已赞", "Liked") : T("点赞", "Like"), _buttonStyle)) { ToggleLikeSelected(); } GUI.enabled = true; if (GUI.Button(new Rect(((Rect)(ref rect)).x + 16f + (num4 + num3) * 2f, num2, num4, 36f), T("刷新", "Refresh"), _buttonStyle)) { RefreshAll(); } } private void DrawCommunityDetailModal() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: 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_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_058b: Unknown result type (might be due to invalid IL or missing references) MapEntry selectedMap = SelectedMap; if (selectedMap == null) { _communityDetailOpen = false; return; } GUI.depth = -101; GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), GUIContent.none, _modalBackdropStyle); float num = Mathf.Min(820f, (float)Screen.width - 32f); float num2 = Mathf.Min(680f, (float)Screen.height - 26f); Rect val = default(Rect); ((Rect)(ref val))..ctor(Mathf.Round(((float)Screen.width - num) * 0.5f), Mathf.Round(((float)Screen.height - num2) * 0.5f), num, num2); GUI.Box(val, GUIContent.none, _rootStyle); Rect rect = default(Rect); ((Rect)(ref rect))..ctor(((Rect)(ref val)).x + 14f, ((Rect)(ref val)).y + 14f, ((Rect)(ref val)).width - 28f, 238f); DrawThumbnail(rect, selectedMap, (ScaleMode)2); GUI.Label(new Rect(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 12f, 118f, 24f), ShortVersion(selectedMap.mod_version), _badgeStyle); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 52f, ((Rect)(ref val)).y + 18f, 34f, 34f), "×", _iconButtonStyle)) { _communityDetailOpen = false; } float num3 = ((Rect)(ref rect)).yMax + 16f; GUI.Label(new Rect(((Rect)(ref val)).x + 24f, num3, ((Rect)(ref val)).width - 48f, 38f), CleanUiText(Safe(selectedMap.name, T("未命名地图", "Untitled map"))), _titleStyle); num3 += 48f; float num4 = 10f; float num5 = (((Rect)(ref val)).width - 48f - num4 * 3f) / 4f; DrawStatBox(new Rect(((Rect)(ref val)).x + 24f, num3, num5, 64f), T("作者", "AUTHOR"), CleanUiText(Safe(selectedMap.author, T("未知", "Unknown")))); DrawStatBox(new Rect(((Rect)(ref val)).x + 24f + num5 + num4, num3, num5, 64f), T("MOD 版本", "MOD VERSION"), CleanUiText(Safe(selectedMap.mod_version, "-"))); DrawStatBox(new Rect(((Rect)(ref val)).x + 24f + (num5 + num4) * 2f, num3, num5, 64f), T("下载次数", "DOWNLOADS"), selectedMap.downloads.ToString()); DrawStatBox(new Rect(((Rect)(ref val)).x + 24f + (num5 + num4) * 3f, num3, num5, 64f), T("点赞", "LIKES"), selectedMap.likes.ToString()); num3 += 78f; GUI.Label(new Rect(((Rect)(ref val)).x + 24f, num3, ((Rect)(ref val)).width - 48f, 20f), T("上传时间:", "Uploaded: ") + DateOnly(Safe(selectedMap.updated_at, selectedMap.created_at)), _mutedStyle); num3 += 28f; GUI.Label(new Rect(((Rect)(ref val)).x + 24f, num3, ((Rect)(ref val)).width - 48f, 20f), T("介绍", "DESCRIPTION"), _tinyStyle); num3 += 26f; float num6 = ((Rect)(ref val)).yMax - 58f; Rect rect2 = default(Rect); ((Rect)(ref rect2))..ctor(((Rect)(ref val)).x + 24f, num3, ((Rect)(ref val)).width - 48f, Mathf.Max(80f, num6 - num3 - 12f)); DrawScrollableDescription(rect2, FormatDetailDescription(CleanUiText(Safe(selectedMap.description, T("没有描述", "No description"))))); bool enabled = GUI.enabled; GUI.enabled = enabled && !_downloading; if (GUI.Button(new Rect(((Rect)(ref val)).x + 24f, num6, 108f, 38f), _downloading ? T("下载中", "Loading") : DownloadButtonLabel(selectedMap), _primaryButtonStyle)) { DownloadSelected(); } GUI.enabled = enabled && !_liking; if (GUI.Button(new Rect(((Rect)(ref val)).x + 144f, num6, 108f, 38f), selectedMap.liked_by_me ? T("已赞", "Liked") : T("点赞", "Like"), _buttonStyle)) { ToggleLikeSelected(); } GUI.enabled = enabled; if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 132f, num6, 108f, 38f), T("关闭", "Close"), _buttonStyle)) { _communityDetailOpen = false; } GUI.enabled = enabled; } private void DrawDetailMeta(Rect rect, MapEntry map) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) float num = 10f; float num2 = (((Rect)(ref rect)).width - num) * 0.5f; DrawStatBox(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, num2, 52f), T("作者", "AUTHOR"), CleanUiText(Safe(map.author, "Unknown"))); DrawStatBox(new Rect(((Rect)(ref rect)).x + num2 + num, ((Rect)(ref rect)).y, num2, 52f), T("版本", "VERSION"), CleanUiText(Safe(map.mod_version, "-")) + ((map.revision > 1) ? (" · v" + map.revision) : "")); string text = T("下载 ", "Downloads ") + map.downloads + " " + T("点赞 ", "Likes ") + map.likes + " " + DateOnly(Safe(map.updated_at, map.created_at)); GUI.Label(new Rect(((Rect)(ref rect)).x + 2f, ((Rect)(ref rect)).y + 62f, ((Rect)(ref rect)).width - 4f, 22f), text, _mutedStyle); } private void DrawStatBox(Rect rect, string label, string value) { //IL_0001: 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) //IL_008f: Unknown result type (might be due to invalid IL or missing references) GUI.Box(rect, GUIContent.none, _statBoxStyle); GUI.Label(new Rect(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 6f, ((Rect)(ref rect)).width - 20f, 20f), label, _statLabelStyle); GUI.Label(new Rect(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 25f, ((Rect)(ref rect)).width - 20f, Mathf.Max(18f, ((Rect)(ref rect)).height - 29f)), value, _statValueStyle); } private void DrawScrollableDescription(Rect rect, string text) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) GUI.Box(rect, GUIContent.none, _detailDescriptionStyle); string text2 = (string.IsNullOrEmpty(text) ? T("没有描述", "No description") : text); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 12f, ((Rect)(ref rect)).y + 12f, ((Rect)(ref rect)).width - 24f, ((Rect)(ref rect)).height - 24f); float num = ((Rect)(ref val)).width - 18f; float num2 = Mathf.Max(((Rect)(ref val)).height, _detailTextStyle.CalcHeight(new GUIContent(text2), num) + 12f); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, num, num2 + 10f); _detailScroll = GUI.BeginScrollView(val, _detailScroll, val2, false, true); GUI.Label(new Rect(0f, 0f, num, num2), text2, _detailTextStyle); GUI.EndScrollView(); } private void DrawPagination(Rect rect) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) bool enabled = GUI.enabled; GUI.enabled = _pagination != null && _pagination.has_prev && !_loadingMaps; if (GUI.Button(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, 34f, 32f), "‹", _buttonStyle)) { _page = Mathf.Max(1, _page - 1); FetchMaps(); } GUI.enabled = enabled; GUI.Label(new Rect(((Rect)(ref rect)).x + 42f, ((Rect)(ref rect)).y, 54f, 32f), _page.ToString(), _pagePillStyle); GUI.enabled = _pagination != null && _pagination.has_next && !_loadingMaps; if (GUI.Button(new Rect(((Rect)(ref rect)).x + 104f, ((Rect)(ref rect)).y, 34f, 32f), "›", _buttonStyle)) { _page++; FetchMaps(); } GUI.enabled = enabled; string text = ((_pagination != null) ? (T("第 ", "Page ") + _pagination.page + " / " + Mathf.Max(1, _pagination.total_pages) + T(" 页", "")) : (T("第 ", "Page ") + _page + T(" 页", ""))); GUI.Label(new Rect(((Rect)(ref rect)).xMax - 110f, ((Rect)(ref rect)).y + 7f, 110f, 22f), text, _mutedStyle); } private void DrawLoginModal() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_0238: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) GUI.depth = -101; GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), GUIContent.none, _modalBackdropStyle); Rect val = default(Rect); ((Rect)(ref val))..ctor(Mathf.Round(((float)Screen.width - 460f) * 0.5f), Mathf.Round(((float)Screen.height - 330f) * 0.5f), 460f, 330f); GUI.Box(val, GUIContent.none, _rootStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 16f, 220f, 16f), T("PEAKMAP 账号", "PEAKMAP ACCOUNT"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 32f, 220f, 34f), T("登录账号", "Sign in"), _titleStyle); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 54f, ((Rect)(ref val)).y + 22f, 36f, 36f), "×", _iconButtonStyle)) { _loginOpen = false; } float num = ((Rect)(ref val)).x + 24f; float num2 = ((Rect)(ref val)).y + 90f; DrawFieldLabel(num, num2, T("邮箱", "Email")); _loginEmail = GUI.TextField(new Rect(num, num2 + 20f, ((Rect)(ref val)).width - 48f, 38f), _loginEmail, _inputStyle); num2 += 72f; DrawFieldLabel(num, num2, T("密码", "Password")); _loginPassword = GUI.PasswordField(new Rect(num, num2 + 20f, ((Rect)(ref val)).width - 48f, 38f), _loginPassword, '*', _inputStyle); num2 += 70f; GUI.Label(new Rect(num, num2, ((Rect)(ref val)).width - 48f, 24f), _status, _mutedStyle); bool enabled = GUI.enabled; GUI.enabled = enabled && !_refreshingSession; if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 196f, ((Rect)(ref val)).yMax - 58f, 82f, 38f), T("网页注册", "Account"), _buttonStyle)) { OpenAccountWebsite(); } if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 104f, ((Rect)(ref val)).yMax - 58f, 86f, 38f), T("登录", "Sign in"), _primaryButtonStyle)) { SignInSelected(); } GUI.enabled = enabled; } private void DrawAccountPage() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) Rect modal = default(Rect); ((Rect)(ref modal))..ctor(((Rect)(ref _windowRect)).x + 248f, ((Rect)(ref _windowRect)).y + 84f, ((Rect)(ref _windowRect)).width - 270f, ((Rect)(ref _windowRect)).height - 128f); GUI.Label(new Rect(((Rect)(ref modal)).x, ((Rect)(ref modal)).y, 260f, 16f), T("我的地图 (" + _accountMaps.Count + ")", "ACTIVE REPOSITORIES (" + _accountMaps.Count + ")"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref modal)).x, ((Rect)(ref modal)).y + 18f, 260f, 34f), T("我的地图", "My Maps"), _titleStyle); GUI.Label(new Rect(((Rect)(ref modal)).x + 270f, ((Rect)(ref modal)).y + 24f, 300f, 22f), T("登录账号:", "Logged in as ") + ShortAccountName(_api.Session.DisplayName), _mutedStyle); if (GUI.Button(new Rect(((Rect)(ref modal)).xMax - 246f, ((Rect)(ref modal)).y + 8f, 72f, 34f), T("刷新", "Refresh"), _buttonStyle)) { FetchAccountMaps(); } if (GUI.Button(new Rect(((Rect)(ref modal)).xMax - 166f, ((Rect)(ref modal)).y + 8f, 72f, 34f), T("退出", "Sign out"), _buttonStyle)) { _accountOpen = false; _api.SignOut(delegate(bool serverRevoked, string error) { _status = (string.IsNullOrEmpty(error) ? T("已退出登录", "Signed out") : T("已退出本地登录,但服务端撤销失败", "Signed out locally, but server revocation failed")); ShowToast(_status); FetchMaps(); }); } if (GUI.Button(new Rect(((Rect)(ref modal)).xMax - 86f, ((Rect)(ref modal)).y + 8f, 34f, 34f), "↗", _iconButtonStyle)) { OpenAccountWebsite(); } if (GUI.Button(new Rect(((Rect)(ref modal)).xMax - 44f, ((Rect)(ref modal)).y + 8f, 34f, 34f), "×", _iconButtonStyle)) { _accountOpen = false; } if (Time.unscaledTime >= _nextLocalSaveScanTime) { RefreshLocalSaves(); } Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref modal)).x, ((Rect)(ref modal)).y + 66f, Mathf.Min(320f, ((Rect)(ref modal)).width * 0.36f), ((Rect)(ref modal)).height - 118f); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).xMax + 18f, ((Rect)(ref val)).y, ((Rect)(ref modal)).xMax - ((Rect)(ref val)).xMax - 18f, ((Rect)(ref val)).height); GUI.Box(val, GUIContent.none, _panelStrongStyle); DrawAccountMapList(val); GUI.Box(val2, GUIContent.none, _panelStrongStyle); DrawAccountEditor(val2); GUI.Label(new Rect(((Rect)(ref modal)).x, ((Rect)(ref modal)).yMax - 36f, ((Rect)(ref modal)).width - 260f, 24f), _status, _mutedStyle); MapEntry selectedAccountMap = SelectedAccountMap; bool enabled = GUI.enabled; GUI.enabled = enabled && selectedAccountMap != null && !_savingAccountMap && !_deletingAccountMap && !_accountVersionDropdownOpen && !_accountJsonDropdownOpen; if (GUI.Button(new Rect(((Rect)(ref modal)).xMax - 214f, ((Rect)(ref modal)).yMax - 44f, 72f, 38f), T("删除", "Delete"), _buttonStyle)) { _deleteConfirmMapId = selectedAccountMap.id; } if (GUI.Button(new Rect(((Rect)(ref modal)).xMax - 132f, ((Rect)(ref modal)).yMax - 44f, 132f, 38f), _savingAccountMap ? T("保存中", "Saving") : T("保存修改", "Save"), _primaryButtonStyle)) { SaveAccountMap(); } GUI.enabled = enabled; if (selectedAccountMap != null && string.Equals(_deleteConfirmMapId, selectedAccountMap.id, StringComparison.Ordinal)) { DrawDeleteConfirm(modal, selectedAccountMap); } } private void DrawAccountMapList(Rect rect) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00d6: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 10f, ((Rect)(ref rect)).width - 20f, ((Rect)(ref rect)).height - 20f); if (_loadingAccountMaps) { GUI.Label(val, T("正在获取我的地图...", "Loading my maps..."), _mutedStyle); return; } if (_accountMaps.Count == 0) { GUI.Label(val, T("当前账号还没有地图。登录后上传的地图会出现在这里。", "This account has no maps yet. Maps uploaded while signed in appear here."), _mutedStyle); return; } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width - 18f, (float)_accountMaps.Count * 54f); _accountScroll = GUI.BeginScrollView(val, _accountScroll, val2, false, true); for (int i = 0; i < _accountMaps.Count; i++) { MapEntry mapEntry = _accountMaps[i]; GUIStyle val3 = ((i == _selectedAccountMapIndex) ? _primaryButtonStyle : _buttonStyle); string text = CleanUiText(Safe(mapEntry.name, T("未命名地图", "Untitled map"))) + "\n" + ShortVersion(mapEntry.mod_version) + " · ♥ " + mapEntry.likes + " · ↓ " + mapEntry.downloads; if (GUI.Button(new Rect(0f, (float)i * 54f, ((Rect)(ref val2)).width, 50f), text, val3)) { SelectAccountMap(i); } } GUI.EndScrollView(); } private void DrawAccountEditor(Rect rect) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: 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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Expected O, but got Unknown //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0412: 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_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_0670: Unknown result type (might be due to invalid IL or missing references) //IL_06b1: Unknown result type (might be due to invalid IL or missing references) //IL_06f3: Unknown result type (might be due to invalid IL or missing references) //IL_0738: Unknown result type (might be due to invalid IL or missing references) MapEntry selectedAccountMap = SelectedAccountMap; if (selectedAccountMap == null) { GUI.Label(new Rect(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 14f, ((Rect)(ref rect)).width - 28f, 60f), T("选择一张自己的地图进行编辑。", "Select one of your maps to edit."), _mutedStyle); return; } float num = ((Rect)(ref rect)).x + 14f; float num2 = ((Rect)(ref rect)).y + 12f; float num3 = ((Rect)(ref rect)).width - 28f; DrawFieldLabel(num, num2, T("地图名称", "Map name")); _editName = GUI.TextField(new Rect(num, num2 + 20f, num3, 34f), _editName, _inputStyle); num2 += 60f; DrawFieldLabel(num, num2, T("作者", "Author")); _editAuthor = GUI.TextField(new Rect(num, num2 + 20f, (num3 - 12f) * 0.5f, 34f), _editAuthor, _inputStyle); float num4 = num + (num3 + 12f) * 0.5f; float num5 = (num3 - 12f) * 0.5f; Rect val = default(Rect); ((Rect)(ref val))..ctor(num4, num2 + 20f, num5, 34f); Rect val2 = (Rect)(_accountVersionDropdownOpen ? new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).yMax + 4f, ((Rect)(ref val)).width, Mathf.Min(150f, Mathf.Max(38f, (float)_versions.Count * 30f + 10f))) : Rect.zero); if (_accountVersionDropdownOpen) { ConsumeAccountVersionDropdownOutsideClick(val, val2); } DrawFieldLabel(num4, num2, T("MOD 版本", "MOD version")); string text = (string.IsNullOrEmpty(_editVersion) ? T("选择版本 ▾", "Select version ▾") : (_editVersion + " ▾")); if (GUI.Button(val, text, _buttonStyle)) { _accountVersionDropdownOpen = !_accountVersionDropdownOpen; _accountJsonDropdownOpen = false; if (_accountVersionDropdownOpen) { if (_versions.Count == 0) { FetchModVersions(); } BlockTopLayerInputThisFrame(); } } bool enabled = GUI.enabled; GUI.enabled = enabled && !_accountVersionDropdownOpen; num2 += 60f; DrawFieldLabel(num, num2, T("描述", "Description")); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(num, num2 + 20f, num3, 112f); GUI.Box(val3, GUIContent.none, _detailMetaStyle); Rect val4 = default(Rect); ((Rect)(ref val4))..ctor(((Rect)(ref val3)).x + 8f, ((Rect)(ref val3)).y + 8f, ((Rect)(ref val3)).width - 16f, ((Rect)(ref val3)).height - 16f); float num6 = ((Rect)(ref val4)).width - 18f; float num7 = Mathf.Max(((Rect)(ref val4)).height, _textAreaStyle.CalcHeight(new GUIContent(_editDescription + "\n "), num6) + 18f); Rect val5 = default(Rect); ((Rect)(ref val5))..ctor(0f, 0f, num6, num7); _accountDescriptionScroll = GUI.BeginScrollView(val4, _accountDescriptionScroll, val5, false, true); _editDescription = GUI.TextArea(new Rect(0f, 0f, num6, num7), _editDescription, _textAreaStyle); GUI.EndScrollView(); num2 += 140f; GUI.Label(new Rect(num, num2, num3, 18f), T("替换 JSON", "REPLACE JSON"), _tinyStyle); num2 += 22f; Rect val6 = default(Rect); ((Rect)(ref val6))..ctor(num, num2, num3, 42f); Rect val7 = (Rect)(_accountJsonDropdownOpen ? new Rect(((Rect)(ref val6)).x, ((Rect)(ref val6)).yMax + 4f, ((Rect)(ref val6)).width, Mathf.Min(150f, Mathf.Max(42f, (float)_filteredLocalSaveIndexes.Count * 30f + 12f))) : Rect.zero); if (_accountJsonDropdownOpen) { ConsumeAccountJsonDropdownOutsideClick(val6, val7); } GUI.Box(val6, GUIContent.none, _detailMetaStyle); string text2 = ((_editReplaceJson && SelectedLocalSavePath != null) ? MapSaveService.DisplayName(SelectedLocalSavePath) : T("不替换 JSON", "Keep current JSON")); if (GUI.Button(new Rect(((Rect)(ref val6)).x + 8f, ((Rect)(ref val6)).y + 6f, ((Rect)(ref val6)).width - 78f, 30f), text2 + " ▾", _buttonStyle)) { _accountJsonDropdownOpen = !_accountJsonDropdownOpen; if (_accountJsonDropdownOpen) { RefreshLocalSaves(); BlockTopLayerInputThisFrame(); } } if (GUI.Button(new Rect(((Rect)(ref val6)).xMax - 62f, ((Rect)(ref val6)).y + 6f, 54f, 30f), T("清除", "Clear"), _buttonStyle)) { _editReplaceJson = false; _accountJsonDropdownOpen = false; } if (_accountJsonDropdownOpen) { DrawAccountJsonDropdown(val7); } num2 = (_accountJsonDropdownOpen ? ((Rect)(ref val7)).yMax : ((Rect)(ref val6)).yMax) + 12f; _editReplaceImage = GUI.Toggle(new Rect(num, num2, num3, 22f), _editReplaceImage, T("替换封面:", "Replace cover: ") + ((SelectedLocalImagePath == null) ? T("未选择", "none") : MapSaveService.DisplayName(SelectedLocalImagePath))); num2 += 24f; _editRemoveImage = GUI.Toggle(new Rect(num, num2, num3, 22f), _editRemoveImage, T("移除当前封面", "Remove current cover")); num2 += 28f; if (GUI.Button(new Rect(num, num2, 86f, 32f), T("选封面", "Pick"), _buttonStyle)) { OpenImagePicker(); } if (GUI.Button(new Rect(num + 94f, num2, 86f, 32f), T("自动匹配", "Auto"), _buttonStyle)) { AutoSelectMatchingImage(showToast: true); } if (GUI.Button(new Rect(num + 188f, num2, 86f, 32f), T("清除", "Clear"), _buttonStyle)) { _selectedLocalImage = -1; } GUI.enabled = enabled; if (_accountVersionDropdownOpen) { DrawAccountVersionDropdown(val2); } } private void DrawDeleteConfirm(Rect modal, MapEntry map) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref modal)).x + 180f, ((Rect)(ref modal)).y + 210f, ((Rect)(ref modal)).width - 360f, 170f); GUI.Box(val, GUIContent.none, _rootStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 18f, ((Rect)(ref val)).width - 36f, 48f), T("确定删除这张地图?此操作不可恢复。", "Delete this map? This cannot be undone."), _dangerStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 70f, ((Rect)(ref val)).width - 36f, 28f), CleanUiText(Safe(map.name, "-")), _labelStyle); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 188f, ((Rect)(ref val)).yMax - 52f, 78f, 34f), T("取消", "Cancel"), _buttonStyle)) { _deleteConfirmMapId = string.Empty; } if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 100f, ((Rect)(ref val)).yMax - 52f, 82f, 34f), T("删除", "Delete"), _primaryButtonStyle)) { DeleteAccountMap(map); } } private void DrawDownloadConfirmModal() { //IL_0091: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) MapEntry mapEntry = FindMapById(_downloadConfirmMapId); if (mapEntry == null) { _downloadConfirmOpen = false; _downloadConfirmMapId = string.Empty; return; } MapDownloadInfo downloadInfo = _api.GetDownloadInfo(mapEntry); if (downloadInfo.Status != MapDownloadStatus.UpdateAvailable && downloadInfo.Status != MapDownloadStatus.LocalModified) { _downloadConfirmOpen = false; _downloadConfirmMapId = string.Empty; return; } GUI.depth = -101; GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), GUIContent.none, _modalBackdropStyle); float num = Mathf.Min(560f, (float)Screen.width - 32f); float num2 = 230f; Rect val = default(Rect); ((Rect)(ref val))..ctor(Mathf.Round(((float)Screen.width - num) * 0.5f), Mathf.Round(((float)Screen.height - num2) * 0.5f), num, num2); GUI.Box(val, GUIContent.none, _rootStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).y + 20f, ((Rect)(ref val)).width - 44f, 32f), (downloadInfo.Status == MapDownloadStatus.LocalModified) ? T("本地文件已修改", "Local file was modified") : T("发现地图新版本", "New map version available"), _titleStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).y + 64f, ((Rect)(ref val)).width - 44f, 34f), CleanUiText(Safe(mapEntry.name, T("未命名地图", "Untitled map"))), _labelStyle); string text = ((downloadInfo.Status == MapDownloadStatus.LocalModified) ? T("本地 JSON 与上次下载内容不同。继续更新会覆盖当前文件,并先备份旧文件。", "The local JSON differs from the downloaded copy. Updating will replace it after backing up the old file.") : T("服务器版本 v" + downloadInfo.CurrentRevision + " 高于本地 v" + downloadInfo.LocalRevision + "。继续更新会先备份旧文件。", "Server version v" + downloadInfo.CurrentRevision + " is newer than local v" + downloadInfo.LocalRevision + ". The old file will be backed up first.")); GUI.Label(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).y + 104f, ((Rect)(ref val)).width - 44f, 52f), text, _mutedStyle); bool enabled = GUI.enabled; GUI.enabled = enabled && !_downloading; if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 194f, ((Rect)(ref val)).yMax - 52f, 82f, 34f), T("取消", "Cancel"), _buttonStyle)) { _downloadConfirmOpen = false; _downloadConfirmMapId = string.Empty; } if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 102f, ((Rect)(ref val)).yMax - 52f, 84f, 34f), _downloading ? T("更新中", "Updating") : T("确认更新", "Update"), _primaryButtonStyle)) { _downloadConfirmOpen = false; _downloadConfirmMapId = string.Empty; StartDownload(mapEntry, allowOverwriteLocalChanges: true); } GUI.enabled = enabled; } private void ConsumeAccountJsonDropdownOutsideClick(Rect rowRect, Rect dropdownRect) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) Event current = Event.current; if (current != null && (int)current.type <= 0 && !((Rect)(ref rowRect)).Contains(current.mousePosition) && !((Rect)(ref dropdownRect)).Contains(current.mousePosition)) { _accountJsonDropdownOpen = false; GUI.FocusControl((string)null); current.Use(); } } private void DrawAccountJsonDropdown(Rect rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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) GUI.Box(rect, GUIContent.none, _panelStrongStyle); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 8f, ((Rect)(ref rect)).y + 8f, ((Rect)(ref rect)).width - 16f, 30f); string text = GUI.TextField(val, _localSaveFilter, _inputStyle); if (!string.Equals(text, _localSaveFilter, StringComparison.Ordinal)) { _localSaveFilter = text; ApplyLocalSaveFilter(resetScroll: true); } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x + 8f, ((Rect)(ref val)).yMax + 6f, ((Rect)(ref rect)).width - 16f, ((Rect)(ref rect)).height - 50f); if (_filteredLocalSaveIndexes.Count == 0) { GUI.Label(val2, T("没有可用的 JSON。", "No JSON files available."), _mutedStyle); return; } Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val2)).width - 18f, (float)_filteredLocalSaveIndexes.Count * 30f); _uploadSaveScroll = GUI.BeginScrollView(val2, _uploadSaveScroll, val3, false, true); int num = Mathf.Max(0, Mathf.FloorToInt(_uploadSaveScroll.y / 30f) - 1); int num2 = Mathf.Min(_filteredLocalSaveIndexes.Count, num + Mathf.CeilToInt(((Rect)(ref val2)).height / 30f) + 2); for (int i = num; i < num2; i++) { int num3 = _filteredLocalSaveIndexes[i]; GUIStyle val4 = ((num3 == _selectedLocalSave) ? _primaryButtonStyle : _buttonStyle); if (GUI.Button(new Rect(0f, (float)i * 30f, ((Rect)(ref val3)).width, 27f), MapSaveService.DisplayName(_localSaves[num3]), val4)) { _selectedLocalSave = num3; _editReplaceJson = true; _accountJsonDropdownOpen = false; _log.LogInfo((object)("JSON selected from account editor: " + _localSaves[num3])); } } GUI.EndScrollView(); } private void ConsumeAccountVersionDropdownOutsideClick(Rect buttonRect, Rect dropdownRect) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) Event current = Event.current; if (current != null && (int)current.type <= 0 && !((Rect)(ref buttonRect)).Contains(current.mousePosition) && !((Rect)(ref dropdownRect)).Contains(current.mousePosition)) { _accountVersionDropdownOpen = false; GUI.FocusControl((string)null); current.Use(); } } private void DrawAccountVersionDropdown(Rect rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) GUI.Box(rect, GUIContent.none, _panelStrongStyle); if (_versions.Count == 0) { GUI.Label(new Rect(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 10f, ((Rect)(ref rect)).width - 20f, 22f), T("正在获取版本...", "Loading versions..."), _mutedStyle); return; } Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 6f, ((Rect)(ref rect)).y + 6f, ((Rect)(ref rect)).width - 12f, ((Rect)(ref rect)).height - 12f); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width - 18f, (float)_versions.Count * 30f); _accountVersionScroll = GUI.BeginScrollView(val, _accountVersionScroll, val2, false, true); int num = _versions.FindIndex((ModVersionEntry v) => string.Equals(v.version_name, _editVersion, StringComparison.Ordinal)); int num2 = Mathf.Max(0, Mathf.FloorToInt(_accountVersionScroll.y / 30f) - 1); int num3 = Mathf.Min(_versions.Count, num2 + Mathf.CeilToInt(((Rect)(ref val)).height / 30f) + 2); for (int num4 = num2; num4 < num3; num4++) { GUIStyle val3 = ((num4 == num) ? _primaryButtonStyle : _buttonStyle); if (GUI.Button(new Rect(0f, (float)num4 * 30f, ((Rect)(ref val2)).width, 27f), _versions[num4].version_name, val3)) { _editVersion = _versions[num4].version_name; _accountVersionDropdownOpen = false; _log.LogInfo((object)("Account map version selected: " + _editVersion)); } } GUI.EndScrollView(); } private void DrawUploadModal() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_06c5: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Unknown result type (might be due to invalid IL or missing references) //IL_07e3: Unknown result type (might be due to invalid IL or missing references) //IL_08ba: Unknown result type (might be due to invalid IL or missing references) //IL_08ee: Unknown result type (might be due to invalid IL or missing references) //IL_0943: Unknown result type (might be due to invalid IL or missing references) //IL_09b5: Unknown result type (might be due to invalid IL or missing references) //IL_0a26: Unknown result type (might be due to invalid IL or missing references) //IL_0a4f: Unknown result type (might be due to invalid IL or missing references) //IL_0a78: Unknown result type (might be due to invalid IL or missing references) GUI.depth = -101; GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), GUIContent.none, _modalBackdropStyle); float num = Mathf.Min(620f, (float)Screen.height - 48f); Rect val = default(Rect); ((Rect)(ref val))..ctor(Mathf.Round(((float)Screen.width - 680f) * 0.5f), Mathf.Round(((float)Screen.height - num) * 0.5f), 680f, Mathf.Round(num)); GUI.Box(val, GUIContent.none, _rootStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 16f, 220f, 16f), T("提交本地存档", "SUBMIT LOCAL SAVE"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 32f, 220f, 34f), T("上传地图", "Upload Map"), _titleStyle); bool enabled = GUI.enabled; GUI.enabled = enabled && !IsTopLayerInputBlocked(); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 54f, ((Rect)(ref val)).y + 22f, 36f, 36f), "×", _iconButtonStyle)) { _uploadOpen = false; } GUI.enabled = enabled; if (Time.unscaledTime >= _nextLocalSaveScanTime) { RefreshLocalSaves(); } float num2 = ((Rect)(ref val)).y + 82f; float num3 = ((Rect)(ref val)).x + 18f; float num4 = (((Rect)(ref val)).width - 54f) / 2f; Rect zero = Rect.zero; Rect zero2 = Rect.zero; Rect zero3 = Rect.zero; float num5 = num2 + 72f; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(num3, num5 + 20f, num4, 38f); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(num3 + num4 + 18f, num5 + 20f, num4 - 184f, 38f); if (_uploadVersionDropdownOpen) { ((Rect)(ref zero))..ctor(((Rect)(ref val2)).x, ((Rect)(ref val2)).yMax + 4f, ((Rect)(ref val2)).width, Mathf.Min(150f, Mathf.Max(38f, (float)_versions.Count * 30f + 10f))); } if (_uploadImageDropdownOpen) { ((Rect)(ref zero2))..ctor(((Rect)(ref val3)).x, ((Rect)(ref val3)).yMax + 4f, num4, 150f); } Rect val4 = default(Rect); ((Rect)(ref val4))..ctor(num3, ((Rect)(ref val)).y + 354f, ((Rect)(ref val)).width - 36f, 38f); if (_uploadSaveDropdownOpen) { ((Rect)(ref zero3))..ctor(((Rect)(ref val4)).x, ((Rect)(ref val4)).yMax + 4f, ((Rect)(ref val4)).width, 184f); } bool flag = _uploadVersionDropdownOpen || _uploadImageDropdownOpen || _uploadSaveDropdownOpen; bool flag2 = IsTopLayerInputBlocked(); if (flag) { Rect dropdownRect = (_uploadVersionDropdownOpen ? zero : (_uploadImageDropdownOpen ? zero2 : zero3)); ConsumeUploadDropdownOutsideClick(dropdownRect); } bool enabled2 = GUI.enabled; GUI.enabled = enabled2 && !flag && !flag2; DrawFieldLabel(num3, num2, T("地图名称", "Map name")); _uploadName = GUI.TextField(new Rect(num3, num2 + 20f, num4, 38f), _uploadName, _inputStyle); DrawFieldLabel(num3 + num4 + 18f, num2, T("作者", "Author")); _uploadAuthor = GUI.TextField(new Rect(num3 + num4 + 18f, num2 + 20f, num4, 38f), _uploadAuthor, _inputStyle); num2 += 72f; DrawFieldLabel(num3, num2, T("MOD 版本", "MOD version")); string text = ((_versions.Count > 0) ? _versions[Mathf.Clamp(_selectedUploadVersion, 0, _versions.Count - 1)].version_name : T("未获取到版本", "No versions loaded")); GUI.enabled = enabled2 && !flag && !flag2 && !_uploading && _versions.Count > 0; if (GUI.Button(val2, text + " ▾", _buttonStyle)) { bool flag3 = (_uploadVersionDropdownOpen = !_uploadVersionDropdownOpen); _uploadImageDropdownOpen = false; if (flag3) { BlockTopLayerInputThisFrame(); } } GUI.enabled = enabled2 && !flag && !flag2; DrawFieldLabel(num3 + num4 + 18f, num2, T("封面图片(可选)", "Cover image (optional)")); string text2 = (string.IsNullOrEmpty(SelectedLocalImagePath) ? T("不上传封面 ▾", "No cover ▾") : (MapSaveService.DisplayName(SelectedLocalImagePath) + " ▾")); if (GUI.Button(val3, text2, _buttonStyle)) { bool flag4 = (_uploadImageDropdownOpen = !_uploadImageDropdownOpen); _uploadVersionDropdownOpen = false; if (flag4) { BlockTopLayerInputThisFrame(); } } if (GUI.Button(new Rect(((Rect)(ref val3)).xMax + 6f, ((Rect)(ref val3)).y, 54f, 38f), T("选图", "Pick"), _buttonStyle)) { _log.LogInfo((object)"Image browser button clicked."); CloseUploadDropdowns(); OpenImagePicker(); } if (GUI.Button(new Rect(((Rect)(ref val3)).xMax + 66f, ((Rect)(ref val3)).y, 54f, 38f), T("自动", "Auto"), _buttonStyle)) { _log.LogInfo((object)("Auto image match button clicked. Json: " + (SelectedLocalSavePath ?? ""))); CloseUploadDropdowns(); AutoSelectMatchingImage(showToast: true); } if (GUI.Button(new Rect(((Rect)(ref val3)).xMax + 126f, ((Rect)(ref val3)).y, 54f, 38f), T("清空", "Clear"), _buttonStyle)) { _log.LogInfo((object)"Upload cover image cleared."); CloseUploadDropdowns(); _selectedLocalImage = -1; } num2 += 72f; DrawFieldLabel(num3, num2, T("描述", "Description")); _uploadDescription = GUI.TextArea(new Rect(num3, num2 + 20f, ((Rect)(ref val)).width - 36f, 72f), _uploadDescription, _inputStyle); num2 += 104f; DrawFieldLabel(num3, ((Rect)(ref val)).y + 324f, T("本地地图 JSON", "Local map JSON")); GUI.enabled = enabled2 && !flag2 && !_uploading; string text3 = (string.IsNullOrEmpty(SelectedLocalSavePath) ? T("选择本地 JSON ▾", "Select local JSON ▾") : (MapSaveService.DisplayName(SelectedLocalSavePath) + " ▾")); if (GUI.Button(val4, text3, _buttonStyle)) { _uploadSaveDropdownOpen = !_uploadSaveDropdownOpen; _uploadVersionDropdownOpen = false; _uploadImageDropdownOpen = false; if (_uploadSaveDropdownOpen) { RefreshLocalSaves(); BlockTopLayerInputThisFrame(); } } GUI.enabled = enabled2; string text4 = ((_localSaves.Length == 0) ? (T("未找到本地 JSON。目录:", "No local JSON found. Directory: ") + MapSaveService.SavePath) : (T("已扫描 ", "Found ") + _localSaves.Length + T(" 个 JSON,点击上方选择", " JSON files. Use the selector above"))); GUI.Label(new Rect(num3, ((Rect)(ref val4)).yMax + 6f, ((Rect)(ref val)).width - 36f, 18f), text4, _mutedStyle); GUI.Label(new Rect(num3, ((Rect)(ref val)).yMax - 66f, ((Rect)(ref val)).width - 280f, 24f), _uploading ? T("上传中,请稍候...", "Uploading, please wait...") : _status, _mutedStyle); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 186f, ((Rect)(ref val)).yMax - 58f, 76f, 38f), T("刷新", "Refresh"), _buttonStyle)) { RefreshLocalSaves(resetScroll: true); } GUI.enabled = enabled2 && !flag && !flag2 && !_uploading; if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 100f, ((Rect)(ref val)).yMax - 58f, 82f, 38f), _uploading ? T("上传中", "Uploading") : T("确认上传", "Upload"), _primaryButtonStyle)) { UploadSelected(); } GUI.enabled = enabled2; if (_uploadVersionDropdownOpen) { GUI.enabled = enabled2 && !flag2; DrawUploadVersionDropdown(zero); } if (_uploadImageDropdownOpen) { GUI.enabled = enabled2 && !flag2; DrawUploadImageDropdown(zero2); } if (_uploadSaveDropdownOpen) { GUI.enabled = enabled2 && !flag2; DrawUploadSaveDropdown(zero3); } GUI.enabled = enabled2; } private void ConsumeUploadDropdownOutsideClick(Rect dropdownRect) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) Event current = Event.current; if (current != null && (int)current.type <= 0 && !((Rect)(ref dropdownRect)).Contains(current.mousePosition)) { CloseUploadDropdowns(); GUI.FocusControl((string)null); current.Use(); } } private void CloseUploadDropdowns() { _uploadVersionDropdownOpen = false; _uploadImageDropdownOpen = false; _uploadSaveDropdownOpen = false; } private void DrawUploadSaveDropdown(Rect rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) GUI.Box(rect, GUIContent.none, _panelStrongStyle); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 8f, ((Rect)(ref rect)).y + 8f, ((Rect)(ref rect)).width - 16f, 30f); string text = GUI.TextField(val, _localSaveFilter, _inputStyle); if (!string.Equals(text, _localSaveFilter, StringComparison.Ordinal)) { _localSaveFilter = text; ApplyLocalSaveFilter(resetScroll: true); } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x + 8f, ((Rect)(ref val)).yMax + 6f, ((Rect)(ref rect)).width - 16f, ((Rect)(ref rect)).height - 50f); if (!string.IsNullOrEmpty(_localSaveError)) { GUI.Label(val2, _localSaveError, _dangerStyle); return; } if (_localSaves.Length == 0) { GUI.Label(val2, T("未找到本地 JSON。", "No local JSON files found."), _mutedStyle); return; } if (_filteredLocalSaveIndexes.Count == 0) { GUI.Label(val2, T("没有匹配的 JSON。", "No matching JSON files."), _mutedStyle); return; } Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val2)).width - 18f, (float)_filteredLocalSaveIndexes.Count * 30f); _uploadSaveScroll = GUI.BeginScrollView(val2, _uploadSaveScroll, val3, false, true); int num = Mathf.Max(0, Mathf.FloorToInt(_uploadSaveScroll.y / 30f) - 1); int num2 = Mathf.Min(_filteredLocalSaveIndexes.Count, num + Mathf.CeilToInt(((Rect)(ref val2)).height / 30f) + 2); for (int i = num; i < num2; i++) { int num3 = _filteredLocalSaveIndexes[i]; GUIStyle val4 = ((num3 == _selectedLocalSave) ? _primaryButtonStyle : _buttonStyle); if (GUI.Button(new Rect(0f, (float)i * 30f, ((Rect)(ref val3)).width, 27f), MapSaveService.DisplayName(_localSaves[num3]), val4)) { _selectedLocalSave = num3; if (string.IsNullOrWhiteSpace(_uploadName)) { _uploadName = Path.GetFileNameWithoutExtension(_localSaves[num3]); } AutoSelectMatchingImage(showToast: false); _uploadSaveDropdownOpen = false; _log.LogInfo((object)("JSON selected from upload dropdown: " + _localSaves[num3])); } } GUI.EndScrollView(); } private void DrawUploadImageDropdown(Rect rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_018d: 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_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) GUI.Box(rect, GUIContent.none, _panelStrongStyle); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 8f, ((Rect)(ref rect)).y + 8f, ((Rect)(ref rect)).width - 16f, 30f); string text = GUI.TextField(val, _localImageFilter, _inputStyle); if (!string.Equals(text, _localImageFilter, StringComparison.Ordinal)) { _localImageFilter = text; ApplyLocalImageFilter(resetScroll: true); } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).x + 8f, ((Rect)(ref val)).yMax + 6f, ((Rect)(ref rect)).width - 16f, ((Rect)(ref rect)).height - 50f); if (!string.IsNullOrEmpty(_localImageError)) { GUI.Label(val2, _localImageError, _dangerStyle); return; } if (_localImages.Length == 0) { GUI.Label(val2, T("未找到封面图片。\n可放入:", "No cover images found.\nYou can place them in: ") + MapSaveService.CoverPath, _mutedStyle); return; } if (_filteredLocalImageIndexes.Count == 0) { GUI.Label(val2, T("没有匹配的图片。", "No matching images."), _mutedStyle); return; } Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val2)).width - 18f, (float)_filteredLocalImageIndexes.Count * 28f); _uploadImageScroll = GUI.BeginScrollView(val2, _uploadImageScroll, val3, false, true); int num = Mathf.Max(0, Mathf.FloorToInt(_uploadImageScroll.y / 28f) - 1); int num2 = Mathf.Min(_filteredLocalImageIndexes.Count, num + Mathf.CeilToInt(((Rect)(ref val2)).height / 28f) + 2); for (int i = num; i < num2; i++) { int num3 = _filteredLocalImageIndexes[i]; GUIStyle val4 = ((num3 == _selectedLocalImage) ? _primaryButtonStyle : _buttonStyle); if (GUI.Button(new Rect(0f, (float)i * 28f, ((Rect)(ref val3)).width, 26f), MapSaveService.DisplayName(_localImages[num3]), val4)) { _selectedLocalImage = num3; _uploadImageDropdownOpen = false; _log.LogInfo((object)("Cover image selected from quick list: " + _localImages[num3])); } } GUI.EndScrollView(); } private void DrawImagePickerModal() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_0561: Unknown result type (might be due to invalid IL or missing references) GUI.depth = -102; GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), GUIContent.none, _modalBackdropStyle); bool enabled = GUI.enabled; bool flag = (GUI.enabled = enabled && !IsTopLayerInputBlocked()); Rect val = default(Rect); ((Rect)(ref val))..ctor(Mathf.Round(((float)Screen.width - 760f) * 0.5f), Mathf.Round(((float)Screen.height - 540f) * 0.5f), 760f, 540f); GUI.Box(val, GUIContent.none, _rootStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 16f, 240f, 16f), T("选择封面图片", "SAFE IMAGE PICKER"), _tinyStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 32f, 240f, 34f), T("选择封面图片", "Pick Cover"), _titleStyle); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 54f, ((Rect)(ref val)).y + 22f, 36f, 36f), "×", _iconButtonStyle)) { _imagePickerOpen = false; } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 82f, 160f, ((Rect)(ref val)).height - 148f); GUI.Box(val2, GUIContent.none, _panelStrongStyle); GUI.Label(new Rect(((Rect)(ref val2)).x + 10f, ((Rect)(ref val2)).y + 8f, ((Rect)(ref val2)).width - 20f, 18f), T("白名单目录", "SAFE ROOTS"), _tinyStyle); for (int i = 0; i < _imageRootPaths.Length; i++) { GUIStyle val3 = ((i == _imagePickerRootIndex) ? _primaryButtonStyle : _buttonStyle); if (GUI.Button(new Rect(((Rect)(ref val2)).x + 10f, ((Rect)(ref val2)).y + 34f + (float)i * 34f, ((Rect)(ref val2)).width - 20f, 30f), MapSaveService.GetImageRootLabel(_imageRootPaths[i]), val3)) { _imagePickerRootIndex = i; _log.LogInfo((object)("Image picker root selected: " + _imageRootPaths[i])); SetImagePickerDirectory(_imageRootPaths[i]); } } Rect val4 = default(Rect); ((Rect)(ref val4))..ctor(((Rect)(ref val2)).xMax + 12f, ((Rect)(ref val2)).y, ((Rect)(ref val)).width - 210f, ((Rect)(ref val2)).height); GUI.Box(val4, GUIContent.none, _panelStrongStyle); GUI.Label(new Rect(((Rect)(ref val4)).x + 12f, ((Rect)(ref val4)).y + 8f, ((Rect)(ref val4)).width - 130f, 20f), ShortPath(_imagePickerDirectory), _mutedStyle); if (GUI.Button(new Rect(((Rect)(ref val4)).xMax - 86f, ((Rect)(ref val4)).y + 8f, 74f, 28f), T("上级", "Up"), _buttonStyle)) { GoImagePickerParent(); } if (!string.IsNullOrEmpty(_imagePickerError)) { GUI.Label(new Rect(((Rect)(ref val4)).x + 12f, ((Rect)(ref val4)).y + 46f, ((Rect)(ref val4)).width - 24f, 64f), _imagePickerError, _dangerStyle); } Rect listRect = default(Rect); ((Rect)(ref listRect))..ctor(((Rect)(ref val4)).x + 10f, ((Rect)(ref val4)).y + 46f, ((Rect)(ref val4)).width - 20f, ((Rect)(ref val4)).height - 58f); DrawImagePickerList(listRect); string text = (string.IsNullOrEmpty(_imagePickerSelected) ? T("未选择图片", "No image selected") : (T("已选择:", "Selected: ") + MapSaveService.DisplayName(_imagePickerSelected))); GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).yMax - 58f, ((Rect)(ref val)).width - 220f, 24f), text, _mutedStyle); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 188f, ((Rect)(ref val)).yMax - 62f, 78f, 38f), T("取消", "Cancel"), _buttonStyle)) { _imagePickerOpen = false; } GUI.enabled = flag && !string.IsNullOrEmpty(_imagePickerSelected); if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 100f, ((Rect)(ref val)).yMax - 62f, 82f, 38f), T("使用图片", "Use"), _primaryButtonStyle)) { UsePickedImage(); } GUI.enabled = enabled; } private void DrawImagePickerList(Rect listRect) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) int num = _imagePickerDirs.Length + _imagePickerFiles.Length; Rect val = default(Rect); ((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref listRect)).width - 18f, (float)num * 30f); _imagePickerScroll = GUI.BeginScrollView(listRect, _imagePickerScroll, val, false, true); int num2 = Mathf.Max(0, Mathf.FloorToInt(_imagePickerScroll.y / 30f) - 2); int num3 = Mathf.CeilToInt(((Rect)(ref listRect)).height / 30f) + 4; int num4 = Mathf.Min(num, num2 + num3); Rect val2 = default(Rect); for (int i = num2; i < num4; i++) { ((Rect)(ref val2))..ctor(0f, (float)i * 30f, ((Rect)(ref val)).width, 27f); if (i < _imagePickerDirs.Length) { string text = _imagePickerDirs[i]; if (GUI.Button(val2, "▸ " + MapSaveService.DisplayName(text), _buttonStyle)) { _log.LogInfo((object)("Image picker directory clicked: " + text)); SetImagePickerDirectory(text); } continue; } int num5 = i - _imagePickerDirs.Length; string text2 = _imagePickerFiles[num5]; GUIStyle val3 = (string.Equals(text2, _imagePickerSelected, StringComparison.OrdinalIgnoreCase) ? _primaryButtonStyle : _buttonStyle); if (GUI.Button(val2, "□ " + MapSaveService.DisplayName(text2), val3)) { _imagePickerSelected = text2; _log.LogInfo((object)("Image picker file clicked: " + text2)); UsePickedImage(); } } GUI.EndScrollView(); } private void OpenImagePicker() { _uploadImageDropdownOpen = false; _imageRootPaths = MapSaveService.GetImageRootPaths(); _log.LogInfo((object)("Opening image picker. Whitelisted root count: " + _imageRootPaths.Length)); for (int i = 0; i < _imageRootPaths.Length; i++) { _log.LogInfo((object)("Image picker root[" + i + "]: " + _imageRootPaths[i])); } if (_imageRootPaths.Length == 0) { _log.LogWarning((object)"Image picker cannot open: no whitelisted image roots."); ShowToast(T("没有可用图片目录", "No image directories are available")); return; } _imagePickerRootIndex = Mathf.Clamp(_imagePickerRootIndex, 0, _imageRootPaths.Length - 1); _imagePickerSelected = SelectedLocalImagePath ?? string.Empty; SetImagePickerDirectory((!string.IsNullOrEmpty(_imagePickerSelected)) ? Path.GetDirectoryName(_imagePickerSelected) : _imageRootPaths[_imagePickerRootIndex]); _imagePickerOpen = true; BlockTopLayerInputThisFrame(); _log.LogInfo((object)("Image picker opened. Directory: " + _imagePickerDirectory + ", preselected: " + (string.IsNullOrEmpty(_imagePickerSelected) ? "" : _imagePickerSelected))); } private void SetImagePickerDirectory(string directory) { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) if (!MapSaveService.TryNormalizeWhitelistedDirectory(directory, out var normalized)) { _imagePickerError = T("目录不在白名单内。", "Directory is outside the whitelist."); _log.LogWarning((object)("Image picker rejected directory: " + (directory ?? ""))); return; } _imagePickerDirectory = normalized; _imagePickerError = string.Empty; try { _imagePickerDirs = MapSaveService.GetChildDirectories(normalized); _imagePickerFiles = MapSaveService.GetImageFilesInDirectory(normalized); _log.LogInfo((object)("Image picker loaded directory: " + normalized + " (dirs=" + _imagePickerDirs.Length + ", images=" + _imagePickerFiles.Length + ")")); } catch (Exception ex) { _imagePickerDirs = new string[0]; _imagePickerFiles = new string[0]; _imagePickerError = T("读取目录失败:", "Failed to read directory: ") + ex.Message; _log.LogWarning((object)("Image picker failed to read directory '" + normalized + "': " + ex.Message)); } _imagePickerScroll = Vector2.zero; } private void GoImagePickerParent() { if (!string.IsNullOrEmpty(_imagePickerDirectory)) { string directoryName = Path.GetDirectoryName(_imagePickerDirectory); if (!string.IsNullOrEmpty(directoryName) && MapSaveService.TryNormalizeWhitelistedDirectory(directoryName, out var normalized)) { _log.LogInfo((object)("Image picker parent directory selected: " + normalized)); SetImagePickerDirectory(normalized); } else { _log.LogWarning((object)("Image picker parent rejected or unavailable: " + (directoryName ?? ""))); } } } private void UsePickedImage() { if (!MapSaveService.TryNormalizeWhitelistedImage(_imagePickerSelected, out var normalized)) { _log.LogWarning((object)("Image picker rejected image: " + (string.IsNullOrEmpty(_imagePickerSelected) ? "" : _imagePickerSelected))); ShowToast(T("图片不在白名单内", "Image is outside the whitelist")); return; } int num = Array.FindIndex(_localImages, (string p) => string.Equals(p, normalized, StringComparison.OrdinalIgnoreCase)); if (num < 0) { Array.Resize(ref _localImages, _localImages.Length + 1); _localImages[_localImages.Length - 1] = normalized; ApplyLocalImageFilter(resetScroll: false); num = _localImages.Length - 1; } _selectedLocalImage = num; if (_accountOpen) { _editReplaceImage = true; _editRemoveImage = false; } _imagePickerOpen = false; _uploadImageDropdownOpen = false; _log.LogInfo((object)("Cover image applied: " + normalized)); ShowToast(T("已选择封面:", "Cover selected: ") + MapSaveService.DisplayName(normalized)); } private string ShortPath(string path) { if (string.IsNullOrEmpty(path)) { return string.Empty; } string text = path; if (text.Length > 74) { text = "..." + text.Substring(text.Length - 71); } return text; } private void DrawUploadVersionDropdown(Rect rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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) GUI.Box(rect, GUIContent.none, _panelStrongStyle); if (_versions.Count == 0) { GUI.Label(new Rect(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 10f, ((Rect)(ref rect)).width - 20f, 20f), T("暂无版本", "No versions"), _mutedStyle); return; } Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 6f, ((Rect)(ref rect)).y + 6f, ((Rect)(ref rect)).width - 12f, ((Rect)(ref rect)).height - 12f); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width - 18f, (float)_versions.Count * 30f); _uploadVersionScroll = GUI.BeginScrollView(val, _uploadVersionScroll, val2, false, true); int num = Mathf.Max(0, Mathf.FloorToInt(_uploadVersionScroll.y / 30f) - 1); int num2 = Mathf.Min(_versions.Count, num + Mathf.CeilToInt(((Rect)(ref val)).height / 30f) + 2); for (int i = num; i < num2; i++) { GUIStyle val3 = ((i == _selectedUploadVersion) ? _primaryButtonStyle : _buttonStyle); if (GUI.Button(new Rect(0f, (float)i * 30f, ((Rect)(ref val2)).width, 27f), _versions[i].version_name, val3)) { _selectedUploadVersion = i; _uploadVersionDropdownOpen = false; } } GUI.EndScrollView(); } private void DrawLocalSaveList(Rect savesRect) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref savesRect)).x + 8f, ((Rect)(ref savesRect)).y + 8f, ((Rect)(ref savesRect)).width - 16f, ((Rect)(ref savesRect)).height - 16f); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width - 18f, (float)_filteredLocalSaveIndexes.Count * 28f); _uploadSaveScroll = GUI.BeginScrollView(val, _uploadSaveScroll, val2, false, true); int num = Mathf.Max(0, Mathf.FloorToInt(_uploadSaveScroll.y / 28f) - 2); int num2 = Mathf.CeilToInt(((Rect)(ref val)).height / 28f) + 4; int num3 = Mathf.Min(_filteredLocalSaveIndexes.Count, num + num2); Rect val3 = default(Rect); for (int i = num; i < num3; i++) { int num4 = _filteredLocalSaveIndexes[i]; ((Rect)(ref val3))..ctor(0f, (float)i * 28f, ((Rect)(ref val2)).width, 26f); GUIStyle val4 = ((num4 == _selectedLocalSave) ? _primaryButtonStyle : _buttonStyle); string text = MapSaveService.DisplayName(_localSaves[num4]); if (GUI.Button(val3, text, val4)) { _selectedLocalSave = num4; if (string.IsNullOrWhiteSpace(_uploadName)) { _uploadName = Path.GetFileNameWithoutExtension(_localSaves[num4]); } AutoSelectMatchingImage(showToast: false); } } GUI.EndScrollView(); } private void DrawFieldLabel(float x, float y, string text) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) GUI.Label(new Rect(x, y, 220f, 18f), text, _mutedStyle); } private void DrawToast() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(_toast) && !(Time.unscaledTime > _toastUntil)) { float num = Mathf.Min(340f, ((Rect)(ref _windowRect)).width - 80f); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).x + (((Rect)(ref _windowRect)).width - num) * 0.5f, ((Rect)(ref _windowRect)).y + 74f, num, 34f); GUI.Label(val, "● " + _toast, _toastStyle); } } private void RefreshAll() { _loadedOnce = true; FetchModVersions(); FetchMaps(); if (_api.IsSignedIn && _accountOpen) { FetchAccountMaps(); } } private void RefreshSessionIfNeeded() { if (Time.unscaledTime < _nextSessionRefreshCheckTime || !_api.ShouldRefreshSession || _refreshingSession) { return; } _nextSessionRefreshCheckTime = Time.unscaledTime + 30f; _refreshingSession = true; _api.RefreshSession(delegate(bool ok, string error) { _refreshingSession = false; if (!ok && !string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); FetchMaps(); } }); } private void FetchMaps() { if (_loadingMaps) { return; } _loadingMaps = true; _status = T("正在获取地图列表...", "Fetching map list..."); _api.FetchMaps(_page, _pageSize, _query, _sort, _versionFilter, delegate(MapsResponse response, string error) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) _loadingMaps = false; if (!string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); } else { _maps = response.data ?? new List(); _pagination = response.pagination; _selectedMapIndex = Mathf.Clamp(_selectedMapIndex, 0, Mathf.Max(0, _maps.Count - 1)); _mapScroll = Vector2.zero; _status = T("地图列表已更新", "Map list updated"); } }); } private void FetchAccountMaps() { if (_loadingAccountMaps || !_api.IsSignedIn) { return; } _loadingAccountMaps = true; _api.FetchAccountMaps(delegate(MapsResponse response, string error) { _loadingAccountMaps = false; if (!string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); } else { _accountMaps = response.data ?? new List(); _selectedAccountMapIndex = Mathf.Clamp(_selectedAccountMapIndex, 0, Mathf.Max(0, _accountMaps.Count - 1)); if (_accountMaps.Count > 0) { SelectAccountMap(_selectedAccountMapIndex); } _status = T("我的地图已更新", "My maps updated"); } }); } private void FetchModVersions() { if (_loadingVersions) { return; } _loadingVersions = true; _api.FetchModVersions(delegate(ModVersionsResponse response, string error) { _loadingVersions = false; if (!string.IsNullOrEmpty(error)) { _status = error; } else { _versions = response.data ?? new List(); _selectedUploadVersion = Mathf.Clamp(_selectedUploadVersion, 0, Mathf.Max(0, _versions.Count - 1)); } }); } private void DownloadSelected() { MapEntry selectedMap = SelectedMap; if (selectedMap != null && !_downloading && !_downloadConfirmOpen) { MapDownloadInfo downloadInfo = _api.GetDownloadInfo(selectedMap); if (downloadInfo.Status == MapDownloadStatus.UpToDate) { _status = T("这张地图已经下载,且本地文件没有变化。", "This map is already downloaded and unchanged locally."); ShowToast(_status); } else if (downloadInfo.Status == MapDownloadStatus.UpdateAvailable || downloadInfo.Status == MapDownloadStatus.LocalModified) { _downloadConfirmMapId = selectedMap.id; _downloadConfirmOpen = true; BlockTopLayerInputThisFrame(); } else { StartDownload(selectedMap, allowOverwriteLocalChanges: false); } } } private void StartDownload(MapEntry map, bool allowOverwriteLocalChanges) { if (map == null || _downloading) { return; } _downloading = true; _status = T("正在下载 ", "Downloading ") + map.name + "..."; ShowToast(T("正在下载地图...", "Downloading map...")); _api.DownloadMap(map, allowOverwriteLocalChanges, delegate(string savedPath, string error) { _downloading = false; if (!string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); } else { _status = T("已保存:", "Saved: ") + savedPath; _downloadInfoCache.Remove(map.id); _downloadInfoCacheUntil = 0f; ShowToast(T("下载完成", "Download complete")); } }); } private string DownloadButtonLabel(MapEntry map) { if (map == null) { return T("下载", "Get"); } MapDownloadInfo downloadInfoForDisplay = GetDownloadInfoForDisplay(map); return downloadInfoForDisplay.Status switch { MapDownloadStatus.UpToDate => T("已下载", "Saved"), MapDownloadStatus.UpdateAvailable => T("有更新", "Update"), MapDownloadStatus.LocalModified => T("本地已改", "Changed"), _ => T("下载", "Get"), }; } private MapEntry FindMapById(string mapId) { if (string.IsNullOrEmpty(mapId)) { return null; } for (int i = 0; i < _maps.Count; i++) { if (string.Equals(_maps[i].id, mapId, StringComparison.Ordinal)) { return _maps[i]; } } return null; } private MapDownloadInfo GetDownloadInfoForDisplay(MapEntry map) { if (map == null || string.IsNullOrEmpty(map.id)) { return _api.GetDownloadInfo(map); } if (Time.unscaledTime >= _downloadInfoCacheUntil) { _downloadInfoCache.Clear(); _downloadInfoCacheUntil = Time.unscaledTime + 1f; } if (!_downloadInfoCache.TryGetValue(map.id, out var value)) { value = _api.GetDownloadInfo(map); _downloadInfoCache[map.id] = value; } return value; } private void ToggleLikeSelected() { MapEntry selectedMap = SelectedMap; if (selectedMap == null || _liking) { return; } _liking = true; _api.ToggleLike(selectedMap, delegate(LikeResponse response, string error) { _liking = false; if (!string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); } else { _status = (response.liked ? T("已点赞", "Liked") : T("已取消点赞", "Unliked")); ShowToast(_status); } }); } private void UploadSelected() { if (_uploading) { return; } string selectedPath = SelectedLocalSavePath; if (string.IsNullOrEmpty(selectedPath)) { _log.LogWarning((object)"Upload blocked: no local JSON selected."); ShowToast(T("请选择本地 JSON", "Please select a local JSON")); return; } string text = ((_versions.Count > 0) ? _versions[Mathf.Clamp(_selectedUploadVersion, 0, _versions.Count - 1)].version_name : string.Empty); string imagePath = SelectedLocalImagePath; _log.LogInfo((object)("Upload started. Json: " + selectedPath + ", image: " + (string.IsNullOrEmpty(imagePath) ? "" : imagePath) + ", version: " + (string.IsNullOrEmpty(text) ? "" : text))); _uploading = true; _status = T("正在上传地图...", "Uploading map..."); _api.UploadMap(_uploadName, _uploadAuthor, text, _uploadDescription, selectedPath, imagePath, delegate(string error) { _uploading = false; if (!string.IsNullOrEmpty(error)) { _log.LogWarning((object)("Upload failed. Json: " + selectedPath + ", image: " + (string.IsNullOrEmpty(imagePath) ? "" : imagePath) + ", error: " + error)); _status = error; ShowToast(T("上传失败", "Upload failed")); } else { _log.LogInfo((object)("Upload succeeded. Json: " + selectedPath + ", image: " + (string.IsNullOrEmpty(imagePath) ? "" : imagePath))); _status = T("上传成功", "Upload succeeded"); ShowToast(T("上传成功", "Upload succeeded")); _uploadOpen = false; FetchMaps(); if (_api.IsSignedIn) { FetchAccountMaps(); } } }); } private void SignInSelected() { if (_refreshingSession) { return; } if (string.IsNullOrWhiteSpace(_loginEmail) || string.IsNullOrEmpty(_loginPassword)) { ShowToast(T("请输入邮箱和密码", "Enter email and password")); return; } _refreshingSession = true; _status = T("正在登录...", "Signing in..."); _api.SignIn(_loginEmail, _loginPassword, delegate(AuthResponse response, string error) { _refreshingSession = false; if (!string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); } else { _loginPassword = string.Empty; _loginOpen = false; _status = T("登录成功", "Signed in"); ShowToast(_status); FetchMaps(); OpenAccount(); } }); } private void OpenLogin() { _loginOpen = true; _accountOpen = false; _uploadOpen = false; _imagePickerOpen = false; BlockTopLayerInputThisFrame(); } private void OpenAccount() { if (!_api.IsSignedIn) { OpenLogin(); return; } _accountOpen = true; _loginOpen = false; _uploadOpen = false; _imagePickerOpen = false; BlockTopLayerInputThisFrame(); RefreshLocalSaves(resetScroll: true); FetchAccountMaps(); } private void SelectAccountMap(int index) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) GUI.FocusControl((string)null); GUIUtility.keyboardControl = 0; GUIUtility.hotControl = 0; _selectedAccountMapIndex = Mathf.Clamp(index, 0, Mathf.Max(0, _accountMaps.Count - 1)); MapEntry selectedAccountMap = SelectedAccountMap; if (selectedAccountMap != null) { _editName = selectedAccountMap.name ?? string.Empty; _editAuthor = selectedAccountMap.author ?? string.Empty; _editVersion = selectedAccountMap.mod_version ?? string.Empty; _editDescription = selectedAccountMap.description ?? string.Empty; _editReplaceJson = false; _accountJsonDropdownOpen = false; _accountVersionDropdownOpen = false; _accountVersionScroll = Vector2.zero; _editReplaceImage = false; _editRemoveImage = false; _deleteConfirmMapId = string.Empty; } } private void SaveAccountMap() { MapEntry selectedAccountMap = SelectedAccountMap; if (selectedAccountMap == null || _savingAccountMap) { return; } string jsonPath = (_editReplaceJson ? SelectedLocalSavePath : null); string imagePath = (_editReplaceImage ? SelectedLocalImagePath : null); _savingAccountMap = true; _status = T("正在保存地图...", "Saving map..."); _api.UpdateMap(selectedAccountMap.id, _editName, _editAuthor, _editVersion, _editDescription, jsonPath, imagePath, _editRemoveImage, delegate(string error) { _savingAccountMap = false; if (!string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); } else { _status = T("地图已保存", "Map saved"); ShowToast(_status); FetchMaps(); FetchAccountMaps(); } }); } private void DeleteAccountMap(MapEntry map) { if (map == null || _deletingAccountMap) { return; } _deletingAccountMap = true; _status = T("正在删除地图...", "Deleting map..."); _api.DeleteMap(map.id, delegate(string error) { _deletingAccountMap = false; _deleteConfirmMapId = string.Empty; if (!string.IsNullOrEmpty(error)) { _status = error; ShowToast(error); } else { _status = T("地图已删除", "Map deleted"); ShowToast(_status); _selectedAccountMapIndex = 0; FetchMaps(); FetchAccountMaps(); } }); } private void OpenUpload() { _log.LogInfo((object)"Upload dialog opened."); _uploadOpen = true; BlockTopLayerInputThisFrame(); _uploadVersionDropdownOpen = false; _uploadImageDropdownOpen = false; _uploadSaveDropdownOpen = false; RefreshLocalSaves(resetScroll: true); _uploadAuthor = ((_api.IsSignedIn && !string.IsNullOrEmpty(_api.Session.DisplayName)) ? _api.Session.DisplayName : GetSteamName()); if (_versions.Count == 0) { FetchModVersions(); } if (!string.IsNullOrEmpty(SelectedLocalSavePath) && string.IsNullOrWhiteSpace(_uploadName)) { _uploadName = Path.GetFileNameWithoutExtension(SelectedLocalSavePath); } AutoSelectMatchingImage(showToast: false); } private void RefreshLocalSaves(bool resetScroll = false) { string selectedPath = SelectedLocalSavePath; try { _localSaves = MapSaveService.GetLocalJsonFiles(); _localImages = MapSaveService.GetLocalImageFiles(); _localSaveError = string.Empty; _localImageError = string.Empty; if (resetScroll) { _log.LogInfo((object)("Local map scan completed. SavePath: " + MapSaveService.SavePath + ", jsonCount=" + _localSaves.Length + ", imageCount=" + _localImages.Length)); } } catch (Exception ex) { _localSaves = new string[0]; _localImages = new string[0]; _localSaveError = T("扫描 Map Saves 失败:", "Failed to scan Map Saves: ") + ex.Message; _localImageError = T("扫描封面图片失败:", "Failed to scan cover images: ") + ex.Message; _log.LogWarning((object)("Local map/image scan failed. SavePath: " + MapSaveService.SavePath + ", error: " + ex.Message)); } _nextLocalSaveScanTime = Time.unscaledTime + 3f; ApplyLocalSaveFilter(resetScroll); ApplyLocalImageFilter(resetScroll); if (!string.IsNullOrEmpty(selectedPath)) { int num = Array.FindIndex(_localSaves, (string p) => string.Equals(p, selectedPath, StringComparison.OrdinalIgnoreCase)); if (num >= 0) { _selectedLocalSave = num; } } if ((_selectedLocalSave < 0 || _selectedLocalSave >= _localSaves.Length) && _filteredLocalSaveIndexes.Count > 0) { _selectedLocalSave = _filteredLocalSaveIndexes[0]; } if (_selectedLocalImage >= _localImages.Length) { _selectedLocalImage = -1; } } private void ApplyLocalSaveFilter(bool resetScroll) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) _filteredLocalSaveIndexes.Clear(); string value = (_localSaveFilter ?? string.Empty).Trim(); for (int i = 0; i < _localSaves.Length; i++) { string text = MapSaveService.DisplayName(_localSaves[i]); if (string.IsNullOrEmpty(value) || text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { _filteredLocalSaveIndexes.Add(i); } } if (_filteredLocalSaveIndexes.Count > 0 && !_filteredLocalSaveIndexes.Contains(_selectedLocalSave)) { _selectedLocalSave = _filteredLocalSaveIndexes[0]; } if (resetScroll) { _uploadSaveScroll = Vector2.zero; } } private void CycleSelectedLocalSave() { RefreshLocalSaves(); if (_filteredLocalSaveIndexes.Count == 0) { ShowToast(T("未找到本地 JSON", "No local JSON found")); return; } int num = _filteredLocalSaveIndexes.IndexOf(_selectedLocalSave); int index = ((num >= 0) ? ((num + 1) % _filteredLocalSaveIndexes.Count) : 0); _selectedLocalSave = _filteredLocalSaveIndexes[index]; ShowToast(T("已选择 JSON:", "JSON selected: ") + MapSaveService.DisplayName(SelectedLocalSavePath)); } private void ApplyLocalImageFilter(bool resetScroll) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) _filteredLocalImageIndexes.Clear(); string value = (_localImageFilter ?? string.Empty).Trim(); for (int i = 0; i < _localImages.Length; i++) { string text = MapSaveService.DisplayName(_localImages[i]); if (string.IsNullOrEmpty(value) || text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { _filteredLocalImageIndexes.Add(i); } } if (resetScroll) { _uploadImageScroll = Vector2.zero; } } private void AutoSelectMatchingImage(bool showToast) { string match = MapSaveService.FindMatchingImage(SelectedLocalSavePath, _localImages); if (string.IsNullOrEmpty(match)) { _log.LogInfo((object)("Auto image match not found for json: " + (SelectedLocalSavePath ?? ""))); if (showToast) { ShowToast(T("未找到同名封面", "No matching cover found")); } return; } int num = Array.FindIndex(_localImages, (string p) => string.Equals(p, match, StringComparison.OrdinalIgnoreCase)); if (num >= 0) { _selectedLocalImage = num; _log.LogInfo((object)("Auto image match selected: " + match)); if (showToast) { ShowToast(T("已匹配封面:", "Matched cover: ") + MapSaveService.DisplayName(match)); } } } private void CycleVersionFilter() { if (_versions.Count == 0) { FetchModVersions(); return; } if (string.IsNullOrEmpty(_versionFilter)) { _versionFilter = _versions[0].version_name; } else { int num = _versions.FindIndex((ModVersionEntry v) => string.Equals(v.version_name, _versionFilter, StringComparison.Ordinal)); num++; _versionFilter = ((num >= _versions.Count) ? string.Empty : _versions[num].version_name); } _page = 1; FetchMaps(); } private void SelectMap(int index) { _selectedMapIndex = Mathf.Clamp(index, 0, Mathf.Max(0, _maps.Count - 1)); } private void ShowToast(string text) { _toast = text; _toastUntil = Time.unscaledTime + 3.6f; } private string T(string zh, string en) { return string.Equals(_language, "en", StringComparison.OrdinalIgnoreCase) ? en : zh; } private static string ShortAccountName(string value) { if (string.IsNullOrWhiteSpace(value)) { return "Account"; } string text = CleanUiText(value.Trim()); return (text.Length <= 14) ? text : (text.Substring(0, 13) + "..."); } private void OpenAccountWebsite() { Application.OpenURL("https://peakmap.top/account"); } private string GetSteamName() { try { string personaName = SteamFriends.GetPersonaName(); if (!string.IsNullOrEmpty(personaName)) { return personaName; } } catch (Exception ex) { _log.LogWarning((object)("Failed to read Steam persona name: " + ex.Message)); } return "Steam Player"; } private void EnsureStyles() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0272: 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_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Expected O, but got Unknown //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0487: 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_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Expected O, but got Unknown //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_062c: Unknown result type (might be due to invalid IL or missing references) //IL_0667: Unknown result type (might be due to invalid IL or missing references) //IL_06b5: Unknown result type (might be due to invalid IL or missing references) //IL_06ce: Unknown result type (might be due to invalid IL or missing references) //IL_0709: Unknown result type (might be due to invalid IL or missing references) //IL_0757: Unknown result type (might be due to invalid IL or missing references) //IL_0770: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Unknown result type (might be due to invalid IL or missing references) //IL_07f9: Unknown result type (might be due to invalid IL or missing references) //IL_0812: Unknown result type (might be due to invalid IL or missing references) //IL_0840: Unknown result type (might be due to invalid IL or missing references) //IL_0880: Unknown result type (might be due to invalid IL or missing references) //IL_0899: Unknown result type (might be due to invalid IL or missing references) //IL_08be: Unknown result type (might be due to invalid IL or missing references) //IL_08d7: Unknown result type (might be due to invalid IL or missing references) if (!_stylesReady) { try { _uiFont = Font.CreateDynamicFontFromOSFont(new string[4] { "Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Arial" }, 16); } catch (Exception ex) { _log.LogWarning((object)("Failed to create Chinese UI font: " + ex.Message)); } _rootStyle = Box(new Color(0.02f, 0.032f, 0.026f, 0.995f), new Color(0.18f, 0.26f, 0.2f, 0.82f)); _panelStyle = Box(new Color(0.014f, 0.025f, 0.019f, 0.985f), new Color(0.13f, 0.2f, 0.16f, 0.9f)); _panelStrongStyle = Box(new Color(0.022f, 0.036f, 0.028f, 0.99f), new Color(0.16f, 0.24f, 0.18f, 0.9f)); _detailMetaStyle = Box(new Color(0.03f, 0.048f, 0.038f, 0.94f), new Color(0.15f, 0.23f, 0.17f, 0.72f)); _detailDescriptionStyle = Box(new Color(0.025f, 0.04f, 0.032f, 0.92f), new Color(0.14f, 0.22f, 0.17f, 0.65f)); _cardStyle = Box(new Color(0.028f, 0.044f, 0.034f, 0.995f), new Color(0.15f, 0.23f, 0.17f, 0.95f)); _buttonStyle = Button(new Color(0.044f, 0.06f, 0.05f, 0.995f), new Color(0.8f, 0.88f, 0.82f, 1f), accent: false); _primaryButtonStyle = Button(new Color(0.18f, 0.78f, 0.42f, 1f), new Color(0.02f, 0.1f, 0.06f, 1f), accent: true); _iconButtonStyle = Button(new Color(0.044f, 0.06f, 0.05f, 0.995f), new Color(0.86f, 0.94f, 0.86f, 1f), accent: false); _sidebarButtonStyle = Button(new Color(0.018f, 0.03f, 0.024f, 0.995f), new Color(0.76f, 0.84f, 0.78f, 1f), accent: false); _sidebarButtonStyle.alignment = (TextAnchor)3; _sidebarButtonStyle.padding = new RectOffset(16, 8, 0, 0); _sidebarSelectedStyle = Button(new Color(0.12f, 0.2f, 0.14f, 0.995f), new Color(0.3f, 0.98f, 0.58f, 1f), accent: false); _sidebarSelectedStyle.alignment = (TextAnchor)3; _sidebarSelectedStyle.padding = new RectOffset(16, 8, 0, 0); _statBoxStyle = Box(new Color(0.04f, 0.06f, 0.048f, 0.98f), new Color(0.16f, 0.25f, 0.18f, 0.9f)); _inputStyle = Input(); _textAreaStyle = Input(); _textAreaStyle.wordWrap = true; _textAreaStyle.alignment = (TextAnchor)0; _titleStyle = Label(24, (FontStyle)1, Color.white); _h2Style = Label(18, (FontStyle)1, Color.white); _h2Style.alignment = (TextAnchor)0; _labelStyle = Label(13, (FontStyle)1, new Color(0.93f, 0.98f, 0.92f, 1f)); _statLabelStyle = Label(11, (FontStyle)1, new Color(0.98f, 0.64f, 0.24f, 1f)); _statLabelStyle.wordWrap = false; _statLabelStyle.clipping = (TextClipping)0; _statValueStyle = Label(15, (FontStyle)1, new Color(0.91f, 0.98f, 0.9f, 1f)); _statValueStyle.wordWrap = false; _statValueStyle.clipping = (TextClipping)0; _cardStatsStyle = Label(13, (FontStyle)1, new Color(0.86f, 0.96f, 0.86f, 1f)); _cardStatsStyle.wordWrap = false; _cardStatsStyle.clipping = (TextClipping)1; _mutedStyle = Label(12, (FontStyle)0, new Color(0.72f, 0.78f, 0.72f, 1f)); _cardDescStyle = Label(12, (FontStyle)0, new Color(0.72f, 0.78f, 0.72f, 1f)); _cardDescStyle.wordWrap = true; _detailTitleStyle = Label(20, (FontStyle)1, Color.white); _detailTextStyle = Label(13, (FontStyle)0, new Color(0.8f, 0.87f, 0.8f, 1f)); _detailTextStyle.wordWrap = true; _detailTextStyle.padding = new RectOffset(0, 2, 1, 1); _tinyStyle = Label(10, (FontStyle)1, new Color(0.95f, 0.67f, 0.32f, 1f)); _dangerStyle = Label(12, (FontStyle)1, new Color(0.95f, 0.45f, 0.38f, 1f)); _badgeStyle = Box(new Color(0.035f, 0.115f, 0.075f, 0.98f), new Color(0.18f, 0.42f, 0.28f, 0.95f)); _badgeStyle.alignment = (TextAnchor)4; _badgeStyle.normal.textColor = new Color(0.7f, 0.95f, 0.76f, 1f); _badgeStyle.fontStyle = (FontStyle)1; _badgeStyle.fontSize = 12; _badgeStyle.font = _uiFont; _apiBadgeStyle = Box(new Color(0.032f, 0.04f, 0.037f, 0.98f), new Color(0.14f, 0.18f, 0.16f, 0.95f)); _apiBadgeStyle.alignment = (TextAnchor)4; _apiBadgeStyle.normal.textColor = new Color(0.68f, 0.78f, 0.7f, 1f); _apiBadgeStyle.fontStyle = (FontStyle)1; _apiBadgeStyle.fontSize = 12; _apiBadgeStyle.font = _uiFont; _pagePillStyle = Box(new Color(0.032f, 0.04f, 0.037f, 0.98f), new Color(0.16f, 0.2f, 0.18f, 0.95f)); _pagePillStyle.alignment = (TextAnchor)4; _pagePillStyle.normal.textColor = new Color(0.78f, 0.88f, 0.78f, 1f); _pagePillStyle.fontStyle = (FontStyle)1; _pagePillStyle.fontSize = 13; _pagePillStyle.font = _uiFont; _toastStyle = Box(new Color(0.025f, 0.03f, 0.028f, 0.98f), new Color(0.18f, 0.42f, 0.28f, 0.9f)); _toastStyle.normal.textColor = new Color(0.86f, 0.95f, 0.86f, 1f); _toastStyle.alignment = (TextAnchor)4; _toastStyle.font = _uiFont; _thumbStyle = Box(new Color(0.055f, 0.07f, 0.06f, 1f), new Color(0.16f, 0.2f, 0.18f, 0.9f)); _modalBackdropStyle = Box(new Color(0f, 0f, 0f, 0.78f), new Color(0f, 0f, 0f, 0f)); _placeholderThumb = CreatePlaceholderThumb(); _stylesReady = true; } } private GUIStyle Box(Color bg, Color border) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0038: 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_0047: Expected O, but got Unknown //IL_0049: Expected O, but got Unknown Texture2D background = MakeTex(8, 8, bg, border); GUIStyle val = new GUIStyle(GUI.skin.box); val.normal.background = background; val.border = new RectOffset(1, 1, 1, 1); val.padding = new RectOffset(8, 8, 6, 6); return val; } private GUIStyle Button(Color bg, Color text, bool accent) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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) //IL_00cf: 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_00e0: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_0157: Expected O, but got Unknown Color border = (accent ? new Color(0.2f, 0.62f, 0.38f, 0.95f) : new Color(0.18f, 0.22f, 0.2f, 0.95f)); Color bg2 = (accent ? new Color(0.18f, 0.58f, 0.37f, 1f) : new Color(0.058f, 0.066f, 0.062f, 0.995f)); Color border2 = (accent ? new Color(0.24f, 0.7f, 0.44f, 0.95f) : new Color(0.25f, 0.3f, 0.27f, 0.95f)); Texture2D background = MakeTex(8, 8, bg, border); Texture2D background2 = MakeTex(8, 8, bg2, border2); GUIStyle val = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)4, fontSize = 14, fontStyle = (FontStyle)1, font = _uiFont }; val.normal.background = background; val.normal.textColor = text; val.hover.background = background2; val.hover.textColor = text; val.active.background = background2; val.active.textColor = text; val.border = new RectOffset(1, 1, 1, 1); return val; } private GUIStyle Input() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_005c: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_00f8: Expected O, but got Unknown GUIStyle val = new GUIStyle(GUI.skin.textField) { fontSize = 14, font = _uiFont }; val.normal.background = MakeTex(8, 8, new Color(0.01f, 0.012f, 0.012f, 0.995f), new Color(0.18f, 0.22f, 0.2f, 0.95f)); val.normal.textColor = Color.white; val.focused.background = MakeTex(8, 8, new Color(0.016f, 0.02f, 0.018f, 0.995f), new Color(0.24f, 0.46f, 0.34f, 0.95f)); val.focused.textColor = Color.white; val.padding = new RectOffset(10, 10, 9, 8); val.border = new RectOffset(1, 1, 1, 1); return val; } private GUIStyle Label(int size, FontStyle fontStyle, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = size, fontStyle = fontStyle, font = _uiFont }; val.normal.textColor = color; val.wordWrap = true; val.clipping = (TextClipping)1; return val; } private Texture2D MakeTex(int width, int height, Color bg, Color border) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0042: 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) //IL_0044: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { bool flag = j == 0 || i == 0 || j == width - 1 || i == height - 1; array[i * width + j] = (flag ? border : bg); } } val.SetPixels(array); val.Apply(); return val; } private Texture2D CreatePlaceholderThumb() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) int num = 256; int num2 = 144; Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false); Color val2 = default(Color); for (int i = 0; i < num2; i++) { for (int j = 0; j < num; j++) { float num3 = Mathf.Abs(Mathf.Sin((float)j * 0.05f + (float)i * 0.035f)); float num4 = Mathf.Abs((float)i - ((float)num2 * 0.58f + Mathf.Sin((float)j * 0.035f) * 26f)); ((Color)(ref val2))..ctor(0.05f, 0.075f + num3 * 0.05f, 0.06f, 1f); if (num4 < 2.4f) { ((Color)(ref val2))..ctor(0.34f, 0.9f, 0.52f, 1f); } val.SetPixel(j, i, val2); } } val.Apply(); return val; } private static string Safe(string value, string fallback) { return string.IsNullOrWhiteSpace(value) ? fallback : value; } private static string SingleLine(string value, int maxLength) { string text = (value ?? string.Empty).Replace("\r", " ").Replace("\n", " ").Trim(); if (text.Length <= maxLength) { return text; } return text.Substring(0, Mathf.Max(0, maxLength - 3)) + "..."; } private static string CompactCardDescription(string value, float width) { string text = (value ?? string.Empty).Replace("\r", " ").Replace("\n", " ").Trim(); if (string.IsNullOrEmpty(text)) { return text; } int num = Mathf.Max(24, Mathf.FloorToInt(width / 8f)); int num2 = Mathf.Max(48, num * 2); if (text.Length <= num2) { return text; } return text.Substring(0, Mathf.Max(0, num2 - 3)).TrimEnd(Array.Empty()) + "..."; } private static string CleanUiText(string value) { if (string.IsNullOrEmpty(value)) { return value; } StringBuilder stringBuilder = new StringBuilder(value.Length); for (int i = 0; i < value.Length; i++) { char c = value[i]; if (char.IsHighSurrogate(c)) { if (i + 1 < value.Length && char.IsLowSurrogate(value[i + 1])) { i++; } } else if (!char.IsLowSurrogate(c) && (!char.IsControl(c) || c == '\n' || c == '\r' || c == '\t') && !IsEmojiLikeBmp(c)) { stringBuilder.Append(c); } } return stringBuilder.ToString(); } private static bool IsEmojiLikeBmp(char ch) { return (ch >= '☀' && ch <= '➿') || (ch >= '\ufe00' && ch <= '\ufe0f') || (ch >= '\u200d' && ch <= '\u200d') || (ch >= '\u20e3' && ch <= '\u20e3'); } private static string FormatDetailDescription(string value) { if (string.IsNullOrWhiteSpace(value)) { return value; } string text = value.Replace("\r\n", "\n").Replace('\r', '\n'); string[] array = text.Split(new char[1] { '\n' }); StringBuilder stringBuilder = new StringBuilder(text.Length + 24); bool flag = false; bool flag2 = false; for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0) { if (flag && !flag2) { stringBuilder.AppendLine(); flag2 = true; } continue; } if (flag && !flag2 && IsDescriptionKeyLine(text2)) { stringBuilder.AppendLine(); } stringBuilder.AppendLine(text2); flag = true; flag2 = false; } return stringBuilder.ToString().TrimEnd(Array.Empty()); } private static bool IsDescriptionKeyLine(string line) { int num = line.IndexOf(':'); if (num <= 0 || num > 18) { return false; } string a = line.Substring(0, num).Trim(); return string.Equals(a, "Desc", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Description", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Difficulty", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Testers", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Note", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Player Count", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Players", StringComparison.OrdinalIgnoreCase); } private string ShortVersion(string value) { if (string.IsNullOrEmpty(value)) { return T("全部", "All"); } int num = value.IndexOf('('); if (num > 0) { string text = value.Substring(0, num).Trim(); if (!string.IsNullOrEmpty(text)) { return (text.Length <= 10) ? text : text.Substring(0, 10); } } return (value.Length <= 10) ? value : value.Substring(0, 10); } private static string DateOnly(string value) { if (string.IsNullOrEmpty(value)) { return "-"; } return (value.Length >= 10) ? value.Substring(0, 10) : value; } } [BepInPlugin("com.wuyachiyu.peakmapbrowser", "PEAK Map Browser", "0.1.1")] public sealed class Plugin : BaseUnityPlugin { private PeakMapWindow _window; private ConfigEntry _apiBaseUrl; private ConfigEntry _language; private ConfigEntry _pageSize; private ConfigEntry _toggleKey; private void Awake() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) _apiBaseUrl = ((BaseUnityPlugin)this).Config.Bind("General", "ApiBaseUrl", "https://peakmap.top", "PEAK map site API base URL."); _language = ((BaseUnityPlugin)this).Config.Bind("General", "Language", "auto", "auto follows the game's Unity Localization language; zh or en forces a language."); _pageSize = ((BaseUnityPlugin)this).Config.Bind("General", "PageSize", 12, "Maps per API page. API allows 1-50."); _toggleKey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleKey", (KeyCode)47, "Open/close PEAK Map Browser."); string text = FormatKeyName(_toggleKey.Value); _window = new PeakMapWindow((MonoBehaviour)(object)this, ((BaseUnityPlugin)this).Logger, _apiBaseUrl.Value, _language.Value, Mathf.Clamp(_pageSize.Value, 1, 50), text); ((BaseUnityPlugin)this).Logger.LogInfo((object)("PEAK Map Browser loaded. Press " + text + " to open.")); } private void Update() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(_toggleKey.Value)) { _window.Toggle(); } _window.Update(); } private void OnDestroy() { if (_window != null) { _window.Dispose(); } } private void OnGUI() { _window.Draw(); } private unsafe static string FormatKeyName(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 return ((int)key == 47) ? "/" : ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } } }