Decompiled source of NomapPrinter v1.5.3

NomapPrinter.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using ConditionalConfigSync;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using NomapPrinter;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Nomap Printer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Nomap Printer")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ba601320-0ece-4b27-b2a4-a1fe1ba817b3")]
[assembly: AssemblyFileVersion("1.5.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.3.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private const string defaultLanguage = "English";

		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin Plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static IEnumerator Load()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized));
			if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", "")))
			{
				PlatformPrefs.SetString("language", "English");
			}
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> localizationFiles = new Dictionary<string, string>();
			string[] prefixes = new string[2]
			{
				Plugin.Info.Metadata.Name + ".",
				Plugin.Info.Metadata.Name.Replace(" ", "") + "."
			};
			Scan(Paths.ConfigPath, warn: true);
			Scan(Paths.PluginPath, warn: false);
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml.");
			}
			Dictionary<string, string> dictionary = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary == null)
			{
				throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text = null;
			if (language != "English")
			{
				if (localizationFiles.ContainsKey(language))
				{
					text = File.ReadAllText(localizationFiles[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text == null && localizationFiles.ContainsKey("English"))
			{
				text = File.ReadAllText(localizationFiles["English"]);
			}
			if (text != null)
			{
				Dictionary<string, string> dictionary2;
				try
				{
					dictionary2 = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>();
				}
				catch (Exception arg)
				{
					global::NomapPrinter.NomapPrinter.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}");
					dictionary2 = new Dictionary<string, string>();
				}
				foreach (KeyValuePair<string, string> item in dictionary2)
				{
					dictionary[item.Key] = item.Value;
				}
			}
			loadedTexts[language] = dictionary;
			foreach (KeyValuePair<string, string> item2 in dictionary)
			{
				UpdatePlaceholderText(__instance, item2.Key);
			}
			void Scan(string root, bool warn)
			{
				foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories)
					where fileExtensions.Contains(Path.GetExtension(f))
					select f)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3);
					string[] array3 = prefixes;
					foreach (string text2 in array3)
					{
						if (fileNameWithoutExtension.StartsWith(text2))
						{
							string text3 = fileNameWithoutExtension.Substring(text2.Length);
							if (!string.IsNullOrWhiteSpace(text3))
							{
								if (localizationFiles.ContainsKey(text3))
								{
									if (warn)
									{
										global::NomapPrinter.NomapPrinter.LogInfo("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3);
									}
								}
								else
								{
									localizationFiles[text3] = item3;
								}
							}
							break;
						}
					}
				}
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace NomapPrinter
{
	internal static class InteractiveMap
	{
		[HarmonyPatch(typeof(Minimap), "SetMapMode")]
		private static class Minimap_SetMapMode_ResetInteractiveState
		{
			private static void Prefix(Minimap __instance, MapMode mode)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Invalid comparison between Unknown and I4
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				if (active && (int)__instance.m_mode == 2 && (int)mode != 2)
				{
					SaveCurrentMapCenter(__instance, Player.m_localPlayer);
				}
			}

			private static void Postfix(Minimap __instance)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Invalid comparison between Unknown and I4
				if (active && (int)__instance.m_mode != 2)
				{
					ResetHiddenPins(__instance);
					active = false;
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "OnDestroy")]
		private static class Minimap_OnDestroy_ResetInteractiveState
		{
			private static void Postfix()
			{
				hiddenPins.Clear();
				active = false;
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdateMap")]
		private static class Minimap_UpdateMap_KeepConfiguredCenter
		{
			private static void Prefix(Minimap __instance, Player player)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				if (IsOpen && NomapPrinter.doNotCenterInteractiveMapOnPlayer.Value && !((Object)(object)player == (Object)null))
				{
					Vector3 position = ((Component)player).transform.position;
					__instance.m_mapOffset += lastPlayerPosition - position;
					lastPlayerPosition = position;
				}
			}

			private static void Postfix(Minimap __instance, Player player)
			{
				if (IsOpen)
				{
					SaveCurrentMapCenter(__instance, player);
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdatePlayerMarker")]
		private static class Minimap_UpdatePlayerMarker_ApplyInteractiveVisibility
		{
			private static void Postfix(Minimap __instance)
			{
				ApplyPlayerMarkerVisibility(__instance);
			}
		}

		[HarmonyPatch(typeof(Minimap), "DelayActivation")]
		private static class Minimap_DelayActivation_KeepFilteredPinNamesHidden
		{
			private static void Postfix(GameObject go, ref IEnumerator __result)
			{
				if (__result != null)
				{
					__result = KeepPinNameHidden(__result, go);
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdatePins")]
		private static class Minimap_UpdatePins_ApplyInteractiveFilters
		{
			private static void Postfix(Minimap __instance)
			{
				if (!IsOpen || __instance.m_pins == null)
				{
					return;
				}
				foreach (PinData pin in __instance.m_pins)
				{
					if (NomapPrinter.applyPinFiltersToInteractiveMap.Value && !MapMaker.ShouldShowPin(pin))
					{
						hiddenPins.Add(pin);
						HidePinVisuals(pin);
					}
					else if (hiddenPins.Remove(pin))
					{
						__instance.DestroyPinMarker(pin);
						__instance.m_pinUpdateRequired = true;
					}
				}
			}
		}

		private static readonly HashSet<PinData> hiddenPins = new HashSet<PinData>();

		private static bool active;

		private static Vector3 lastPlayerPosition;

		private static bool hasLastMapCenter;

		private static Vector3 lastMapCenter;

		internal static bool IsOpen => active && (Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2;

		public static void Show()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)instance == (Object)null || (Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			active = true;
			bool noMap = Game.m_noMap;
			try
			{
				Game.m_noMap = false;
				instance.inputDelay = 1f;
				instance.SetMapMode((MapMode)2);
			}
			catch
			{
				active = false;
				throw;
			}
			finally
			{
				Game.m_noMap = noMap;
			}
			lastPlayerPosition = ((Component)localPlayer).transform.position;
			if (NomapPrinter.doNotCenterInteractiveMapOnPlayer.Value)
			{
				Vector3 val = (hasLastMapCenter ? lastMapCenter : Vector3.zero);
				instance.m_mapOffset = val - lastPlayerPosition;
				instance.CenterMap(val);
				lastMapCenter = val;
				hasLastMapCenter = true;
			}
			ApplyPlayerMarkerVisibility(instance);
			instance.m_pinUpdateRequired = true;
			instance.UpdatePins();
		}

		private static void ApplyPlayerMarkerVisibility(Minimap minimap)
		{
			if (IsOpen && NomapPrinter.hidePlayerMarkerOnInteractiveMap.Value)
			{
				if ((Object)(object)minimap.m_largeMarker != (Object)null)
				{
					((Component)minimap.m_largeMarker).gameObject.SetActive(false);
				}
				if ((Object)(object)minimap.m_largeShipMarker != (Object)null)
				{
					((Component)minimap.m_largeShipMarker).gameObject.SetActive(false);
				}
			}
		}

		private static void HidePinVisuals(PinData pin)
		{
			if (pin != null)
			{
				if ((Object)(object)pin.m_uiElement != (Object)null)
				{
					((Component)pin.m_uiElement).gameObject.SetActive(false);
				}
				PinNameData namePinData = pin.m_NamePinData;
				if ((Object)(object)((namePinData != null) ? namePinData.PinNameGameObject : null) != (Object)null)
				{
					pin.m_NamePinData.PinNameGameObject.SetActive(false);
				}
			}
		}

		private static bool ShouldKeepPinNameHidden(GameObject pinNameGameObject)
		{
			if (!IsOpen || !NomapPrinter.applyPinFiltersToInteractiveMap.Value || (Object)(object)pinNameGameObject == (Object)null)
			{
				return false;
			}
			foreach (PinData hiddenPin in hiddenPins)
			{
				object obj;
				if (hiddenPin == null)
				{
					obj = null;
				}
				else
				{
					PinNameData namePinData = hiddenPin.m_NamePinData;
					obj = ((namePinData != null) ? namePinData.PinNameGameObject : null);
				}
				if ((Object)obj == (Object)(object)pinNameGameObject)
				{
					return true;
				}
			}
			return false;
		}

		private static IEnumerator KeepPinNameHidden(IEnumerator original, GameObject pinNameGameObject)
		{
			try
			{
				while (original.MoveNext())
				{
					yield return original.Current;
					if (ShouldKeepPinNameHidden(pinNameGameObject))
					{
						pinNameGameObject.SetActive(false);
					}
				}
				if (ShouldKeepPinNameHidden(pinNameGameObject))
				{
					pinNameGameObject.SetActive(false);
				}
			}
			finally
			{
				if (original is IDisposable disposable)
				{
					disposable.Dispose();
				}
			}
		}

		private static void ResetHiddenPins(Minimap minimap)
		{
			foreach (PinData hiddenPin in hiddenPins)
			{
				if (hiddenPin != null)
				{
					minimap.DestroyPinMarker(hiddenPin);
				}
			}
			hiddenPins.Clear();
		}

		private static void SaveCurrentMapCenter(Minimap minimap, Player player)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (NomapPrinter.doNotCenterInteractiveMapOnPlayer.Value && !((Object)(object)minimap == (Object)null) && !((Object)(object)player == (Object)null))
			{
				lastMapCenter = ((Component)player).transform.position + minimap.m_mapOffset;
				hasLastMapCenter = true;
			}
		}

		internal static void ResetSession()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			hiddenPins.Clear();
			active = false;
			hasLastMapCenter = false;
			lastMapCenter = Vector3.zero;
			lastPlayerPosition = Vector3.zero;
		}
	}
	internal static class MapGenerator
	{
		private const int _textureSize = 4096;

		private static bool[] _exploredData;

		private static Color32[] _mapTexture;

		private static Color[] _forestTexture;

		private static Color32[] _heightmap;

		private static Color32[] _result;

		private static Color32[] space;

		private static int spaceRes;

		private static Color32[] fog;

		private static int fogRes;

		private static Color32[] contours;

		private static int contoursRes;

		public static readonly Color32 yellowMap = new Color32((byte)203, (byte)155, (byte)87, byte.MaxValue);

		public static readonly Color32 oceanColor = new Color32((byte)20, (byte)100, byte.MaxValue, byte.MaxValue);

		public static readonly Color32 abyssColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue);

		public static readonly Color32 lavaColor = new Color32((byte)205, (byte)51, (byte)15, byte.MaxValue);

		public static readonly Color32 northColor = new Color32((byte)170, (byte)173, (byte)194, byte.MaxValue);

		public static readonly Color32 mistColor = new Color32((byte)217, (byte)140, (byte)166, byte.MaxValue);

		public static readonly Color clearMask = new Color(0f, 0f, 0f, 1f);

		public static int TextureSize => (int)(4096f * NomapPrinter.mapSizeMultiplier.Value);

		private static Color32[] MapTexture
		{
			get
			{
				if (_mapTexture == null)
				{
					_mapTexture = (Color32[])(object)new Color32[TextureSize * TextureSize];
				}
				return _mapTexture;
			}
			set
			{
				_mapTexture = value;
			}
		}

		private static Color[] ForestTexture
		{
			get
			{
				if (_forestTexture == null)
				{
					_forestTexture = (Color[])(object)new Color[TextureSize * TextureSize];
				}
				return _forestTexture;
			}
			set
			{
				_forestTexture = value;
			}
		}

		private static Color32[] Heightmap
		{
			get
			{
				if (_heightmap == null)
				{
					_heightmap = (Color32[])(object)new Color32[TextureSize * TextureSize];
				}
				return _heightmap;
			}
			set
			{
				_heightmap = value;
			}
		}

		private static bool[] ExploredData
		{
			get
			{
				if (_exploredData == null)
				{
					_exploredData = new bool[TextureSize * TextureSize];
				}
				return _exploredData;
			}
			set
			{
				_exploredData = value;
			}
		}

		public static Color32[] Result
		{
			get
			{
				if (_result == null)
				{
					_result = (Color32[])(object)new Color32[TextureSize * TextureSize];
				}
				return _result;
			}
			set
			{
				_result = value;
			}
		}

		public static IEnumerator Initialize()
		{
			if (spaceRes == 0 && (NomapPrinter.mapType.Value == NomapPrinter.MapType.BirdsEye || NomapPrinter.mapType.Value == NomapPrinter.MapType.Topographical))
			{
				yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Minimap.instance != (Object)null && (Object)(object)Minimap.instance.m_mapLargeShader != (Object)null));
				Texture spaceTex = Minimap.instance.m_mapLargeShader.GetTexture("_SpaceTex");
				spaceRes = spaceTex.width;
				RenderTexture tmp = RenderTexture.GetTemporary(spaceRes, spaceRes, 24);
				Graphics.Blit(spaceTex, tmp);
				RenderTexture previous = RenderTexture.active;
				RenderTexture.active = tmp;
				Texture2D tex = new Texture2D(spaceRes, spaceRes, (TextureFormat)4, false, false);
				tex.ReadPixels(new Rect(0f, 0f, (float)spaceRes, (float)spaceRes), 0, 0);
				tex.Apply();
				RenderTexture.active = previous;
				RenderTexture.ReleaseTemporary(tmp);
				space = tex.GetPixels32();
				Object.Destroy((Object)(object)tex);
			}
		}

		public static void InitializeTextures(Texture2D biomes, Texture2D forests, Texture2D height)
		{
			MapTexture = biomes.GetPixels32();
			ForestTexture = forests.GetPixels();
			Heightmap = height.GetPixels32();
		}

		public static void DeInitializeTextures()
		{
			MapTexture = null;
			ForestTexture = null;
			Heightmap = null;
			Result = null;
			fog = null;
			contours = null;
		}

		public static void SetFogTexture(Texture2D fog)
		{
			SetFogTexture(fog.GetPixels32());
		}

		public static void SetContoursTexture(Color32[] newContours)
		{
			contours = (Color32[])(object)new Color32[newContours.Length];
			contoursRes = (int)Math.Sqrt(newContours.Length);
			newContours.CopyTo(contours, 0);
		}

		public static void SetFogTexture(Color32[] newFog)
		{
			fog = (Color32[])(object)new Color32[newFog.Length];
			fogRes = (int)Math.Sqrt(newFog.Length);
			newFog.CopyTo(fog, 0);
		}

		public static void SetMapTexture(Texture2D map)
		{
			SetMapTexture(map.GetPixels32());
		}

		public static void SetMapTexture(Color32[] map)
		{
			map.CopyTo(MapTexture, 0);
		}

		public static IEnumerator OverlayTextureOnMap(Texture2D texture)
		{
			texture.GetPixels32().CopyTo(Result, 0);
			yield return OverlayResultOnMap();
		}

		public static IEnumerator OverlayExplorationFog(bool[] exploration)
		{
			for (int i = 0; i < ExploredData.Length; i++)
			{
				ExploredData[i] = false;
			}
			if (exploration.Length == ExploredData.Length)
			{
				exploration.CopyTo(ExploredData, 0);
			}
			else
			{
				int targetSize = (int)Math.Sqrt(ExploredData.Length);
				int currentSize = (int)Math.Sqrt(exploration.Length);
				for (int row = 0; row < currentSize; row++)
				{
					for (int col = 0; col < currentSize; col++)
					{
						if (exploration[row * currentSize + col])
						{
							SetExploredData(row * 2 * targetSize + col * 2);
							SetExploredData(row * 2 * targetSize + col * 2 + 1);
							SetExploredData((row * 2 + 1) * targetSize + col * 2);
							SetExploredData((row * 2 + 1) * targetSize + col * 2 + 1);
						}
					}
				}
			}
			yield return StylizeFog();
			yield return OverlayResultOnMap();
			static void SetExploredData(int position)
			{
				if (position < ExploredData.Length)
				{
					ExploredData[position] = true;
				}
			}
		}

		public static IEnumerator GenerateOldMap(int graduationHeight)
		{
			yield return GenerateOceanTexture(Heightmap, MapTexture, 0.25f);
			Color32[] oceanTexture = Result;
			yield return ReplaceAbyssWithColor(MapTexture, abyssColor, yellowMap);
			Color32[] outtex = Result;
			yield return OverlayTexture(outtex, oceanTexture);
			outtex = Result;
			yield return GetSolidColour(yellowMap);
			Color32[] offYellow = Result;
			yield return LerpTextures(outtex, offYellow);
			outtex = Result;
			yield return LerpTextures(outtex, offYellow);
			outtex = Result;
			yield return LerpTextures(outtex, offYellow);
			outtex = Result;
			yield return AddPerlinNoise(outtex, 128, 16);
			outtex = Result;
			yield return ApplyForestMaskTexture(outtex, ForestTexture, 0.95f);
			outtex = Result;
			yield return GenerateContourMap(Heightmap, graduationHeight, 128);
			Color32[] contours = Result;
			yield return OverlayTexture(outtex, contours);
		}

		public static IEnumerator GenerateChartMap(int graduationHeight)
		{
			yield return GenerateOceanTexture(Heightmap, MapTexture, 0.15f);
			Color32[] oceanTexture = Result;
			yield return ReplaceAbyssWithColor(MapTexture, abyssColor, yellowMap);
			Color32[] outtex = Result;
			yield return OverlayTexture(outtex, oceanTexture);
			outtex = Result;
			yield return GetSolidColour(yellowMap);
			Color32[] offYellow = Result;
			yield return LerpTextures(outtex, offYellow);
			outtex = Result;
			yield return AddPerlinNoise(outtex, 128, 16);
			outtex = Result;
			yield return ApplyForestMaskTexture(outtex, ForestTexture);
			outtex = Result;
			yield return GenerateContourMap(Heightmap, graduationHeight, 128);
			Color32[] contours = Result;
			yield return OverlayTexture(outtex, contours);
		}

		public static IEnumerator GenerateSatelliteImage()
		{
			yield return GenerateOceanTexture(Heightmap, MapTexture);
			Color32[] oceanTexture = Result;
			yield return AddPerlinNoise(oceanTexture, 4, 64);
			oceanTexture = Result;
			yield return ReplaceAbyssWithSpace(MapTexture, abyssColor);
			Color32[] outtex = Result;
			yield return OverlayTexture(outtex, oceanTexture);
			outtex = Result;
			yield return CreateShadowMap(Heightmap, 23);
			Color32[] shadowmap = Result;
			yield return DarkenTextureLinear(outtex, 20);
			outtex = Result;
			yield return ApplyForestMaskTexture(outtex, ForestTexture);
			outtex = Result;
			yield return GenerateContourMap(Heightmap, 128, 64);
			Color32[] contours = Result;
			yield return OverlayTexture(outtex, contours);
			outtex = Result;
			yield return OverlayTexture(outtex, shadowmap);
		}

		public static IEnumerator GenerateTopographicalMap(int graduationHeight)
		{
			yield return GenerateOceanTexture(Heightmap, MapTexture);
			Color32[] oceanTexture = Result;
			yield return AddPerlinNoise(oceanTexture, 4, 64);
			oceanTexture = Result;
			yield return ReplaceAbyssWithSpace(MapTexture, abyssColor);
			Color32[] outtex = Result;
			yield return OverlayTexture(outtex, oceanTexture);
			outtex = Result;
			yield return CreateShadowMap(Heightmap, 23);
			Color32[] shadowmap = Result;
			yield return DarkenTextureLinear(outtex, 20);
			outtex = Result;
			yield return ApplyForestMaskTexture(outtex, ForestTexture);
			outtex = Result;
			yield return GenerateContourMap(Heightmap, graduationHeight, 128);
			Color32[] contours = Result;
			yield return OverlayTexture(outtex, contours);
			outtex = Result;
			yield return OverlayTexture(outtex, shadowmap);
		}

		private static IEnumerator OverlayResultOnMap()
		{
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < MapTexture.Length; i++)
				{
					Result[i] = Color32.op_Implicit(Color.Lerp(Color32.op_Implicit(MapTexture[i]), Color32.op_Implicit(Result[i]), Color32.op_Implicit(Result[i]).a));
					Result[i].a = (byte)(255f * Mathf.Clamp01(Color32.op_Implicit(Result[i]).a + Color32.op_Implicit(MapTexture[i]).a));
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			SetMapTexture(Result);
		}

		private static IEnumerator OverlayTexture(Color32[] array1, Color32[] array2)
		{
			Color32[] output = (Color32[])(object)new Color32[array1.Length];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: 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_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < array1.Length; i++)
				{
					float a = Color32.op_Implicit(array2[i]).a;
					float a2 = Color32.op_Implicit(array1[i]).a;
					Color val = Color.Lerp(Color32.op_Implicit(array1[i]), Color32.op_Implicit(array2[i]), a);
					val.a = a + a2;
					if (val.a > 1f)
					{
						val.a = 1f;
					}
					output[i] = Color32.op_Implicit(val);
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator LerpTextures(Color32[] array1, Color32[] array2)
		{
			Color32[] output = (Color32[])(object)new Color32[TextureSize * TextureSize];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < TextureSize * TextureSize; i++)
				{
					int num = array2[i].a - array1[i].a;
					int num2 = Math.Min(array1[i].a + array2[i].a, 255);
					int num3 = ((array1[i].a > array2[i].a) ? array1[i].a : array2[i].a) * 2;
					float num4 = (float)num / (float)num3 + 0.5f;
					output[i] = Color32.Lerp(array1[i], array2[i], num4);
					output[i].a = (byte)num2;
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator DarkenTextureLinear(Color32[] array, byte d)
		{
			Color32[] output = (Color32[])(object)new Color32[TextureSize * TextureSize];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				for (int i = 0; i < TextureSize * TextureSize; i++)
				{
					int num = array[i].r - d;
					if (num < 0)
					{
						num = 0;
					}
					output[i].r = (byte)num;
					num = array[i].g - d;
					if (num < 0)
					{
						num = 0;
					}
					output[i].g = (byte)num;
					num = array[i].b - d;
					if (num < 0)
					{
						num = 0;
					}
					output[i].b = (byte)num;
					output[i].a = array[i].a;
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator CreateShadowMap(Color32[] heightmap, byte intensity)
		{
			yield return CreateHardShadowMap(heightmap, intensity);
			Color32[] hardshadows = Result;
			yield return CreateSoftShadowMap(heightmap);
			Color32[] softshadows = Result;
			yield return LerpTextures(softshadows, hardshadows);
		}

		private static IEnumerator CreateSoftShadowMap(Color32[] input)
		{
			Color32[] output = (Color32[])(object)new Color32[input.Length];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//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)
				for (int i = 0; i < TextureSize; i++)
				{
					for (int j = 0; j < TextureSize; j++)
					{
						int num = i * TextureSize + j;
						int num2 = ((i > 0) ? (input[num].r - input[(i - 1) * TextureSize + j].r) : 0);
						num2 *= 8;
						byte b = (byte)Math.Abs(num2);
						byte b2 = (byte)((num2 >= 0) ? byte.MaxValue : 0);
						output[num] = new Color32(b2, b2, b2, b);
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator CreateHardShadowMap(Color32[] input, byte intensity)
		{
			Color32[] output = (Color32[])(object)new Color32[input.Length];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				bool[] array = new bool[TextureSize * TextureSize];
				for (int i = 0; i < TextureSize * TextureSize; i++)
				{
					array[i] = false;
				}
				for (int j = 0; j < TextureSize; j++)
				{
					for (int k = 0; k < TextureSize; k++)
					{
						int num = j * TextureSize + k;
						if (!array[num])
						{
							output[num] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)0);
							for (int l = 1; j + l < TextureSize && input[num].r > input[(j + l) * TextureSize + k].r + l * 2; l++)
							{
								array[(j + l) * TextureSize + k] = true;
							}
						}
						else
						{
							output[num] = new Color32((byte)0, (byte)0, (byte)0, intensity);
						}
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator GenerateOceanTexture(Color32[] input, Color32[] biomeColor, float oceanLerpTarget = 0.1f)
		{
			Color32[] output = (Color32[])(object)new Color32[input.Length];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: 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_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < TextureSize * TextureSize; i++)
				{
					if (input[i].b == 0)
					{
						output[i] = Color32.op_Implicit(Color.clear);
					}
					else
					{
						int num = i / TextureSize / 16 - 128;
						int num2 = i % TextureSize / 16 - 128;
						int num3 = num * num / 128 + num2 * num2 / 512;
						if (num < 0)
						{
							output[i].r = (byte)(10 + num3);
							output[i].g = (byte)(136 - num3 / 4);
							output[i].b = 193;
						}
						else
						{
							output[i].r = (byte)(10 + num3 / 2);
							output[i].g = 136;
							output[i].b = (byte)(193 - num3 / 2);
						}
						output[i].a = (byte)Math.Min(input[i].b * 16 + 128, 255);
						if (Color32.op_Implicit(biomeColor[i]) == Color.blue)
						{
							output[i] = Color32.Lerp(output[i], oceanColor, oceanLerpTarget);
						}
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator GetPerlin(int tightness, byte damping)
		{
			for (int i = 0; i < Result.Length; i++)
			{
				Result[i] = new Color32((byte)0, (byte)0, (byte)0, (byte)0);
			}
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				for (int j = 0; j < TextureSize; j++)
				{
					for (int k = 0; k < TextureSize; k++)
					{
						float num = Mathf.PerlinNoise((float)j / (float)tightness, (float)k / (float)tightness);
						num = (num - 0.5f) / (float)(int)damping + 0.5f;
						Result[j * TextureSize + k] = Color32.op_Implicit(new Color(num, num, num, 0.2f));
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
		}

		private static int[] BuildExploredIntegral()
		{
			int textureSize = TextureSize;
			int num = textureSize + 1;
			int[] array = new int[num * num];
			for (int i = 1; i <= textureSize; i++)
			{
				int num2 = i * num;
				int num3 = (i - 1) * num;
				int num4 = (i - 1) * textureSize;
				for (int j = 1; j <= textureSize; j++)
				{
					int num5 = (ExploredData[num4 + j - 1] ? 1 : 0);
					array[num2 + j] = num5 + array[num2 + j - 1] + array[num3 + j] - array[num3 + j - 1];
				}
			}
			return array;
		}

		private static bool IsNearExplored(int[] integral, int x, int y, int range)
		{
			return GetExploredCount(integral, x, y, range) > 0;
		}

		private static int GetExploredCount(int[] integral, int x, int y, int range)
		{
			int textureSize = TextureSize;
			int num = textureSize + 1;
			int num2 = Math.Max(0, x - range);
			int num3 = Math.Min(textureSize - 1, x + range);
			int num4 = Math.Max(0, y - range);
			int num5 = Math.Min(textureSize - 1, y + range);
			int num6 = num2;
			int num7 = num4;
			int num8 = num3 + 1;
			int num9 = num5 + 1;
			return integral[num8 * num + num9] - integral[num6 * num + num9] - integral[num8 * num + num7] + integral[num6 * num + num7];
		}

		private static float GetContourDistanceAlpha(int[] exploredIntegral, int x, int y, int contourDistance, float contourAlphaMax)
		{
			int num = Math.Max(1, contourDistance);
			int num2 = Math.Max(num + 1, contourDistance * 2);
			int exploredCount = GetExploredCount(exploredIntegral, x, y, num);
			if (exploredCount > 0)
			{
				return contourAlphaMax;
			}
			int exploredCount2 = GetExploredCount(exploredIntegral, x, y, num2);
			if (exploredCount2 <= 0)
			{
				return 0f;
			}
			int num3 = (num * 2 + 1) * (num * 2 + 1);
			int num4 = (num2 * 2 + 1) * (num2 * 2 + 1);
			int num5 = Math.Max(1, num4 - num3);
			float num6 = (float)(exploredCount2 - exploredCount) / (float)num5;
			float num7 = Mathf.Clamp01(num6 * 5f);
			float num8 = Mathf.Pow(num7, 1.5f);
			return contourAlphaMax * num8;
		}

		private static IEnumerator StylizeFog()
		{
			bool customFog = fog != null;
			if (!customFog)
			{
				yield return GetPerlin(128, 16);
				fog = Result;
				fogRes = TextureSize;
			}
			float contourAlphaFactor = Math.Max(0f, NomapPrinter.fogContoursAlpha.Value);
			int contourDistance = Math.Max(0, NomapPrinter.fogContoursDistance.Value);
			bool haveContours = NomapPrinter.fogContoursEnabled.Value && contours != null && contourDistance > 0;
			int[] exploredIntegral = (haveContours ? BuildExploredIntegral() : null);
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < TextureSize; i++)
				{
					for (int j = 0; j < TextureSize; j++)
					{
						int num = i * TextureSize + j;
						if (!ExploredData[num])
						{
							Color32 val = fog[i % fogRes * fogRes + j % fogRes];
							if (customFog)
							{
								Result[num] = val;
							}
							else
							{
								Result[num] = new Color32((byte)(yellowMap.r + (val.r - 128)), (byte)(yellowMap.g + (val.g - 128)), (byte)(yellowMap.b + (val.b - 128)), byte.MaxValue);
							}
							if (haveContours && IsNearExplored(exploredIntegral, i, j, contourDistance * 2))
							{
								Color32 val2 = contours[i % contoursRes * contoursRes + j % contoursRes];
								if (val2.a > 0)
								{
									float contourDistanceAlpha = GetContourDistanceAlpha(exploredIntegral, i, j, contourDistance, contourAlphaFactor);
									float num2 = (float)(int)val2.a / 255f * contourDistanceAlpha;
									Result[num] = Color32.Lerp(Result[num], val2, num2);
									Result[num].a = byte.MaxValue;
								}
							}
						}
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
		}

		public static IEnumerator GenerateContourMap(Color32[] start, int graduations, byte alpha)
		{
			Color32[] input = (Color32[])(object)new Color32[start.Length];
			Color32[] output = (Color32[])(object)new Color32[input.Length];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0199: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0184: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < TextureSize * TextureSize; i++)
				{
					int num = ((start[i].b <= 0) ? Math.Min(start[i].r + graduations, 255) : 0);
					input[i].r = (byte)num;
				}
				for (int j = 1; j < TextureSize - 1; j++)
				{
					int num2 = j * TextureSize;
					for (int k = 1; k < TextureSize - 1; k++)
					{
						int num3 = num2 + k;
						int num4 = input[num2 + k].r / graduations;
						output[num3] = Color32.op_Implicit(Color.clear);
						for (int l = -1; l < 2; l++)
						{
							int num5 = l * TextureSize;
							for (int m = -1; m < 2; m++)
							{
								if (l != 0 || m != 0)
								{
									int num6 = num3 + num5 + m;
									int num7 = input[num6].r / graduations;
									if (num7 < num4)
									{
										byte b = alpha;
										if (num4 % 5 - 1 != 0)
										{
											b /= 2;
										}
										if (l == 0 || m == 0 || output[num3].a == b)
										{
											output[num3] = new Color32((byte)0, (byte)0, (byte)0, b);
											break;
										}
										output[num3] = new Color32((byte)0, (byte)0, (byte)0, (byte)(b / 2));
									}
								}
							}
						}
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator AddPerlinNoise(Color32[] input, int tightness, byte damping)
		{
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < TextureSize; i++)
				{
					for (int j = 0; j < TextureSize; j++)
					{
						int num = i * TextureSize + j;
						Color val = Color32.op_Implicit(input[num]);
						float num2 = Mathf.PerlinNoise((float)i / (float)tightness, (float)j / (float)tightness);
						num2 = (num2 - 0.5f) / (float)(int)damping;
						Result[num] = Color32.op_Implicit(new Color(val.r + num2, val.g + num2, val.b + num2, val.a));
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
		}

		private static IEnumerator GetSolidColour(Color32 TexColour)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[TextureSize * TextureSize];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = TexColour;
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = array;
		}

		private static IEnumerator ReplaceAbyssWithColor(Color32[] input, Color32 from, Color32 to)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Color32[] output = (Color32[])(object)new Color32[input.Length];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: 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)
				for (int i = 0; i < input.Length; i++)
				{
					if (input[i].r == from.r && input[i].g == from.g && input[i].b == from.b)
					{
						output[i] = to;
					}
					else
					{
						output[i] = input[i];
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator ReplaceAbyssWithSpace(Color32[] input, Color32 from)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Color32[] output = (Color32[])(object)new Color32[input.Length];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < TextureSize; i++)
				{
					for (int j = 0; j < TextureSize; j++)
					{
						int num = i * TextureSize + j;
						if (input[num].r == from.r && input[num].g == from.g && input[num].b == from.b)
						{
							output[num] = space[i % spaceRes * spaceRes + j % spaceRes];
						}
						else
						{
							output[num] = input[num];
						}
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		private static IEnumerator ApplyForestMaskTexture(Color32[] array, Color[] forestMask, float forestColorFactor = 0.9f)
		{
			Color32[] output = (Color32[])(object)new Color32[TextureSize * TextureSize];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0167: Unknown result type (might be due to invalid IL or missing references)
				//IL_018d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01df: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_023d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0242: Unknown result type (might be due to invalid IL or missing references)
				//IL_0264: Unknown result type (might be due to invalid IL or missing references)
				//IL_0269: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02db: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < TextureSize * TextureSize; i++)
				{
					if (forestMask[i] == clearMask)
					{
						output[i] = array[i];
					}
					else
					{
						if (forestMask[i].r > 0f)
						{
							float num = 1f - (1f - forestColorFactor) * forestMask[i].r;
							output[i].r = (byte)((float)(int)array[i].r * num);
							output[i].g = (byte)((float)(int)array[i].g * num);
							output[i].b = (byte)((float)(int)array[i].b * num);
						}
						if (forestMask[i].g > 0f)
						{
							float wy = ((float)(i / TextureSize) / (float)TextureSize - 0.5f) * 400f;
							float wx = ((float)(i % TextureSize) / (float)TextureSize - 0.5f) * 400f;
							output[i] = Color32.Lerp(array[i], mistColor, forestMask[i].g * GetMistlandsNoise(wx, wy) * 0.9f);
						}
						if (forestMask[i].b > 0f)
						{
							output[i] = Color32.Lerp(array[i], lavaColor, forestMask[i].b);
						}
						if (forestMask[i].a != 1f)
						{
							if (forestMask[i].a >= 0.5f)
							{
								output[i] = Color32.Lerp(array[i], lavaColor, (forestMask[i].a - 0.5f) / 0.5f);
							}
							if (0f <= forestMask[i].a && forestMask[i].a < 0.5f)
							{
								output[i] = Color32.Lerp(array[i], northColor, forestMask[i].a / 0.5f);
							}
						}
						output[i].a = array[i].a;
					}
				}
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			Result = output;
		}

		public static float GetMistlandsNoise(float wx, float wy)
		{
			float num = 1f * Mathf.PerlinNoise(1f * wx, 1f * wy) + 0.5f * Mathf.PerlinNoise(2f * wx, 2f * wy) + 0.25f * Mathf.PerlinNoise(4f * wx, 4f * wy) + 0.125f * Mathf.PerlinNoise(8f * wx, 8f * wy);
			return num / 1.875f;
		}
	}
	public static class MapMaker
	{
		public class WorldMapData
		{
			public const int _textureSize = 4096;

			public const int _pixelSize = 6;

			public const string cacheFileName = "worldData";

			public const int version = 2;

			public long worldUID;

			public Thread[] threads;

			public bool initialized = false;

			public Texture2D m_mapTexture;

			public Texture2D m_forestTexture;

			public Texture2D m_heightmap;

			public Texture2D m_contoursTexture;

			public static int TextureSize => (int)(4096f * NomapPrinter.mapSizeMultiplier.Value);

			public static int PixelSize => (int)(6f * NomapPrinter.mapSizeMultiplier.Value);

			public WorldMapData(long worldUID)
			{
				this.worldUID = worldUID;
			}

			public IEnumerator Init()
			{
				if (initialized)
				{
					threads = null;
					yield break;
				}
				if (LoadFromCache())
				{
					NomapPrinter.LogInfo("World data loaded from cache");
					initialized = true;
					yield break;
				}
				yield return (object)new WaitUntil((Func<bool>)(() => WorldGenerator.instance != null && (Object)(object)ZoneSystem.instance != (Object)null));
				Color32[] m_mapTextureArray = (Color32[])(object)new Color32[TextureSize * TextureSize];
				Color[] m_forestTextureArray = (Color[])(object)new Color[TextureSize * TextureSize];
				Color32[] m_heightmapArray = (Color32[])(object)new Color32[TextureSize * TextureSize];
				if (!initialized && threads == null)
				{
					threads = new Thread[4]
					{
						new Thread((ThreadStart)delegate
						{
							FillMapPart(0, 0, m_mapTextureArray, m_forestTextureArray, m_heightmapArray);
						}),
						new Thread((ThreadStart)delegate
						{
							FillMapPart(0, 1, m_mapTextureArray, m_forestTextureArray, m_heightmapArray);
						}),
						new Thread((ThreadStart)delegate
						{
							FillMapPart(1, 0, m_mapTextureArray, m_forestTextureArray, m_heightmapArray);
						}),
						new Thread((ThreadStart)delegate
						{
							FillMapPart(1, 1, m_mapTextureArray, m_forestTextureArray, m_heightmapArray);
						})
					};
					CollectionExtensions.Do<Thread>((IEnumerable<Thread>)threads, (Action<Thread>)delegate(Thread thread)
					{
						thread.Start();
					});
				}
				yield return (object)new WaitWhile((Func<bool>)(() => threads != null && threads.Any((Thread thread) => thread.IsAlive)));
				m_mapTexture = new Texture2D(TextureSize, TextureSize, (TextureFormat)3, false)
				{
					name = "NomapPrinter_m_mapTexture",
					wrapMode = (TextureWrapMode)1
				};
				m_forestTexture = new Texture2D(TextureSize, TextureSize, (TextureFormat)4, false)
				{
					name = "NomapPrinter_m_forestTexture",
					wrapMode = (TextureWrapMode)1
				};
				m_heightmap = new Texture2D(TextureSize, TextureSize, (TextureFormat)3, false)
				{
					name = "NomapPrinter_m_heightmap",
					wrapMode = (TextureWrapMode)1
				};
				m_mapTexture.SetPixels32(m_mapTextureArray);
				m_mapTexture.Apply();
				yield return null;
				m_forestTexture.SetPixels(m_forestTextureArray);
				m_forestTexture.Apply();
				yield return null;
				m_heightmap.SetPixels32(m_heightmapArray);
				m_heightmap.Apply();
				yield return null;
				yield return MapGenerator.GenerateContourMap(m_heightmapArray, 8, 128);
				m_contoursTexture = new Texture2D(TextureSize, TextureSize, (TextureFormat)4, false)
				{
					name = "NomapPrinter_m_contoursTexture",
					wrapMode = (TextureWrapMode)1
				};
				m_contoursTexture.SetPixels32(MapGenerator.Result);
				m_contoursTexture.Apply();
				yield return null;
				threads = null;
				initialized = true;
				SaveToCache();
			}

			private void FillMapPart(int partX, int partY, Color32[] mapTextureArray, Color[] forestTextureArray, Color32[] heightmapArray)
			{
				for (int i = partX * TextureSize / 2; i < (partX + 1) * TextureSize / 2; i++)
				{
					for (int j = partY * TextureSize / 2; j < (partY + 1) * TextureSize / 2; j++)
					{
						FillMap(i, j, mapTextureArray, forestTextureArray, heightmapArray);
					}
				}
			}

			private void FillMap(int i, int j, Color32[] mapTextureArray, Color[] forestTextureArray, Color32[] heightmapArray)
			{
				//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_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_012f: Invalid comparison between Unknown and I4
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_014f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: 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_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				float num = (float)((i - TextureSize / 2) * PixelSize) + (float)PixelSize / 2f;
				float num2 = (float)((j - TextureSize / 2) * PixelSize) + (float)PixelSize / 2f;
				int num3 = i * TextureSize + j;
				if (DUtils.Length(num2, num) > NomapPrinter.worldSize.Value)
				{
					mapTextureArray[num3] = MapGenerator.abyssColor;
					return;
				}
				Biome biome = WorldGenerator.instance.GetBiome(num2, num, 0.02f, false);
				Color val = default(Color);
				float biomeHeight = WorldGenerator.instance.GetBiomeHeight(biome, num2, num, ref val, false);
				if (biomeHeight < -100f)
				{
					mapTextureArray[num3] = MapGenerator.abyssColor;
					return;
				}
				float num4 = biomeHeight - ZoneSystem.instance.m_waterLevel;
				forestTextureArray[num3] = GetMaskColor(num2, num, num4, biome);
				if (num4 > 0f)
				{
					heightmapArray[num3] = Color32.op_Implicit(new Color(num4 / Mathf.Pow(2f, 9f), 0f, 0f));
				}
				else
				{
					heightmapArray[num3] = Color32.op_Implicit(new Color(0f, 0f, num4 / (0f - Mathf.Pow(2f, (float)(8 + (((int)biome == 2) ? 1 : 0))))));
				}
				mapTextureArray[num3] = Color32.op_Implicit(GetPixelColor(biome, biomeHeight));
			}

			private string CacheFile()
			{
				return Path.Combine(CacheDirectory(), ZNet.instance.GetWorldName() + "_worldData");
			}

			private bool LoadFromCache()
			{
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Expected O, but got Unknown
				//IL_012f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Expected O, but got Unknown
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Expected O, but got Unknown
				//IL_0191: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Expected O, but got Unknown
				string text = CacheFile();
				if (!File.Exists(text))
				{
					NomapPrinter.LogInfo("File not found: " + text);
					return false;
				}
				byte[] array;
				try
				{
					array = File.ReadAllBytes(text);
				}
				catch (Exception ex)
				{
					NomapPrinter.LogWarning("Error reading file (" + text + ")! Error: " + ex.Message);
					return false;
				}
				ZPackage val = new ZPackage(array);
				int num = val.ReadInt();
				if (2 != num)
				{
					NomapPrinter.LogWarning("World data (" + text + "): Version mismatch");
					return false;
				}
				try
				{
					worldUID = val.ReadLong();
					if (TextureSize != val.ReadInt())
					{
						return false;
					}
					if (PixelSize != val.ReadInt())
					{
						return false;
					}
					if ((Object)(object)m_mapTexture == (Object)null)
					{
						m_mapTexture = new Texture2D(2, 2);
					}
					ImageConversion.LoadImage(m_mapTexture, val.ReadByteArray());
					if ((Object)(object)m_forestTexture == (Object)null)
					{
						m_forestTexture = new Texture2D(2, 2);
					}
					ImageConversion.LoadImage(m_forestTexture, val.ReadByteArray());
					if ((Object)(object)m_heightmap == (Object)null)
					{
						m_heightmap = new Texture2D(2, 2);
					}
					ImageConversion.LoadImage(m_heightmap, val.ReadByteArray());
					if ((Object)(object)m_contoursTexture == (Object)null)
					{
						m_contoursTexture = new Texture2D(2, 2);
					}
					ImageConversion.LoadImage(m_contoursTexture, val.ReadByteArray());
				}
				catch (Exception ex2)
				{
					NomapPrinter.LogWarning("Error reading file (" + text + ")! Error: " + ex2.Message);
					DestroyTextures();
					return false;
				}
				return true;
			}

			private void SaveToCache()
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ZPackage val = new ZPackage();
				val.Write(2);
				val.Write(worldUID);
				val.Write(TextureSize);
				val.Write(PixelSize);
				val.Write(ImageConversion.EncodeToPNG(m_mapTexture));
				val.Write(ImageConversion.EncodeToPNG(m_forestTexture));
				val.Write(ImageConversion.EncodeToPNG(m_heightmap));
				val.Write(ImageConversion.EncodeToPNG(m_contoursTexture));
				string text = CacheFile();
				try
				{
					File.WriteAllBytes(text, val.GetArray());
				}
				catch (Exception ex)
				{
					NomapPrinter.LogWarning("Error writing file (" + text + ")! Error: " + ex.Message);
				}
			}

			internal void DestroyTextures()
			{
				Object.Destroy((Object)(object)m_mapTexture);
				Object.Destroy((Object)(object)m_forestTexture);
				Object.Destroy((Object)(object)m_heightmap);
				Object.Destroy((Object)(object)m_contoursTexture);
			}
		}

		public class ExploredMapData
		{
			public const string exploredMapFileName = "mapData";

			public const int version = 2;

			public Texture2D exploredMap;

			public NomapPrinter.MapType exploredMapType;

			public void Init(Color32[] mapData, NomapPrinter.MapType mapType)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				int num = (int)Math.Sqrt(mapData.Length);
				exploredMap = new Texture2D(num, num, (TextureFormat)4, false, false);
				exploredMap.SetPixels32(mapData);
				exploredMap.Apply(false);
				exploredMapType = mapType;
				SaveExploredMap();
			}

			private string ExploredMapFileName()
			{
				return Path.Combine(CacheDirectory(), string.Format("{0}_{1}", "mapData", exploredMapType));
			}

			private bool LoadFromCustomFile()
			{
				if (!NomapPrinter.useCustomExploredLayer.Value)
				{
					return false;
				}
				exploredMap = GetLayerTexture("explored", NomapPrinter.syncExploredLayerFromServer.Value);
				return (Object)(object)exploredMap != (Object)null;
			}

			public bool LoadExploredMap()
			{
				if ((Object)(object)exploredMap != (Object)null && exploredMapType == NomapPrinter.mapType.Value)
				{
					return true;
				}
				ResetExploredMap();
				return LoadFromCustomFile() || LoadExploredMapFromFile();
			}

			public void ResetExploredMap()
			{
				if ((Object)(object)exploredMap != (Object)null)
				{
					Object.Destroy((Object)(object)exploredMap);
				}
				exploredMap = null;
				exploredMapType = NomapPrinter.mapType.Value;
			}

			private bool LoadExploredMapFromFile()
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Expected O, but got Unknown
				string text = ExploredMapFileName();
				byte[] packedImageData = GetPackedImageData(text);
				if (packedImageData == null)
				{
					return false;
				}
				try
				{
					exploredMap = new Texture2D(2, 2);
					return ImageConversion.LoadImage(exploredMap, packedImageData);
				}
				catch (Exception ex)
				{
					NomapPrinter.LogWarning("Error loading map image (" + text + ")! Error: " + ex.Message);
				}
				return false;
			}

			public static byte[] GetPackedImageData(string filename)
			{
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Expected O, but got Unknown
				if (!File.Exists(filename))
				{
					NomapPrinter.LogInfo("File not found: " + filename);
					return null;
				}
				byte[] array;
				try
				{
					array = File.ReadAllBytes(filename);
				}
				catch (Exception ex)
				{
					NomapPrinter.LogWarning("Error reading file (" + filename + ")! Error: " + ex.Message);
					return null;
				}
				ZPackage val = new ZPackage(array);
				if (2 != val.ReadInt())
				{
					NomapPrinter.LogWarning("World map data (" + filename + "): Version mismatch");
					return null;
				}
				array = val.ReadByteArray();
				byte[] bytes = new UTF8Encoding().GetBytes("shudnal.NomapPrinter");
				for (int i = 0; i < array.Length; i++)
				{
					array[i] ^= bytes[i % bytes.Length];
				}
				return array;
			}

			public static byte[] GetPackedImageData(byte[] data)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ZPackage val = new ZPackage();
				val.Write(2);
				byte[] bytes = new UTF8Encoding().GetBytes("shudnal.NomapPrinter");
				for (int i = 0; i < data.Length; i++)
				{
					data[i] ^= bytes[i % bytes.Length];
				}
				val.Write(data);
				return val.GetArray();
			}

			private void SaveExploredMap()
			{
				if ((Object)(object)exploredMap == (Object)null)
				{
					return;
				}
				string text = ExploredMapFileName();
				try
				{
					File.WriteAllBytes(text, GetPackedImageData(ImageConversion.EncodeToPNG(exploredMap)));
				}
				catch (Exception ex)
				{
					NomapPrinter.LogWarning("Error writing file (" + text + ")! Error: " + ex.Message);
				}
			}
		}

		public static WorldMapData worldMapData;

		public static ExploredMapData exploredMapData = new ExploredMapData();

		public const float abyss_depth = -100f;

		public const string worldDataPrefix = "NomapPrinter_Exploration_";

		public const int heightmapFactor = 8;

		public const int graduationLinesDensity = 8;

		public static bool isWorking = false;

		private static IEnumerator worker;

		public static Texture2D mapTexture = new Texture2D(WorldMapData.TextureSize, WorldMapData.TextureSize, (TextureFormat)3, false);

		private static readonly Dictionary<string, Color32[]> pinIcons = new Dictionary<string, Color32[]>();

		private static readonly Dictionary<string, Color32[]> pinIconsDouble = new Dictionary<string, Color32[]>();

		private static Texture2D iconSpriteTexture;

		private static int iconSize = 32;

		private static long worldUID;

		private static Texture2D noClouds;

		private static bool[] exploration;

		private static Color32[] cachedContours;

		private static long cachedContoursWorldUID;

		private static int cachedContoursTextureSize;

		private static Color32[] stripeBuffer;

		private static int GetPinGroup(PinType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected I4, but got Unknown
			switch ((int)type)
			{
			case 4:
			case 7:
			case 10:
			case 12:
			case 13:
				return 0;
			case 0:
			case 1:
			case 2:
			case 3:
			case 6:
				return 1;
			case 5:
			case 9:
			case 11:
				return 3;
			case 14:
			case 15:
			case 16:
				return 4;
			case 8:
				return 5;
			default:
				return 2;
			}
		}

		public static void ResetExploredMap()
		{
			exploredMapData?.ResetExploredMap();
		}

		public static void ResetExploredMapOnTextureChange()
		{
			if (NomapPrinter.useCustomExploredLayer.Value)
			{
				exploredMapData?.ResetExploredMap();
			}
		}

		public static void GenerateMap()
		{
			if (NomapPrinter.saveMapToFile.Value || Game.m_noMap)
			{
				if (isWorking && worker != null)
				{
					((MonoBehaviour)NomapPrinter.instance).StopCoroutine(worker);
					worker = null;
				}
				worldUID = ZNet.instance.GetWorldUID();
				worker = CreateMap();
				((MonoBehaviour)NomapPrinter.instance).StartCoroutine(worker);
			}
		}

		public static void PregenerateMap()
		{
			worldUID = ZNet.instance.GetWorldUID();
			((MonoBehaviour)NomapPrinter.instance).StartCoroutine(CreateMap(pregeneration: true));
		}

		public static void PreloadExploredMap()
		{
			worldUID = ZNet.instance.GetWorldUID();
			if (exploredMapData == null)
			{
				exploredMapData = new ExploredMapData();
			}
			if (NomapPrinter.mapType.Value != NomapPrinter.MapType.Vanilla)
			{
				if (exploredMapData.LoadExploredMap())
				{
					NomapPrinter.LogInfo($"Preloaded map data for world {worldUID} {ZNet.instance.GetWorldName()}");
				}
				if (NomapPrinter.fogContoursEnabled.Value && NomapPrinter.fogContoursDistance.Value > 0)
				{
					((MonoBehaviour)NomapPrinter.instance).StartCoroutine(PrepareFogContours());
				}
			}
		}

		private static string CacheDirectory()
		{
			Directory.CreateDirectory(NomapPrinter.cacheDirectory);
			string text = Path.Combine(NomapPrinter.cacheDirectory, worldUID.ToString());
			Directory.CreateDirectory(text);
			return text;
		}

		private static IEnumerator CreateMap(bool pregeneration = false)
		{
			isWorking = true;
			InitIconSize();
			bool haveExploration = GetPlayerExploration(Player.m_localPlayer, worldUID);
			if (NomapPrinter.mapType.Value == NomapPrinter.MapType.Vanilla)
			{
				if (!pregeneration)
				{
					NomapPrinter.ShowMessage("$nomapprinter_start", (MessageType)2);
					yield return GetVanillaMap(2048 * (int)NomapPrinter.mapSize.Value, haveExploration);
				}
			}
			else
			{
				if (!pregeneration)
				{
					NomapPrinter.ShowMessage("$nomapprinter_start", (MessageType)2);
				}
				if (!exploredMapData.LoadExploredMap())
				{
					yield return PrepareTerrainData();
					if (!pregeneration)
					{
						NomapPrinter.ShowMessage("$nomapprinter_saving", (MessageType)2);
					}
					yield return MapGenerator.Initialize();
					yield return PrepareMap(NomapPrinter.mapType.Value);
					exploredMapData.Init(MapGenerator.Result, NomapPrinter.mapType.Value);
				}
				else
				{
					NomapPrinter.LogInfo("World map data loaded from cache");
				}
				yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Player.m_localPlayer != (Object)null));
				if (haveExploration)
				{
					if (NomapPrinter.fogContoursEnabled.Value && NomapPrinter.fogContoursDistance.Value > 0)
					{
						yield return PrepareFogContours();
					}
					MapGenerator.SetMapTexture(exploredMapData.exploredMap);
					if (NomapPrinter.useCustomUnderFogLayer.Value)
					{
						yield return OverlayMarkingsLayer();
					}
					if (NomapPrinter.useCustomFogLayer.Value)
					{
						OverrideFogTexture();
					}
					yield return MapGenerator.OverlayExplorationFog(exploration);
					if (NomapPrinter.useCustomOverFogLayer.Value)
					{
						yield return OverlayMarkingsLayer(overFog: true);
					}
					yield return ApplyMapTexture(MapGenerator.Result);
					NomapPrinter.ShowMessage("$nomapprinter_ready", (MessageType)2);
				}
				MapGenerator.DeInitializeTextures();
			}
			if (!pregeneration && MapViewer.IsMapReady() && NomapPrinter.saveMapToFile.Value)
			{
				string filename = NomapPrinter.filePath.Value;
				if (Utility.IsNullOrWhiteSpace(filename))
				{
					filename = Path.Combine(NomapPrinter.LocalPath, "screenshots", $"{NomapPrinter.mapType.Value}.{ZNet.instance.GetWorldName()}.png");
				}
				else
				{
					FileAttributes attr = File.GetAttributes(filename);
					if (attr.HasFlag(FileAttributes.Directory))
					{
						filename = Path.Combine(filename, $"{NomapPrinter.mapType.Value}.{ZNet.instance.GetWorldName()}.png");
					}
				}
				string filepath = Path.GetDirectoryName(filename);
				NomapPrinter.LogInfo("Writing " + filename);
				Thread internalThread = new Thread((ThreadStart)delegate
				{
					Directory.CreateDirectory(filepath);
					File.WriteAllBytes(filename, ImageConversion.EncodeToPNG(mapTexture));
				});
				internalThread.Start();
				while (internalThread.IsAlive)
				{
					yield return null;
				}
				NomapPrinter.ShowMessage("$nomapprinter_savedto " + filepath, (MessageType)1);
			}
			NomapPrinter.LogInfo("Finished Map Draw");
			isWorking = false;
		}

		private static IEnumerator PrepareTerrainData()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => WorldGenerator.instance != null));
			Stopwatch stopwatch = Stopwatch.StartNew();
			long uid = ((worldUID == 0L) ? WorldGenerator.m_instance.m_world.m_uid : worldUID);
			worldMapData?.DestroyTextures();
			NomapPrinter.LogInfo($"Preparing terrain data for world {uid} started");
			worldMapData = new WorldMapData(uid);
			yield return worldMapData.Init();
			NomapPrinter.LogInfo($"Terrain data for world {uid} is ready in {stopwatch.ElapsedMilliseconds,-4:F2} ms");
		}

		private static IEnumerator PrepareMap(NomapPrinter.MapType mapType)
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			MapGenerator.InitializeTextures(worldMapData.m_mapTexture, worldMapData.m_forestTexture, worldMapData.m_heightmap);
			switch (mapType)
			{
			case NomapPrinter.MapType.BirdsEye:
				yield return MapGenerator.GenerateSatelliteImage();
				break;
			case NomapPrinter.MapType.Topographical:
				yield return MapGenerator.GenerateTopographicalMap(8);
				break;
			default:
				yield return MapGenerator.GenerateChartMap(8);
				break;
			case NomapPrinter.MapType.OldChart:
				yield return MapGenerator.GenerateOldMap(8);
				break;
			}
			NomapPrinter.LogInfo($"Prepared map data {mapType} for world {worldUID} in {stopwatch.ElapsedMilliseconds,-4:F2} ms");
		}

		private static bool HasCachedContours()
		{
			return cachedContours != null && cachedContoursWorldUID == worldUID && cachedContoursTextureSize == WorldMapData.TextureSize;
		}

		private static void CacheContours(Color32[] contourData)
		{
			if (contourData != null && contourData.Length != 0)
			{
				cachedContours = (Color32[])(object)new Color32[contourData.Length];
				contourData.CopyTo(cachedContours, 0);
				cachedContoursWorldUID = worldUID;
				cachedContoursTextureSize = WorldMapData.TextureSize;
			}
		}

		private static IEnumerator PrepareFogContours()
		{
			if (HasCachedContours())
			{
				MapGenerator.SetContoursTexture(cachedContours);
				yield break;
			}
			if (worldMapData == null || !worldMapData.initialized || (Object)(object)worldMapData.m_contoursTexture == (Object)null)
			{
				yield return PrepareTerrainData();
			}
			if (!((Object)(object)worldMapData?.m_contoursTexture == (Object)null))
			{
				CacheContours(worldMapData.m_contoursTexture.GetPixels32());
				MapGenerator.SetContoursTexture(cachedContours);
			}
		}

		private static bool GetPlayerExploration(Player player, long worldUID)
		{
			if (!player.m_customData.TryGetValue(WorldDataName(worldUID), out var value))
			{
				return false;
			}
			BitArray bitArray = new BitArray(Utils.Decompress(Convert.FromBase64String(value)));
			if (exploration == null || exploration.Length != bitArray.Count)
			{
				exploration = new bool[bitArray.Count];
			}
			bitArray.CopyTo(exploration, 0);
			return true;
		}

		public static void SavePlayerExploration()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			exploration = Minimap.instance.m_explored.ToArray();
			if (NomapPrinter.showSharedMap.Value)
			{
				for (int i = 0; i < exploration.Length; i++)
				{
					exploration[i] = exploration[i] || Minimap.instance.m_exploredOthers[i];
				}
			}
			BitArray bitArray = new BitArray(exploration);
			byte[] array = new byte[(bitArray.Length - 1) / 8 + 1];
			bitArray.CopyTo(array, 0);
			SaveValue(WorldDataName(ZNet.instance.GetWorldUID()), Convert.ToBase64String(Utils.Compress(array)));
			NomapPrinter.LogInfo($"Exploration saved in {stopwatch.ElapsedMilliseconds,-4:F2} ms");
			static void SaveValue(string key, string value)
			{
				if (Player.m_localPlayer.m_customData.ContainsKey(key))
				{
					Player.m_localPlayer.m_customData[key] = value;
				}
				else
				{
					Player.m_localPlayer.m_customData.Add(key, value);
				}
			}
		}

		private static string WorldDataName(long worldUID)
		{
			return "NomapPrinter_Exploration_" + worldUID;
		}

		private static IEnumerator GetVanillaMap(int resolution, bool haveExploration)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)Minimap.instance != (Object)null));
			bool wasOpen = Minimap.instance.m_largeRoot.activeSelf;
			if (!wasOpen)
			{
				bool nomap = Game.m_noMap;
				if (nomap)
				{
					Game.m_noMap = false;
				}
				Minimap.instance.inputDelay = 0.5f;
				Minimap.instance.SetMapMode((MapMode)2);
				Minimap.instance.CenterMap(Vector3.zero);
				if (nomap)
				{
					Game.m_noMap = true;
				}
			}
			if ((Object)(object)noClouds == (Object)null)
			{
				noClouds = new Texture2D(1, 1);
				noClouds.SetPixels((Color[])(object)new Color[1] { Color.clear });
				noClouds.Apply(false);
			}
			Material material = Minimap.instance.m_mapLargeShader;
			Texture clouds = material.GetTexture("_CloudTex");
			bool m_showSharedMapData = Minimap.instance.m_showSharedMapData;
			bool replaceSharedMapToggle = NomapPrinter.showSharedMap.Value != Minimap.instance.m_showSharedMapData;
			if (replaceSharedMapToggle)
			{
				material.SetFloat("_SharedFade", NomapPrinter.showSharedMap.Value ? 1f : 0f);
			}
			Color32[] fogTex = Minimap.instance.m_fogTexture.GetPixels32();
			bool combineFog = !NomapPrinter.preserveSharedMapFog.Value && NomapPrinter.showSharedMap.Value;
			Color[] pixels = Minimap.instance.m_fogTexture.GetPixels();
			for (int i = 0; i < pixels.Length; i++)
			{
				if (haveExploration && !exploration[i])
				{
					pixels[i] = Color.white;
				}
				else if (combineFog && pixels[i].g == 0f && pixels[i].r != 0f)
				{
					pixels[i].r = pixels[i].g;
				}
			}
			Minimap.instance.m_fogTexture.SetPixels(pixels);
			Minimap.instance.m_fogTexture.Apply();
			GameObject mapPanelObject = InitMapPanel(material);
			RenderTexture renderTexture = (RenderTexture.active = new RenderTexture(resolution, resolution, 24));
			EnvSetup env = EnvMan.instance.GetCurrentEnvironment();
			float m_sunAngle = env.m_sunAngle;
			float m_smoothDayFraction = EnvMan.instance.m_smoothDayFraction;
			Vector3 m_dirLight = ((Component)EnvMan.instance.m_dirLight).transform.forward;
			EnvMan.instance.m_smoothDayFraction = 0.5f;
			env.m_sunAngle = 60f;
			EnvMan.instance.SetEnv(env, 1f, 0f, 0f, 0f, Time.fixedDeltaTime);
			((Component)EnvMan.instance.m_dirLight).transform.forward = Vector3.down;
			GameObject cameraObject = new GameObject
			{
				layer = 19
			};
			Camera camera = cameraObject.AddComponent<Camera>();
			camera.targetTexture = renderTexture;
			camera.orthographic = true;
			camera.rect = new Rect(0f, 0f, (float)resolution, (float)resolution);
			camera.nearClipPlane = 0f;
			camera.farClipPlane = 100f;
			camera.orthographicSize = 50f;
			camera.cullingMask = 524288;
			camera.Render();
			Texture2D mapWithClouds = new Texture2D(resolution, resolution, (TextureFormat)3, false);
			mapWithClouds.ReadPixels(new Rect(0f, 0f, (float)resolution, (float)resolution), 0, 0);
			Color32[] mapClouds = mapWithClouds.GetPixels32();
			Object.Destroy((Object)(object)mapWithClouds);
			material.SetTexture("_CloudTex", (Texture)(object)noClouds);
			camera.Render();
			material.SetTexture("_CloudTex", clouds);
			EnvMan.instance.m_smoothDayFraction = m_smoothDayFraction;
			env.m_sunAngle = m_sunAngle;
			((Component)EnvMan.instance.m_dirLight).transform.forward = m_dirLight;
			EnvMan.s_lastFrame--;
			EnvMan.instance.FixedUpdate();
			if (replaceSharedMapToggle)
			{
				material.SetFloat("_SharedFade", m_showSharedMapData ? 1f : 0f);
			}
			if (combineFog)
			{
				Minimap.instance.m_fogTexture.SetPixels32(fogTex);
				Minimap.instance.m_fogTexture.Apply();
			}
			if (!wasOpen)
			{
				Minimap.instance.SetMapMode((MapMode)1);
			}
			mapTexture.Reinitialize(resolution, resolution, (TextureFormat)3, false);
			mapTexture.ReadPixels(new Rect(0f, 0f, (float)resolution, (float)resolution), 0, 0);
			RenderTexture.active = null;
			Object.Destroy((Object)(object)mapPanelObject);
			Object.Destroy((Object)(object)cameraObject);
			Object.Destroy((Object)(object)renderTexture);
			Minimap.instance.m_mapTexture.GetPixels32();
			Color32[] forest = Minimap.instance.m_forestMaskTexture.GetPixels32();
			int resolutionMask = ((Texture)Minimap.instance.m_mapTexture).height;
			Color32[] map = mapTexture.GetPixels32();
			float[] lerp = new float[resolution * resolution];
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				//IL_0195: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				for (int j = 0; j < resolutionMask; j++)
				{
					for (int k = 0; k < resolutionMask; k++)
					{
						int num = resolution / resolutionMask;
						int num2 = j * resolutionMask + k;
						if (!((float)(int)forest[num2].g <= 0.1f) && !((float)(int)forest[num2].r > 0f) && !((float)(int)forest[num2].b > 0f))
						{
							lerp[j * num * resolution + k * num] = (int)forest[num2].g;
							for (int l = -3 * num; l <= 3 * num; l++)
							{
								for (int m = -3 * num; m <= 3 * num; m++)
								{
									int num3 = Mathf.Clamp(j * num + l, 0, resolution - 1);
									int num4 = Mathf.Clamp(k * num + m, 0, resolution - 1);
									lerp[num3 * resolution + num4] += 0.1f;
								}
							}
						}
					}
				}
				for (int n = 0; n < lerp.Length; n++)
				{
					if (lerp[n] != 0f)
					{
						map[n] = Color32.Lerp(map[n], mapClouds[n], lerp[n]);
					}
				}
			});
			NomapPrinter.ShowMessage("$nomapprinter_saving", (MessageType)2);
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return null;
			}
			if (NomapPrinter.showPins.Value)
			{
				yield return AddPinsOnMap(map, resolution);
			}
			mapTexture.SetPixels32(map);
			mapTexture.Apply(false);
			MapViewer.SetMapIsReady();
		}

		private static GameObject InitMapPanel(Material material)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			Vector3[] vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(-50f, -50f, 10f),
				new Vector3(50f, -50f, 10f),
				new Vector3(-50f, 50f, 10f),
				new Vector3(50f, 50f, 10f)
			};
			int[] triangles = new int[6] { 0, 2, 1, 2, 3, 1 };
			Vector3[] normals = (Vector3[])(object)new Vector3[4]
			{
				-Vector3.forward,
				-Vector3.forward,
				-Vector3.forward,
				-Vector3.forward
			};
			Vector2[] uv = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(0f, 0f),
				new Vector2(1f, 0f),
				new Vector2(0f, 1f),
				new Vector2(1f, 1f)
			};
			GameObject val = new GameObject();
			MeshRenderer val2 = val.AddComponent<MeshRenderer>();
			((Renderer)val2).sharedMaterial = material;
			MeshFilter val3 = val.AddComponent<MeshFilter>();
			val3.mesh = new Mesh
			{
				vertices = vertices,
				triangles = triangles,
				normals = normals,
				uv = uv
			};
			val.layer = 19;
			return val;
		}

		private static IEnumerator ApplyMapTexture(Color32[] map)
		{
			int mapResolution = (int)Math.Sqrt(map.Length);
			if (NomapPrinter.mapSize.Value == NomapPrinter.MapSize.Smooth)
			{
				int currentMapSize = mapResolution;
				mapResolution = currentMapSize * 2;
				Color32[] doublemap = (Color32[])(object)new Color32[mapResolution * mapResolution];
				yield return DoubleMapSize(map, doublemap, currentMapSize, mapResolution);
				map = doublemap;
			}
			if (NomapPrinter.showPins.Value)
			{
				yield return AddPinsOnMap(map, mapResolution);
			}
			yield return ApplyMapTextureStriped(map, mapResolution);
			MapViewer.SetMapIsReady();
		}

		private static IEnumerator ApplyMapTextureStriped(Color32[] map, int mapResolution)
		{
			if (((Texture)mapTexture).width != mapResolution || ((Texture)mapTexture).height != mapResolution)
			{
				mapTexture.Reinitialize(mapResolution, mapResolution, (TextureFormat)3, false);
			}
			int pixelsPerStripe = mapResolution * 64;
			int stripeCount = mapResolution / 64;
			if (stripeBuffer == null || stripeBuffer.Length != pixelsPerStripe)
			{
				stripeBuffer = (Color32[])(object)new Color32[pixelsPerStripe];
			}
			for (int stripeIndex = 0; stripeIndex < stripeCount; stripeIndex++)
			{
				int y = stripeIndex * 64;
				int sourceOffset = y * mapResolution;
				Array.Copy(map, sourceOffset, stripeBuffer, 0, pixelsPerStripe);
				mapTexture.SetPixels32(0, y, mapResolution, 64, stripeBuffer);
				yield return null;
			}
			mapTexture.Apply(false);
		}

		private static void OverrideFogTexture()
		{
			Texture2D layerTexture = GetLayerTexture("fog", NomapPrinter.syncFogLayerFromServer.Value);
			if (!((Object)(object)layerTexture == (Object)null))
			{
				MapGenerator.SetFogTexture(layerTexture);
				Object.Destroy((Object)(object)layerTexture);
			}
		}

		private static IEnumerator OverlayMarkingsLayer(bool overFog = false)
		{
			Texture2D markings = GetLayerTexture(overFog ? "overfog" : "underfog", overFog ? NomapPrinter.syncOverFogLayerFromServer.Value : NomapPrinter.syncUnderFogLayerFromServer.Value);
			if (!((Object)(object)markings == (Object)null))
			{
				yield return MapGenerator.OverlayTextureOnMap(markings);
				Object.Destroy((Object)(object)markings);
			}
		}

		private static string[] CustomTextureFileNames(string textureType, string ext)
		{
			return new string[2]
			{
				$"{NomapPrinter.mapType.Value}.{ZNet.instance.GetWorldUID()}.{textureType}.{ext}",
				$"{NomapPrinter.mapType.Value}.{ZNet.instance.GetWorldName()}.{textureType}.{ext}"
			};
		}

		private static Texture2D GetLayerTexture(string layer, bool loadFromServer)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (!TryGetLayerData(layer, loadFromServer, out var data, out var source))
			{
				return null;
			}
			Texture2D val = new Texture2D(2, 2);
			if ((data != null && data.Length == 0) || !ImageConversion.LoadImage(val, data))
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			NomapPrinter.LogInfo("Loaded " + layer + " layer from " + source);
			return val;
		}

		private static bool TryGetLayerData(string layer, bool loadFromServer, out byte[] data, out string source)
		{
			data = null;
			source = null;
			if (loadFromServer)
			{
				string serverTextureString = GetServerTextureString(layer);
				if (Utility.IsNullOrWhiteSpace(serverTextureString))
				{
					return false;
				}
				data = Convert.FromBase64String(serverTextureString);
				source = "server";
				return true;
			}
			if (Directory.Exists(NomapPrinter.configDirectory))
			{
				foreach (FileInfo item in new DirectoryInfo(NomapPrinter.configDirectory).EnumerateFiles("*", SearchOption.AllDirectories))
				{
					data = GetLayerFileData(item.Name, item.FullName, layer);
					if (data != null)
					{
						source = "file " + item.Name;
						return true;
					}
				}
			}
			return false;
		}

		private static string GetServerTextureString(string layer)
		{
			if (1 == 0)
			{
			}
			string result = layer switch
			{
				"explored" => NomapPrinter.customLayerExplored.Value, 
				"fog" => NomapPrinter.customLayerFog.Value, 
				"underfog" => NomapPrinter.customLayerUnderfog.Value, 
				"overfog" => NomapPrinter.customLayerOverfog.Value, 
				_ => "", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static byte[] GetLayerFileData(string name, string fullname, string layer)
		{
			string[] array = CustomTextureFileNames(layer, "png");
			foreach (string value in array)
			{
				if (name.Equals(value, StringComparison.OrdinalIgnoreCase))
				{
					try
					{
						return File.ReadAllBytes(fullname);
					}
					catch (Exception ex)
					{
						NomapPrinter.LogWarning("Error reading png file (" + name + ")! Error: " + ex.Message);
					}
				}
			}
			string[] array2 = CustomTextureFileNames(layer, "zpack");
			foreach (string value2 in array2)
			{
				if (name.Equals(value2, StringComparison.OrdinalIgnoreCase))
				{
					try
					{
						return ExploredMapData.GetPackedImageData(fullname);
					}
					catch (Exception ex2)
					{
						NomapPrinter.LogWarning("Error reading packed file (" + name + ")! Error: " + ex2.Message);
					}
				}
			}
			return null;
		}

		internal static string GetTextureString(string filename, string fullname, string layer)
		{
			byte[] layerFileData = GetLayerFileData(filename, fullname, layer);
			if (layerFileData != null)
			{
				NomapPrinter.LogInfo("Loaded " + layer + " layer from " + filename);
				return Convert.ToBase64String(layerFileData);
			}
			return null;
		}

		private static IEnumerator DoubleMapSize(Color32[] map, Color32[] doublemap, int currentMapSize, int mapSize)
		{
			for (int row = 0; row < currentMapSize; row++)
			{
				for (int col = 0; col < currentMapSize; col++)
				{
					doublemap[(row * 2 + 1) * mapSize + col * 2 + 1] = (doublemap[(row * 2 + 1) * mapSize + col * 2] = (doublemap[row * 2 * mapSize + col * 2 + 1] = (doublemap[row * 2 * mapSize + col * 2] = map[row * currentMapSize + col])));
				}
				if (row % 64 == 0)
				{
					yield return null;
				}
			}
		}

		private static Color GetPixelColor(Biome biome, float height)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_0021: 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_0039: Expected I4, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Invalid comparison between Unknown and I4
			//IL_014a: Unknown result type