Decompiled source of PeakMapBrowser v0.1.0

PeakMapBrowser.dll

Decompiled a day ago
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.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]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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<MapEntry> data;

		public PaginationInfo pagination;

		public string error_code;

		public string error;

		public string error_message;
	}
	internal sealed class ModVersionsResponse
	{
		public bool success;

		public List<ModVersionEntry> data;

		public string error_code;

		public string error;

		public string error_message;
	}
	internal sealed class MapEntry
	{
		public string id;

		public string name;

		public string author;

		public string mod_version;

		public string description;

		public int downloads;

		public string created_at;

		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 MapSaveService
	{
		public static string SavePath => Path.Combine(Application.persistentDataPath, "TerrainCustomiser", "Map Saves");

		public static string CoverPath => Path.Combine(SavePath, "Covers");

		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<string> list = new List<string>();
			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);
		}

		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<string> list = new List<string>();
			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<string> list = new List<string>();
			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)
		{
			EnsureSaveDirectory();
			string value = (string.IsNullOrWhiteSpace(map.name) ? "peak-map" : map.name.Trim());
			string text = SanitizeFileName(value);
			if (string.IsNullOrEmpty(text))
			{
				text = "peak-map";
			}
			string text2 = Path.Combine(SavePath, text + ".json");
			int num = 2;
			while (File.Exists(text2))
			{
				text2 = Path.Combine(SavePath, text + "-" + num + ".json");
				num++;
			}
			File.WriteAllBytes(text2, bytes);
			return text2;
		}

		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) != 0 || (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 sealed class PeakMapApiClient
	{
		[CompilerGenerated]
		private sealed class <DownloadMapRoutine>d__13 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public MapEntry map;

			public Action<string, string> done;

			public PeakMapApiClient <>4__this;

			private UnityWebRequest <request>5__1;

			private string <saved>5__2;

			private Exception <ex>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DownloadMapRoutine>d__13(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<request>5__1 = null;
				<saved>5__2 = null;
				<ex>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						if (map == null || string.IsNullOrEmpty(map.download_url))
						{
							done(null, <>4__this.Text("地图缺少下载地址", "Map is missing a download URL"));
							result = false;
							break;
						}
						<request>5__1 = UnityWebRequest.Get(map.download_url);
						<>1__state = -3;
						<>2__current = <request>5__1.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						if (HasError(<request>5__1))
						{
							done(null, <>4__this.Text("下载失败: ", "Download failed: ") + <request>5__1.error);
							result = false;
							<>m__Finally1();
							break;
						}
						try
						{
							<saved>5__2 = MapSaveService.SaveDownloadedMap(map, <request>5__1.downloadHandler.data);
							done(<saved>5__2, null);
							<saved>5__2 = null;
						}
						catch (Exception ex)
						{
							<ex>5__3 = ex;
							done(null, <>4__this.Text("保存失败: ", "Save failed: ") + <ex>5__3.Message);
						}
						<>m__Finally1();
						<request>5__1 = null;
						result = false;
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__1 != null)
				{
					((IDisposable)<request>5__1).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DownloadTextureRoutine>d__15 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public string url;

			public Action<Texture2D> done;

			public PeakMapApiClient <>4__this;

			private UnityWebRequest <request>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DownloadTextureRoutine>d__15(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<request>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						if (string.IsNullOrEmpty(url))
						{
							done(null);
							result = false;
							break;
						}
						<request>5__1 = UnityWebRequestTexture.GetTexture(url);
						<>1__state = -3;
						<>2__current = <request>5__1.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						if (HasError(<request>5__1))
						{
							<>4__this._log.LogWarning((object)("Thumbnail failed: " + <request>5__1.error));
							done(null);
							result = false;
							<>m__Finally1();
						}
						else
						{
							done(DownloadHandlerTexture.GetContent(<request>5__1));
							<>m__Finally1();
							<request>5__1 = null;
							result = false;
						}
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__1 != null)
				{
					((IDisposable)<request>5__1).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FetchMapsRoutine>d__11 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public int page;

			public int pageSize;

			public string query;

			public string sort;

			public string modVersion;

			public Action<MapsResponse, string> done;

			public PeakMapApiClient <>4__this;

			private string <url>5__1;

			private UnityWebRequest <request>5__2;

			private MapsResponse <response>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FetchMapsRoutine>d__11(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<url>5__1 = null;
				<request>5__2 = null;
				<response>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						<url>5__1 = <>4__this._baseUrl + "/api/maps?page=" + page + "&page_size=" + pageSize + "&sort=" + Escape(sort) + "&lang=" + <>4__this._language;
						if (!string.IsNullOrWhiteSpace(query))
						{
							<url>5__1 = <url>5__1 + "&q=" + Escape(query.Trim());
						}
						if (!string.IsNullOrWhiteSpace(modVersion))
						{
							<url>5__1 = <url>5__1 + "&mod_version=" + Escape(modVersion.Trim());
						}
						<request>5__2 = UnityWebRequest.Get(<url>5__1);
						<>1__state = -3;
						<>2__current = <request>5__2.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						if (HasError(<request>5__2))
						{
							done(null, <>4__this.Text("获取地图列表失败: ", "Failed to fetch maps: ") + <request>5__2.error);
							result = false;
						}
						else
						{
							<response>5__3 = <>4__this.Parse<MapsResponse>(<request>5__2.downloadHandler.text);
							if (<response>5__3 != null && <response>5__3.success)
							{
								done(<response>5__3, null);
								<response>5__3 = null;
								<>m__Finally1();
								<request>5__2 = null;
								result = false;
								break;
							}
							done(<response>5__3, ResponseError(<response>5__3, <>4__this.Text("获取地图列表失败", "Failed to fetch maps")));
							result = false;
						}
						<>m__Finally1();
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__2 != null)
				{
					((IDisposable)<request>5__2).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FetchModVersionsRoutine>d__12 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Action<ModVersionsResponse, string> done;

			public PeakMapApiClient <>4__this;

			private UnityWebRequest <request>5__1;

			private ModVersionsResponse <response>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FetchModVersionsRoutine>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<request>5__1 = null;
				<response>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						<request>5__1 = UnityWebRequest.Get(<>4__this._baseUrl + "/api/mod-versions?lang=" + <>4__this._language);
						<>1__state = -3;
						<>2__current = <request>5__1.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						if (HasError(<request>5__1))
						{
							done(null, <>4__this.Text("获取 MOD 版本失败: ", "Failed to fetch MOD versions: ") + <request>5__1.error);
							result = false;
						}
						else
						{
							<response>5__2 = <>4__this.Parse<ModVersionsResponse>(<request>5__1.downloadHandler.text);
							if (<response>5__2 != null && <response>5__2.success)
							{
								done(<response>5__2, null);
								<response>5__2 = null;
								<>m__Finally1();
								<request>5__1 = null;
								result = false;
								break;
							}
							done(<response>5__2, ResponseError(<response>5__2, <>4__this.Text("获取 MOD 版本失败", "Failed to fetch MOD versions")));
							result = false;
						}
						<>m__Finally1();
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__1 != null)
				{
					((IDisposable)<request>5__1).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <UploadMapRoutine>d__14 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public string mapName;

			public string author;

			public string version;

			public string description;

			public string jsonPath;

			public string imagePath;

			public Action<string> done;

			public PeakMapApiClient <>4__this;

			private List<IMultipartFormSection> <form>5__1;

			private string <ext>5__2;

			private string <contentType>5__3;

			private UnityWebRequest <request>5__4;

			private string <body>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <UploadMapRoutine>d__14(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<form>5__1 = null;
				<ext>5__2 = null;
				<contentType>5__3 = null;
				<request>5__4 = null;
				<body>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Expected O, but got Unknown
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Expected O, but got Unknown
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Expected O, but got Unknown
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_014c: Expected O, but got Unknown
				//IL_016e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Expected O, but got Unknown
				//IL_028e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0298: Expected O, but got Unknown
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						if (string.IsNullOrWhiteSpace(mapName) || string.IsNullOrWhiteSpace(author) || string.IsNullOrWhiteSpace(version))
						{
							done(<>4__this.Text("地图名称、作者和版本不能为空", "Map name, author, and version are required"));
							result = false;
							break;
						}
						if (string.IsNullOrEmpty(jsonPath) || !File.Exists(jsonPath))
						{
							done(<>4__this.Text("请选择本地 JSON 地图文件", "Please select a local JSON map file"));
							result = false;
							break;
						}
						<form>5__1 = new List<IMultipartFormSection>
						{
							(IMultipartFormSection)new MultipartFormDataSection("name", mapName.Trim()),
							(IMultipartFormSection)new MultipartFormDataSection("author", author.Trim()),
							(IMultipartFormSection)new MultipartFormDataSection("mod_version", version.Trim()),
							(IMultipartFormSection)new MultipartFormDataSection("description", (description == null) ? string.Empty : description.Trim()),
							(IMultipartFormSection)new MultipartFormFileSection("json_file", File.ReadAllBytes(jsonPath), Path.GetFileName(jsonPath), "application/json")
						};
						if (!string.IsNullOrEmpty(imagePath) && File.Exists(imagePath))
						{
							<ext>5__2 = Path.GetExtension(imagePath).ToLowerInvariant();
							<contentType>5__3 = ((<ext>5__2 == ".jpg" || <ext>5__2 == ".jpeg") ? "image/jpeg" : ((<ext>5__2 == ".webp") ? "image/webp" : ((<ext>5__2 == ".gif") ? "image/gif" : "image/png")));
							<>4__this._log.LogInfo((object)("Upload request includes image file: " + imagePath + " (" + <contentType>5__3 + ")"));
							<form>5__1.Add((IMultipartFormSection)new MultipartFormFileSection("image_file", File.ReadAllBytes(imagePath), Path.GetFileName(imagePath), <contentType>5__3));
							<ext>5__2 = null;
							<contentType>5__3 = null;
						}
						else
						{
							<>4__this._log.LogInfo((object)("Upload request has no image file. imagePath=" + (string.IsNullOrEmpty(imagePath) ? "<none>" : imagePath)));
						}
						<request>5__4 = UnityWebRequest.Post(<>4__this._baseUrl + "/api/upload", <form>5__1);
						<>1__state = -3;
						<>4__this._log.LogInfo((object)("Sending upload request to " + <>4__this._baseUrl + "/api/upload"));
						<>2__current = <request>5__4.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						if (HasError(<request>5__4))
						{
							<body>5__5 = ((<request>5__4.downloadHandler != null) ? <request>5__4.downloadHandler.text : string.Empty);
							<>4__this._log.LogWarning((object)("Upload request failed. Code=" + <request>5__4.responseCode + ", error=" + <request>5__4.error + ", body=" + <body>5__5));
							done(<>4__this.Text("上传失败: ", "Upload failed: ") + ((!string.IsNullOrEmpty(<body>5__5)) ? <body>5__5 : <request>5__4.error));
							result = false;
							<>m__Finally1();
						}
						else
						{
							<>4__this._log.LogInfo((object)("Upload request succeeded. Code=" + <request>5__4.responseCode));
							done(null);
							<>m__Finally1();
							<request>5__4 = null;
							result = false;
						}
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__4 != null)
				{
					((IDisposable)<request>5__4).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private readonly MonoBehaviour _runner;

		private readonly ManualLogSource _log;

		private readonly string _baseUrl;

		private string _language;

		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");
		}

		public void SetLanguage(string language)
		{
			_language = (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) ? "en" : "zh");
		}

		public void FetchMaps(int page, int pageSize, string query, string sort, string modVersion, Action<MapsResponse, string> done)
		{
			_runner.StartCoroutine(FetchMapsRoutine(page, pageSize, query, sort, modVersion, done));
		}

		public void FetchModVersions(Action<ModVersionsResponse, string> done)
		{
			_runner.StartCoroutine(FetchModVersionsRoutine(done));
		}

		public void DownloadMap(MapEntry map, Action<string, string> done)
		{
			_runner.StartCoroutine(DownloadMapRoutine(map, done));
		}

		public void UploadMap(string mapName, string author, string version, string description, string jsonPath, string imagePath, Action<string> done)
		{
			_runner.StartCoroutine(UploadMapRoutine(mapName, author, version, description, jsonPath, imagePath, done));
		}

		public void DownloadTexture(string url, Action<Texture2D> done)
		{
			_runner.StartCoroutine(DownloadTextureRoutine(url, done));
		}

		[IteratorStateMachine(typeof(<FetchMapsRoutine>d__11))]
		private IEnumerator FetchMapsRoutine(int page, int pageSize, string query, string sort, string modVersion, Action<MapsResponse, string> done)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FetchMapsRoutine>d__11(0)
			{
				<>4__this = this,
				page = page,
				pageSize = pageSize,
				query = query,
				sort = sort,
				modVersion = modVersion,
				done = done
			};
		}

		[IteratorStateMachine(typeof(<FetchModVersionsRoutine>d__12))]
		private IEnumerator FetchModVersionsRoutine(Action<ModVersionsResponse, string> done)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FetchModVersionsRoutine>d__12(0)
			{
				<>4__this = this,
				done = done
			};
		}

		[IteratorStateMachine(typeof(<DownloadMapRoutine>d__13))]
		private IEnumerator DownloadMapRoutine(MapEntry map, Action<string, string> done)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DownloadMapRoutine>d__13(0)
			{
				<>4__this = this,
				map = map,
				done = done
			};
		}

		[IteratorStateMachine(typeof(<UploadMapRoutine>d__14))]
		private IEnumerator UploadMapRoutine(string mapName, string author, string version, string description, string jsonPath, string imagePath, Action<string> done)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <UploadMapRoutine>d__14(0)
			{
				<>4__this = this,
				mapName = mapName,
				author = author,
				version = version,
				description = description,
				jsonPath = jsonPath,
				imagePath = imagePath,
				done = done
			};
		}

		[IteratorStateMachine(typeof(<DownloadTextureRoutine>d__15))]
		private IEnumerator DownloadTextureRoutine(string url, Action<Texture2D> done)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DownloadTextureRoutine>d__15(0)
			{
				<>4__this = this,
				url = url,
				done = done
			};
		}

		private T Parse<T>(string json) where T : class
		{
			try
			{
				return JsonConvert.DeserializeObject<T>(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 ResponseError(MapsResponse response, string fallback)
		{
			return (response != null && !string.IsNullOrEmpty(response.error_message)) ? response.error_message : fallback;
		}

		private static string ResponseError(ModVersionsResponse response, string fallback)
		{
			return (response != null && !string.IsNullOrEmpty(response.error_message)) ? response.error_message : fallback;
		}

		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);
			}
			SystemLanguage systemLanguage = Application.systemLanguage;
			string rawValue = ((object)(SystemLanguage)(ref systemLanguage)).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 sealed class PeakMapWindow
	{
		private readonly MonoBehaviour _runner;

		private readonly ManualLogSource _log;

		private readonly PeakMapApiClient _api;

		private readonly int _pageSize;

		private readonly Dictionary<string, Texture2D> _thumbnails = new Dictionary<string, Texture2D>();

		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 _uploadOpen;

		private bool _loadedOnce;

		private int _topLayerOpenedFrame = -1;

		private Rect _windowRect;

		private Vector2 _mapScroll;

		private Vector2 _uploadSaveScroll;

		private Vector2 _detailScroll;

		private List<MapEntry> _maps = new List<MapEntry>();

		private List<ModVersionEntry> _versions = new List<ModVersionEntry>();

		private PaginationInfo _pagination;

		private int _selectedMapIndex;

		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 string[] _localSaves = new string[0];

		private readonly List<int> _filteredLocalSaveIndexes = new List<int>();

		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 string[] _localImages = new string[0];

		private readonly List<int> _filteredLocalImageIndexes = new List<int>();

		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 GUIStyle _rootStyle;

		private GUIStyle _panelStyle;

		private GUIStyle _panelStrongStyle;

		private GUIStyle _detailMetaStyle;

		private GUIStyle _detailDescriptionStyle;

		private GUIStyle _cardStyle;

		private GUIStyle _cardSelectedStyle;

		private GUIStyle _buttonStyle;

		private GUIStyle _primaryButtonStyle;

		private GUIStyle _iconButtonStyle;

		private GUIStyle _inputStyle;

		private GUIStyle _titleStyle;

		private GUIStyle _h2Style;

		private GUIStyle _labelStyle;

		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 _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;

		public PeakMapWindow(MonoBehaviour runner, ManualLogSource log, string apiBaseUrl, string language, int pageSize, string toggleKeyLabel)
		{
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: 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;
				_uploadVersionDropdownOpen = false;
				_uploadImageDropdownOpen = 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<Canvas>();
				val.renderMode = (RenderMode)0;
				val.sortingOrder = 32767;
				_inputBlocker.AddComponent<GraphicRaycaster>();
				GameObject val2 = new GameObject("Blocker");
				val2.transform.SetParent(_inputBlocker.transform, false);
				Image val3 = val2.AddComponent<Image>();
				((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();
			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_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!_visible)
			{
				return;
			}
			EnsureStyles();
			CenterWindow();
			GUI.depth = 10;
			DrawDimBackground();
			GUI.Box(_windowRect, GUIContent.none, _rootStyle);
			if (!_uploadOpen && !_imagePickerOpen)
			{
				DrawHeader();
				if (!_uploadOpen && !_imagePickerOpen)
				{
					DrawContent();
				}
			}
			if (_uploadOpen && !_imagePickerOpen)
			{
				DrawUploadModal();
			}
			if (_imagePickerOpen)
			{
				DrawImagePickerModal();
			}
			DrawToast();
			ConsumeOverlayEvents();
		}

		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(960f, (float)Screen.width - 48f));
			float num2 = Mathf.Round(Mathf.Min(640f, (float)Screen.height - 48f));
			_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 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Invalid comparison between Unknown and I4
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: 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, 82f);
			GUI.Box(val, GUIContent.none, _panelStrongStyle);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 18f, 44f, 44f);
			GUI.Box(val2, GUIContent.none, _badgeStyle);
			GUI.Label(new Rect(((Rect)(ref val2)).x + 11f, ((Rect)(ref val2)).y + 2f, 28f, 36f), "/", _titleStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 72f, ((Rect)(ref val)).y + 18f, 180f, 16f), "EXPEDITION DATABASE", _tinyStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 72f, ((Rect)(ref val)).y + 32f, 190f, 34f), T("PEAK 地图库", "PEAK Maps"), _titleStyle);
			float num = ((Rect)(ref val)).x + 276f;
			float num2 = ((Rect)(ref val)).y + 23f;
			float num3 = 38f;
			float num4 = 118f;
			float num5 = 38f;
			float num6 = 76f;
			float num7 = 96f;
			float num8 = 8f;
			float num9 = Mathf.Max(170f, ((Rect)(ref val)).xMax - num - num3 - num4 - num5 - num6 - num7 - num8 * 6f - 18f);
			GUI.SetNextControlName("PeakMapSearch");
			string text = GUI.TextField(new Rect(num, num2, num9, 38f), _query, _inputStyle);
			if (text != _query)
			{
				_query = text;
			}
			num += num9 + num8;
			if (GUI.Button(new Rect(num, num2, num7, 38f), ShortVersion(_versionFilter), _buttonStyle))
			{
				CycleVersionFilter();
			}
			num += num7 + num8;
			if (GUI.Button(new Rect(num, num2, num6, 38f), (_sort == "downloads") ? T("下载量", "Popular") : T("最新", "Newest"), _buttonStyle))
			{
				_sort = ((_sort == "downloads") ? "newest" : "downloads");
				_page = 1;
				FetchMaps();
			}
			num += num6 + num8;
			if (GUI.Button(new Rect(num, num2, num5, 38f), "↻", _iconButtonStyle))
			{
				RefreshAll();
			}
			num += num5 + num8;
			if (GUI.Button(new Rect(num, num2, num4, 38f), T("↑ 上传地图", "↑ Upload"), _primaryButtonStyle))
			{
				OpenUpload();
			}
			num += num4 + num8;
			if (GUI.Button(new Rect(num, num2, num3, 38f), "×", _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 DrawContent()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).x + 14f, ((Rect)(ref _windowRect)).y + 96f, ((Rect)(ref _windowRect)).width - 28f, ((Rect)(ref _windowRect)).height - 110f);
			float num = Mathf.Min(336f, ((Rect)(ref val)).width * 0.38f);
			Rect rect = default(Rect);
			((Rect)(ref rect))..ctor(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width - num - 14f, ((Rect)(ref val)).height);
			Rect rect2 = default(Rect);
			((Rect)(ref rect2))..ctor(((Rect)(ref rect)).xMax + 14f, ((Rect)(ref val)).y, num, ((Rect)(ref val)).height);
			DrawMapList(rect);
			DrawDetail(rect2);
		}

		private void DrawMapList(Rect rect)
		{
			//IL_0001: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: 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 + 14f, ((Rect)(ref rect)).y + 14f, ((Rect)(ref rect)).width - 160f, 22f), T("共 ", "") + text + T(" 张社区地图 · 当前筛选 ", " community maps · Filter ") + (string.IsNullOrEmpty(_versionFilter) ? T("全部版本", "All versions") : _versionFilter), _mutedStyle);
			GUI.Label(new Rect(((Rect)(ref rect)).xMax - 142f, ((Rect)(ref rect)).y + 10f, 128f, 26f), "API: peakmap.top", _apiBadgeStyle);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 50f, ((Rect)(ref rect)).width - 28f, ((Rect)(ref rect)).height - 104f);
			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 + 14f, ((Rect)(ref rect)).yMax - 44f, ((Rect)(ref rect)).width - 28f, 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 > 440f)) ? 1 : 2);
			float num2 = 12f;
			float num3 = (((Rect)(ref rect)).width - (float)(num - 1) * num2 - 10f) / (float)num;
			float num4 = 270f;
			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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			bool flag = index == _selectedMapIndex;
			GUI.Box(rect, GUIContent.none, flag ? _cardSelectedStyle : _cardStyle);
			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, 108f);
			DrawThumbnail(rect2, map);
			GUI.Label(new Rect(((Rect)(ref rect2)).x + 10f, ((Rect)(ref rect2)).y + 10f, 86f, 22f), ShortVersion(map.mod_version), _badgeStyle);
			float num = ((Rect)(ref val)).y + 124f;
			GUI.Label(new Rect(((Rect)(ref val)).x + 11f, num, ((Rect)(ref val)).width - 22f, 32f), CleanUiText(Safe(map.name, T("未命名地图", "Untitled map"))), _h2Style);
			GUI.Label(new Rect(((Rect)(ref val)).x + 11f, num + 35f, ((Rect)(ref val)).width - 22f, 19f), "○ " + CleanUiText(Safe(map.author, "Unknown")), _mutedStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 11f, num + 60f, ((Rect)(ref val)).width - 22f, 42f), CleanUiText(Safe(map.description, T("没有描述", "No description"))), _cardDescStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 11f, ((Rect)(ref val)).yMax - 34f, 72f, 26f), "↓ " + map.downloads, _mutedStyle);
			if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 74f, ((Rect)(ref val)).yMax - 38f, 60f, 30f), T("下载", "Get"), _primaryButtonStyle))
			{
				SelectMap(index);
				DownloadSelected();
			}
			if ((int)Event.current.type == 0 && ((Rect)(ref rect)).Contains(Event.current.mousePosition))
			{
				SelectMap(index);
				Event.current.Use();
			}
		}

		private void DrawThumbnail(Rect rect, MapEntry map)
		{
			//IL_0009: 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)1);
			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_00a3: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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_028d: 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_02f6: 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, 118f, 74f);
			DrawThumbnail(rect2, selectedMap);
			float num = ((Rect)(ref rect2)).xMax + 12f;
			GUI.Label(new Rect(num, ((Rect)(ref rect)).y + 16f, ((Rect)(ref rect)).xMax - num - 14f, 16f), "SELECTED MAP", _tinyStyle);
			GUI.Label(new Rect(num, ((Rect)(ref rect)).y + 34f, ((Rect)(ref rect)).xMax - num - 14f, 28f), CleanUiText(Safe(selectedMap.name, T("未命名地图", "Untitled map"))), _detailTitleStyle);
			GUI.Label(new Rect(num, ((Rect)(ref rect)).y + 64f, ((Rect)(ref rect)).xMax - num - 14f, 18f), T("下载 ", "Downloads ") + selectedMap.downloads + " · " + DateOnly(selectedMap.created_at), _mutedStyle);
			float num2 = ((Rect)(ref rect2)).yMax + 14f;
			DrawDetailMeta(new Rect(((Rect)(ref rect)).x + 14f, num2, ((Rect)(ref rect)).width - 28f, 58f), selectedMap);
			num2 += 68f;
			float num3 = ((Rect)(ref rect)).yMax - 48f;
			Rect rect3 = default(Rect);
			((Rect)(ref rect3))..ctor(((Rect)(ref rect)).x + 14f, num2, ((Rect)(ref rect)).width - 28f, Mathf.Max(110f, num3 - num2 - 12f));
			DrawScrollableDescription(rect3, FormatDetailDescription(CleanUiText(Safe(selectedMap.description, T("没有描述", "No description")))));
			GUI.enabled = !_downloading;
			if (GUI.Button(new Rect(((Rect)(ref rect)).x + 16f, num3, ((Rect)(ref rect)).width - 126f, 36f), _downloading ? T("下载中...", "Downloading...") : T("下载到本地", "Download"), _primaryButtonStyle))
			{
				DownloadSelected();
			}
			GUI.enabled = true;
			if (GUI.Button(new Rect(((Rect)(ref rect)).xMax - 102f, num3, 86f, 36f), T("刷新", "Refresh"), _buttonStyle))
			{
				RefreshAll();
			}
		}

		private void DrawDetailMeta(Rect rect, MapEntry map)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			GUI.Box(rect, GUIContent.none, _detailMetaStyle);
			float num = (((Rect)(ref rect)).width - 20f) * 0.5f;
			float num2 = ((Rect)(ref rect)).x + num + 10f;
			GUI.Label(new Rect(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 7f, num - 10f, 16f), T("作者", "AUTHOR"), _tinyStyle);
			GUI.Label(new Rect(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 27f, num - 10f, 20f), CleanUiText(Safe(map.author, "Unknown")), _labelStyle);
			GUI.Label(new Rect(num2, ((Rect)(ref rect)).y + 7f, ((Rect)(ref rect)).xMax - num2 - 10f, 16f), T("版本", "VERSION"), _tinyStyle);
			GUI.Label(new Rect(num2, ((Rect)(ref rect)).y + 27f, ((Rect)(ref rect)).xMax - num2 - 10f, 20f), CleanUiText(Safe(map.mod_version, "-")), _labelStyle);
		}

		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 DrawUploadModal()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: 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_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0720: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_084f: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e4: 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_0999: Unknown result type (might be due to invalid IL or missing references)
			//IL_09cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a22: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a94: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b05: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b2e: Unknown result type (might be due to invalid IL or missing references)
			GUI.depth = 0;
			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), "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;
			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 - 136f, 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);
			}
			bool flag = _uploadVersionDropdownOpen || _uploadImageDropdownOpen;
			bool flag2 = IsTopLayerInputBlocked();
			if (flag)
			{
				ConsumeUploadDropdownOutsideClick(_uploadVersionDropdownOpen ? zero : zero2);
			}
			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, 42f, 38f), T("浏览", "Pick"), _buttonStyle))
			{
				_log.LogInfo((object)"Image browser button clicked.");
				CloseUploadDropdowns();
				OpenImagePicker();
			}
			if (GUI.Button(new Rect(((Rect)(ref val3)).xMax + 52f, ((Rect)(ref val3)).y, 40f, 38f), T("自动", "Auto"), _buttonStyle))
			{
				_log.LogInfo((object)("Auto image match button clicked. Json: " + (SelectedLocalSavePath ?? "<none>")));
				CloseUploadDropdowns();
				AutoSelectMatchingImage(showToast: true);
			}
			if (GUI.Button(new Rect(((Rect)(ref val3)).xMax + 96f, ((Rect)(ref val3)).y, 36f, 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, num2, T("本地地图 JSON", "Local map JSON"));
			string text3 = GUI.TextField(new Rect(num3 + 110f, num2 - 4f, ((Rect)(ref val)).width - 146f, 30f), _localSaveFilter, _inputStyle);
			if (!string.Equals(text3, _localSaveFilter, StringComparison.Ordinal))
			{
				_localSaveFilter = text3;
				ApplyLocalSaveFilter(resetScroll: true);
			}
			float num6 = ((Rect)(ref val)).yMax - 74f;
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(num3, num2 + 34f, ((Rect)(ref val)).width - 36f, Mathf.Max(76f, num6 - num2 - 42f));
			GUI.Box(val4, GUIContent.none, _panelStrongStyle);
			if (!string.IsNullOrEmpty(_localSaveError))
			{
				GUI.Label(new Rect(((Rect)(ref val4)).x + 14f, ((Rect)(ref val4)).y + 14f, ((Rect)(ref val4)).width - 28f, 42f), _localSaveError, _dangerStyle);
			}
			else if (_localSaves.Length == 0)
			{
				GUI.Label(new Rect(((Rect)(ref val4)).x + 14f, ((Rect)(ref val4)).y + 14f, ((Rect)(ref val4)).width - 28f, 42f), T("未找到本地 JSON。目录已自动创建:\n", "No local JSON found. Directory was created:\n") + MapSaveService.SavePath, _mutedStyle);
			}
			else if (_filteredLocalSaveIndexes.Count == 0)
			{
				GUI.Label(new Rect(((Rect)(ref val4)).x + 14f, ((Rect)(ref val4)).y + 14f, ((Rect)(ref val4)).width - 28f, 42f), T("没有匹配筛选条件的 JSON。", "No JSON matches the filter."), _mutedStyle);
			}
			else
			{
				DrawLocalSaveList(val4);
			}
			string text4 = T("扫描到 ", "Found ") + _localSaves.Length + T(" 个 JSON", " JSON files");
			if (!string.IsNullOrWhiteSpace(_localSaveFilter))
			{
				text4 = text4 + T(" · 匹配 ", " · Matched ") + _filteredLocalSaveIndexes.Count + T(" 个", "");
			}
			GUI.Label(new Rect(num3, ((Rect)(ref val4)).yMax + 4f, ((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);
			}
			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;
		}

		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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0100: 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_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: 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_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			GUI.depth = -1;
			GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), GUIContent.none, _modalBackdropStyle);
			bool enabled = GUI.enabled;
			bool flag2 = (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), "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 = flag2 && !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) ? "<none>" : _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 ?? "<null>")));
				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 ?? "<null>")));
				}
			}
		}

		private void UsePickedImage()
		{
			if (!MapSaveService.TryNormalizeWhitelistedImage(_imagePickerSelected, out var normalized))
			{
				_log.LogWarning((object)("Image picker rejected image: " + (string.IsNullOrEmpty(_imagePickerSelected) ? "<none>" : _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;
			_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_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(_toast) && !(Time.unscaledTime > _toastUntil))
			{
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).xMax - 230f, ((Rect)(ref _windowRect)).yMax - 54f, 210f, 34f);
				GUI