Decompiled source of Expand World Size v1.18.0

ExpandWorldSize.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using Service;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ExpandWorldSize")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ExpandWorldSize")]
[assembly: AssemblyTitle("ExpandWorldSize")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: <6f814533-c1a6-47e5-ac86-c658dea9eae5>RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<bee41ebe-7be8-424d-839e-5623aada36b8>Embedded]
	internal sealed class <bee41ebe-7be8-424d-839e-5623aada36b8>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<bee41ebe-7be8-424d-839e-5623aada36b8>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[<bee41ebe-7be8-424d-839e-5623aada36b8>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[<bee41ebe-7be8-424d-839e-5623aada36b8>Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class <6f814533-c1a6-47e5-ac86-c658dea9eae5>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <6f814533-c1a6-47e5-ac86-c658dea9eae5>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Service
{
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	public class ConfigWrapper
	{
		private readonly ConfigFile ConfigFile;

		private readonly ConfigSync ConfigSync;

		public readonly Action Regenerate;

		public static Dictionary<ConfigEntry<string>, float?> Floats = new Dictionary<ConfigEntry<string>, float?>();

		public static Dictionary<ConfigEntry<string>, int?> Ints = new Dictionary<ConfigEntry<string>, int?>();

		public ConfigWrapper(ConfigFile configFile, ConfigSync configSync, Action regenerate)
		{
			ConfigFile = configFile;
			ConfigSync = configSync;
			Regenerate = regenerate;
		}

		public ConfigEntry<string> BindFloat(string group, string name, float value, bool regenerate, string description = "", bool synchronizedSetting = true)
		{
			ConfigEntry<string> entry = Bind(group, name, value.ToString(CultureInfo.InvariantCulture), regenerate, description, synchronizedSetting);
			entry.SettingChanged += [<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(0)] (object s, EventArgs e) =>
			{
				Floats[entry] = TryParseFloat(entry);
			};
			Floats[entry] = TryParseFloat(entry);
			return entry;
		}

		public ConfigEntry<string> BindFloat(string group, string name, float? value, bool regenerate, string description = "", bool synchronizedSetting = true)
		{
			ConfigEntry<string> entry = Bind(group, name, value.HasValue ? value.Value.ToString(CultureInfo.InvariantCulture) : "", regenerate, description, synchronizedSetting);
			entry.SettingChanged += [<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(0)] (object s, EventArgs e) =>
			{
				Floats[entry] = TryParseFloat(entry);
			};
			Floats[entry] = TryParseFloat(entry);
			return entry;
		}

		public ConfigEntry<T> Bind<[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(2)] T>(string group, string name, T value, bool regenerate, ConfigDescription description, bool synchronizedSetting = true)
		{
			ConfigEntry<T> val = ConfigFile.Bind<T>(group, name, value, description);
			if (regenerate)
			{
				val.SettingChanged += Regen;
			}
			ConfigSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronizedSetting;
			return val;
		}

		public ConfigEntry<T> Bind<[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(2)] T>(string group, string name, T value, bool regenerate, string description = "", bool synchronizedSetting = true)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			return Bind(group, name, value, regenerate, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		private void Regen(object e, EventArgs s)
		{
			Regenerate();
		}

		private static float? TryParseFloat(string value)
		{
			if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return null;
		}

		private static float? TryParseFloat(ConfigEntry<string> setting)
		{
			if (float.TryParse(setting.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return TryParseFloat((string)((ConfigEntryBase)setting).DefaultValue);
		}
	}
}
namespace ExpandWorldSize
{
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(2)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	public class BetterContinents
	{
		[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(1)]
		public const string GUID = "BetterContinents";

		private static Assembly Assembly;

		private static FieldInfo SettingsField;

		private static FieldInfo IsEnabledField;

		private static FieldInfo WorldSizeField;

		private static FieldInfo EdgeSizeField;

		public static void Run()
		{
			if (!Chainloader.PluginInfos.TryGetValue("BetterContinents", out var value))
			{
				return;
			}
			Assembly = ((object)value.Instance).GetType().Assembly;
			Type type = Assembly.GetType("BetterContinents.BetterContinents");
			if (type == null)
			{
				return;
			}
			SettingsField = AccessTools.Field(type, "Settings");
			if (SettingsField == null)
			{
				return;
			}
			type = Assembly.GetType("BetterContinents.BetterContinents+BetterContinentsSettings");
			IsEnabledField = AccessTools.Field(type, "EnabledForThisWorld");
			if (IsEnabledField == null)
			{
				return;
			}
			type = Assembly.GetType("BetterContinents.BetterContinents");
			if (!(type == null))
			{
				WorldSizeField = AccessTools.Field(type, "WorldSize");
				if (!(WorldSizeField == null))
				{
					EdgeSizeField = AccessTools.Field(type, "EdgeSize");
					EWS.Log.LogInfo((object)"\"Better Continents\" detected. Applying compatibility.");
				}
			}
		}

		public static bool IsEnabled()
		{
			if (SettingsField == null)
			{
				return false;
			}
			if (IsEnabledField == null)
			{
				return false;
			}
			object value = SettingsField.GetValue(null);
			if (value == null)
			{
				return false;
			}
			return (bool)IsEnabledField.GetValue(value);
		}

		public static void RefreshSize()
		{
			if (!(WorldSizeField == null))
			{
				WorldSizeField.SetValue(null, Configuration.WorldTotalRadius);
				if (!(EdgeSizeField == null))
				{
					EdgeSizeField.SetValue(null, Configuration.WorldEdgeSize);
				}
			}
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(2)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	public class EWD
	{
		[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(1)]
		public const string GUID = "expand_world_data";

		private static Assembly Assembly;

		private static MethodInfo SetSize;

		public static void Run()
		{
			if (!Chainloader.PluginInfos.TryGetValue("expand_world_data", out var value))
			{
				return;
			}
			Assembly = ((object)value.Instance).GetType().Assembly;
			Type type = Assembly.GetType("ExpandWorldData.WorldInfo");
			if (!(type == null))
			{
				SetSize = AccessTools.Method(type, "Set", (Type[])null, (Type[])null);
				if (!(SetSize == null))
				{
					EWS.Log.LogInfo((object)"\"Expand World Data\" detected. Applying compatibility.");
				}
			}
		}

		public static void RefreshSize()
		{
			if (!(SetSize == null))
			{
				SetSize.Invoke(null, new object[4]
				{
					Configuration.WorldRadius,
					Configuration.WorldTotalRadius,
					Configuration.WorldStretch,
					Configuration.BiomeStretch
				});
			}
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(2)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	public class Marketplace
	{
		[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(1)]
		public const string GUID = "MarketplaceAndServerNPCs";

		private static Assembly MarketplaceAssembly;

		private static FieldInfo IsLoadingField;

		public static void Run()
		{
			if (!Chainloader.PluginInfos.TryGetValue("MarketplaceAndServerNPCs", out var value))
			{
				return;
			}
			MarketplaceAssembly = ((object)value.Instance).GetType().Assembly;
			Type type = MarketplaceAssembly.GetType("API.ClientSide");
			if (!(type == null))
			{
				IsLoadingField = AccessTools.Field(type, "FillingTerritoryData");
				if (!(IsLoadingField == null))
				{
					EWS.Log.LogInfo((object)"\"Marketplace\" detected. Applying compatibility.");
				}
			}
		}

		public static bool IsLoading()
		{
			if (IsLoadingField == null)
			{
				return false;
			}
			return (bool)IsLoadingField.GetValue(null);
		}
	}
	public class WorldInfo
	{
		public static float WaterLevel = 30f;

		public static float BaseWaterLevel = Helper.HeightToBaseHeight(WaterLevel);

		public static float WorldStretch = 1f;

		public static float BiomeStretch = 1f;

		public static float WaterDepth = 1f;

		public static float AltitudeMultiplier = 1f;

		public static float BaseAltitudeDelta = 0f;

		public static float ForestMultiplier = 1f;

		public static void SetWaterLevel(float waterLevel)
		{
			if (WaterLevel != waterLevel)
			{
				WaterLevel = waterLevel;
				BaseWaterLevel = Helper.HeightToBaseHeight(WaterLevel);
			}
		}

		public static void Generate()
		{
			if (!Patcher.IsMenu)
			{
				EWS.Log.LogInfo((object)"Regenerating the world.");
				Refresh();
				MapGeneration.Cancel();
				WorldGenerator.instance.Pregenerate();
				Heightmap[] array = Object.FindObjectsOfType<Heightmap>();
				foreach (Heightmap obj in array)
				{
					obj.m_buildData = null;
					obj.Regenerate();
				}
				ClutterSystem instance = ClutterSystem.instance;
				if (instance != null)
				{
					instance.ClearAll();
				}
				SetupMaterial.Refresh();
				if (Object.op_Implicit((Object)(object)EnvMan.instance))
				{
					ScaleGlobalWaterSurface.Refresh(EnvMan.instance);
				}
				if (Configuration.RegenerateMap)
				{
					Map();
				}
			}
		}

		public static void Map()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				Minimap instance = Minimap.instance;
				if (instance != null)
				{
					instance.GenerateWorldMap();
				}
			}
		}

		public static void Refresh()
		{
			WorldStretch = Configuration.WorldStretch;
			BiomeStretch = Configuration.BiomeStretch;
			WaterDepth = Configuration.WaterDepthMultiplier;
			AltitudeMultiplier = Configuration.AltitudeMultiplier;
			ForestMultiplier = Configuration.ForestMultiplier;
			BaseAltitudeDelta = Helper.HeightToBaseHeight(Configuration.AltitudeDelta);
			if (Patcher.WG != null)
			{
				Patcher.WG.maxMarshDistance = VersionSetup.MaxMarshDistance * Configuration.WorldRadius / 10000f / Configuration.WorldStretch;
			}
			EWD.RefreshSize();
			BetterContinents.RefreshSize();
			Patcher.Patch();
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(WorldGenerator), "VersionSetup")]
	public class VersionSetup
	{
		public static float MaxMarshDistance = 6000f;

		private static void Prefix(WorldGenerator __instance)
		{
			__instance.maxMarshDistance = 6000f;
		}

		private static void Postfix(WorldGenerator __instance)
		{
			MaxMarshDistance = __instance.maxMarshDistance;
		}
	}
	[HarmonyPatch(typeof(World), "LoadWorld")]
	public class LoadWorld
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static World Postfix(World result)
		{
			if (Configuration.Seed != "" && !result.m_menu)
			{
				result.m_seedName = Configuration.Seed;
				result.m_seed = StringExtensionMethods.GetStableHashCode(Configuration.Seed);
			}
			return result;
		}
	}
	public class Configuration
	{
		public static ConfigEntry<bool> configRegenerateMap;

		public static ConfigEntry<string> configWorldRadius;

		public static ConfigEntry<string> configWorldEdgeSize;

		public static ConfigEntry<string> configMapSize;

		public static ConfigEntry<string> configMapPixelSize;

		public static ConfigEntry<string> configAltitudeMultiplier;

		public static ConfigEntry<string> configAltitudeDelta;

		public static ConfigEntry<string> configLocationsMultiplier;

		public static ConfigEntry<string> configForestMultiplier;

		public static ConfigEntry<string> configWorldStretch;

		public static ConfigEntry<string> configBiomeStretch;

		public static ConfigEntry<string> configSeed;

		public static ConfigEntry<string> configOffsetX;

		public static ConfigEntry<string> configOffsetY;

		public static ConfigEntry<string> configHeightSeed;

		public static ConfigEntry<string> configWaterDepthMultiplier;

		public static bool RegenerateMap => configRegenerateMap.Value;

		public static float WorldRadius => ConfigWrapper.Floats[configWorldRadius] ?? 10000f;

		public static float StrechedWorldRadius => WorldRadius / WorldStretch;

		public static float WorldEdgeSize => ConfigWrapper.Floats[configWorldEdgeSize] ?? 500f;

		public static float WorldTotalRadius => WorldRadius + WorldEdgeSize;

		public static float StrechedWorldTotalRadius => WorldTotalRadius / WorldStretch;

		public static float MapSize => ConfigWrapper.Floats[configMapSize] ?? 1f;

		public static float MapPixelSize => ConfigWrapper.Floats[configMapPixelSize] ?? 1f;

		public static float AltitudeMultiplier => ConfigWrapper.Floats[configAltitudeMultiplier] ?? 1f;

		public static float AltitudeDelta => ConfigWrapper.Floats[configAltitudeDelta].GetValueOrDefault();

		public static float LocationsMultiplier => ConfigWrapper.Floats[configLocationsMultiplier] ?? 1f;

		public static float ForestMultiplier => ConfigWrapper.Floats[configForestMultiplier] ?? 1f;

		public static float WorldStretch => ConfigWrapper.Floats[configWorldStretch] ?? 1f;

		public static float BiomeStretch => ConfigWrapper.Floats[configBiomeStretch] ?? 1f;

		public static string Seed => configSeed.Value;

		public static float? OffsetX => ConfigWrapper.Floats[configOffsetX];

		public static float? OffsetY => ConfigWrapper.Floats[configOffsetY];

		public static float? HeightSeed => ConfigWrapper.Floats[configHeightSeed];

		public static float WaterDepthMultiplier => ConfigWrapper.Floats[configWaterDepthMultiplier].GetValueOrDefault();

		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		public static void Init(ConfigWrapper wrapper)
		{
			string group = "1. General";
			configRegenerateMap = wrapper.Bind(group, "Regenerate map", value: true, regenerate: false, "If true, the world map is regenerated automatically on data changes.");
			configWorldRadius = wrapper.BindFloat(group, "World radius", 10000f, regenerate: true, "Radius of the world in meters (excluding the edge).");
			configWorldEdgeSize = wrapper.BindFloat(group, "World edge size", 500f, regenerate: true, "Size of the edge area in meters (added to the radius for the total size).");
			configMapSize = wrapper.BindFloat(group, "Minimap size", 1f, regenerate: false, "Increases the minimap size, but also significantly increases the generation time.");
			configMapSize.SettingChanged += delegate
			{
				if (Object.op_Implicit((Object)(object)Minimap.instance))
				{
					int num2 = (int)((float)MinimapAwake.OriginalTextureSize * MapSize);
					if (num2 != Minimap.instance.m_textureSize)
					{
						Minimap.instance.m_maxZoom = MinimapAwake.OriginalMinZoom * Mathf.Max(1f, MapSize);
						MapGeneration.UpdateTextureSize(Minimap.instance, num2);
						wrapper.Regenerate();
					}
				}
			};
			configMapPixelSize = wrapper.BindFloat(group, "Minimap pixel size", 1f, regenerate: false, "Decreases the minimap detail, but doesn't affect the generation time.");
			configMapPixelSize.SettingChanged += delegate
			{
				if (Object.op_Implicit((Object)(object)Minimap.instance))
				{
					float num = MinimapAwake.OriginalPixelSize * MapPixelSize;
					if (num != Minimap.instance.m_pixelSize)
					{
						Minimap.instance.m_pixelSize = num;
						wrapper.Regenerate();
					}
				}
			};
			configWorldStretch = wrapper.BindFloat(group, "Stretch world", 1f, regenerate: true, "Stretches the world to a bigger area.");
			configBiomeStretch = wrapper.BindFloat(group, "Stretch biomes", 1f, regenerate: true, "Stretches the biomes to a bigger area.");
			configForestMultiplier = wrapper.BindFloat(group, "Forest multiplier", 1f, regenerate: true, "Multiplies the amount of forest.");
			configAltitudeMultiplier = wrapper.BindFloat(group, "Altitude multiplier", 1f, regenerate: true, "Multiplies the altitude.");
			configAltitudeDelta = wrapper.BindFloat(group, "Altitude delta", 0f, regenerate: true, "Adds to the altitude.");
			configWaterDepthMultiplier = wrapper.BindFloat(group, "Water depth multiplier", 1f, regenerate: true, "Multplies the water depth.");
			configLocationsMultiplier = wrapper.BindFloat(group, "Locations", 1f, regenerate: true, "Multiplies the max amount of locations.");
			configOffsetX = wrapper.BindFloat(group, "Offset X", null, regenerate: true);
			configOffsetY = wrapper.BindFloat(group, "Offset Y", null, regenerate: true);
			configSeed = wrapper.Bind(group, "Seed", "", regenerate: false);
			configSeed.SettingChanged += delegate
			{
				if (!(Seed == "") && WorldGenerator.instance != null)
				{
					World world = WorldGenerator.instance.m_world;
					if (!world.m_menu)
					{
						world.m_seedName = Seed;
						world.m_seed = StringExtensionMethods.GetStableHashCode(Seed);
						world.m_menu = true;
						WorldGenerator.Initialize(world);
						world.m_menu = false;
						WorldInfo.Generate();
					}
				}
			};
			configHeightSeed = wrapper.BindFloat(group, "Height variation seed", null, regenerate: true);
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch]
	public static class Patcher
	{
		[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(2)]
		public static WorldGenerator WG;

		[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(2)]
		private static Harmony Harmony;

		public static bool IsMenu
		{
			get
			{
				if (WG != null)
				{
					return WG.m_world.m_menu;
				}
				return true;
			}
		}

		public static void Init(Harmony harmony)
		{
			Harmony = harmony;
			Patch();
		}

		public static void Patch()
		{
			if (Harmony == null)
			{
				throw new Exception("Harmony not initialized.");
			}
			Harmony.UnpatchSelf();
			Harmony.PatchAll();
			CheckWorldStretch(Harmony);
			CheckWaterDepth(Harmony);
			CheckForest(Harmony);
			CheckAltitude(Harmony);
		}

		[HarmonyPatch(typeof(WorldGenerator), "VersionSetup")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void PatchOnLoad(WorldGenerator __instance)
		{
			WG = __instance;
			WorldInfo.Refresh();
		}

		private static void CheckWorldStretch(Harmony harmony)
		{
			if (IsMenu || Configuration.WorldStretch == 1f)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(WorldGenerator), "GetBiomeHeight", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Stretch), "GetBiomeHeight", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
				methodInfo = AccessTools.Method(typeof(WorldGenerator), "GetAshlandsOceanGradient", new Type[1] { typeof(Vector3) }, (Type[])null);
				methodInfo2 = AccessTools.Method(typeof(Stretch), "GetAshlandsOceanGradient", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
				methodInfo = AccessTools.Method(typeof(Minimap), "GetMaskColor", (Type[])null, (Type[])null);
				methodInfo2 = AccessTools.Method(typeof(Stretch), "GetMaskColor", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
				methodInfo = AccessTools.Method(typeof(WorldGenerator), "GetBiome", new Type[4]
				{
					typeof(float),
					typeof(float),
					typeof(float),
					typeof(bool)
				}, (Type[])null);
				methodInfo2 = AccessTools.Method(typeof(Stretch), "GetBiome", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
				methodInfo = AccessTools.Method(typeof(WorldGenerator), "AddRivers", (Type[])null, (Type[])null);
				methodInfo2 = AccessTools.Method(typeof(AddRivers), "Prefix", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
			}
		}

		private static void CheckWaterDepth(Harmony harmony)
		{
			if (IsMenu || Configuration.WaterDepthMultiplier == 1f)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(WorldGenerator), "GetBiomeHeight", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(BiomeHeight), "Postfix", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
			}
		}

		private static void CheckForest(Harmony harmony)
		{
			if (IsMenu || Configuration.ForestMultiplier == 1f || Configuration.ForestMultiplier == 0f)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(WorldGenerator), "GetForestFactor", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Forest), "Postfix", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
			}
		}

		private static void CheckAltitude(Harmony harmony)
		{
			if (IsMenu || (Configuration.AltitudeDelta == 0f && Configuration.AltitudeMultiplier == 1f))
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(WorldGenerator), "GetBaseHeight", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(BaseHeight), "Postfix", (Type[])null, (Type[])null);
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public class DebugCommands
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static ConsoleEvent <>9__0_1;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				WorldInfo.Map();
			}

			internal void <Postfix>b__0_1(ConsoleEventArgs args)
			{
				WorldGenerator instance = WorldGenerator.m_instance;
				if (instance != null)
				{
					List<string> values = new List<string>
					{
						"Main: " + instance.m_world.m_seedName,
						"Generator: " + instance.m_world.m_worldGenVersion,
						"World: " + instance.m_world.m_seed,
						"Offset X: " + instance.m_offset0,
						"Offset Y: " + instance.m_offset1,
						"Height: " + instance.m_offset3,
						"Meadows: " + instance.m_offset3,
						"Black forest: " + instance.m_offset2,
						"Swamp: " + instance.m_offset0,
						"Plains: " + instance.m_offset1,
						"Mistlands: " + instance.m_offset4
					};
					ZLog.Log((object)string.Join("\n", values));
					args.Context.AddString(string.Join("\n", values));
				}
			}
		}

		private static void Postfix()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0029: Expected O, but got Unknown
			//IL_006a: 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)
			//IL_0061: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate
				{
					WorldInfo.Map();
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("ew_map", "Refreshes the world map.", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleEvent val2 = delegate(ConsoleEventArgs args)
				{
					WorldGenerator instance = WorldGenerator.m_instance;
					if (instance != null)
					{
						List<string> values = new List<string>
						{
							"Main: " + instance.m_world.m_seedName,
							"Generator: " + instance.m_world.m_worldGenVersion,
							"World: " + instance.m_world.m_seed,
							"Offset X: " + instance.m_offset0,
							"Offset Y: " + instance.m_offset1,
							"Height: " + instance.m_offset3,
							"Meadows: " + instance.m_offset3,
							"Black forest: " + instance.m_offset2,
							"Swamp: " + instance.m_offset0,
							"Plains: " + instance.m_offset1,
							"Mistlands: " + instance.m_offset4
						};
						ZLog.Log((object)string.Join("\n", values));
						args.Context.AddString(string.Join("\n", values));
					}
				};
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("ew_seeds", "- Prints different seeds.", (ConsoleEvent)obj2, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[BepInPlugin("expand_world_size", "Expand World Size", "1.18")]
	[BepInIncompatibility("expand_world")]
	public class EWS : BaseUnityPlugin
	{
		public const string GUID = "expand_world_size";

		public const string NAME = "Expand World Size";

		public const string VERSION = "1.18";

		[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
		public static ManualLogSource Log;

		public static ConfigSync ConfigSync = new ConfigSync("expand_world_size")
		{
			DisplayName = "Expand World Size",
			CurrentVersion = "1.18",
			ModRequired = true,
			IsLocked = true
		};

		public static string ConfigName = "expand_world_size.cfg";

		public static bool NeedsMigration = File.Exists(Path.Combine(Paths.ConfigPath, "expand_world.cfg")) && !File.Exists(Path.Combine(Paths.ConfigPath, ConfigName));

		public void Awake()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Configuration.Init(new ConfigWrapper(((BaseUnityPlugin)this).Config, ConfigSync, InvokeRegenerate));
			if (NeedsMigration)
			{
				MigrateOldConfig();
			}
			Patcher.Init(new Harmony("expand_world_size"));
			try
			{
				SetupWatcher();
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex);
			}
		}

		public void Start()
		{
			Marketplace.Run();
			BetterContinents.Run();
			EWD.Run();
		}

		private void MigrateOldConfig()
		{
			Log.LogWarning((object)"Migrating old config file.");
			((BaseUnityPlugin)this).Config.Save();
			string[] array = File.ReadAllLines(Path.Combine(Paths.ConfigPath, "expand_world.cfg"));
			string[] array2 = File.ReadAllLines(Path.Combine(Paths.ConfigPath, ConfigName));
			string[] array3 = array;
			foreach (string text in array3)
			{
				string[] array4 = text.Split(new char[1] { '=' });
				if (array4.Length != 2)
				{
					continue;
				}
				for (int j = 0; j < array2.Length; j++)
				{
					if (array2[j].StartsWith(array4[0]))
					{
						array2[j] = text;
					}
				}
			}
			File.WriteAllLines(Path.Combine(Paths.ConfigPath, ConfigName), array2);
			((BaseUnityPlugin)this).Config.Reload();
		}

		public void InvokeRegenerate()
		{
			if (!Patcher.IsMenu)
			{
				((MonoBehaviour)this).CancelInvoke("Regenerate");
				((MonoBehaviour)this).Invoke("Regenerate", 1f);
			}
		}

		public void Regenerate()
		{
			WorldInfo.Generate();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				return;
			}
			try
			{
				Log.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				Log.LogError((object)("There was an issue loading your " + ((BaseUnityPlugin)this).Config.ConfigFilePath));
				Log.LogError((object)"Please check your config entries for spelling and format!");
			}
		}
	}
	[HarmonyPatch(typeof(ZRpc), "SetLongTimeout")]
	public class IncreaseTimeout
	{
		private static bool Prefix()
		{
			ZRpc.m_timeout = 300f;
			ZLog.Log((object)$"ZRpc timeout set to {ZRpc.m_timeout}s ");
			return false;
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "GetForestFactor")]
	public class Forest
	{
		public static float Postfix(float result)
		{
			return result /= WorldInfo.ForestMultiplier;
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "GetBaseHeight")]
	public class BaseHeight
	{
		public static float Postfix(float result)
		{
			return WorldInfo.BaseWaterLevel + (result - WorldInfo.BaseWaterLevel) * WorldInfo.AltitudeMultiplier + WorldInfo.BaseAltitudeDelta;
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "GetBiomeHeight")]
	public class BiomeHeight
	{
		public static float Postfix(float result)
		{
			if (!(result > WorldInfo.WaterLevel))
			{
				return (result - WorldInfo.WaterLevel) * WorldInfo.WaterDepth + WorldInfo.WaterLevel;
			}
			return result;
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch]
	public class HeightSeed
	{
		private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			if (!Configuration.HeightSeed.HasValue)
			{
				return instructions;
			}
			return Helper.ReplaceSeed(new CodeMatcher(instructions, (ILGenerator)null), "m_offset3", Configuration.HeightSeed.Value).InstructionEnumeration();
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetAshlandsHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Ashlands(IEnumerable<CodeInstruction> instructions)
		{
			return Transpile(instructions);
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetForestHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Forest(IEnumerable<CodeInstruction> instructions)
		{
			return Transpile(instructions);
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetMeadowsHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Meadows(IEnumerable<CodeInstruction> instructions)
		{
			return Transpile(instructions);
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetDeepNorthHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> DeepNorth(IEnumerable<CodeInstruction> instructions)
		{
			return Transpile(instructions);
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetPlainsHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Plains(IEnumerable<CodeInstruction> instructions)
		{
			return Transpile(instructions);
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetSnowMountainHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Mountain(IEnumerable<CodeInstruction> instructions)
		{
			return Transpile(instructions);
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetMistlandsHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Mistlands(IEnumerable<CodeInstruction> instructions)
		{
			return Transpile(instructions);
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(ZoneSystem), "GenerateLocations", new Type[] { typeof(ZoneLocation) })]
	public class GenerateLocationsQuantity
	{
		private static void Prefix(ZoneLocation location, ref int __state)
		{
			__state = location.m_quantity;
			if (Configuration.LocationsMultiplier != 1f && !(location.m_prefabName == Game.instance.m_StartLocation))
			{
				location.m_quantity = Mathf.RoundToInt((float)location.m_quantity * Configuration.LocationsMultiplier);
			}
		}

		private static void Postfix(ZoneLocation location, int __state)
		{
			location.m_quantity = __state;
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(ZoneSystem), "GenerateLocations", new Type[] { typeof(ZoneLocation) })]
	public class GenerateLocationsMin
	{
		private static void Prefix(ZoneLocation location, ref float __state)
		{
			__state = location.m_minDistance;
			location.m_minDistance *= Configuration.WorldRadius / 10000f;
		}

		private static void Postfix(ZoneLocation location, float __state)
		{
			location.m_minDistance = __state;
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(ZoneSystem), "GenerateLocations", new Type[] { typeof(ZoneLocation) })]
	public class GenerateLocationsMax
	{
		private static void Prefix(ZoneLocation location, ref float __state)
		{
			__state = location.m_maxDistance;
			location.m_maxDistance *= Configuration.WorldRadius / 10000f;
		}

		private static void Postfix(ZoneLocation location, float __state)
		{
			location.m_maxDistance = __state;
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "GetRandomZone")]
	public class GetRandomZone
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 10000f, Configuration.WorldRadius).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "GenerateLocations", new Type[] { typeof(ZoneLocation) })]
	public class GenerateLocations
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 10000f, Configuration.WorldRadius).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "FindLakes")]
	public class FindLakes
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Helper.Replace(Helper.Replace(Stretch.Replace(Stretch.Replace(Helper.Replace(Helper.Replace(Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), -10000f, 0f - Configuration.WorldRadius), -10000f, 0f - Configuration.WorldRadius), 10000f, Configuration.WorldRadius), OpCodes.Ldloc_3), OpCodes.Ldloc_2), 10000f, Configuration.WorldRadius), 10000f, Configuration.WorldRadius).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "IsRiverAllowed")]
	public class IsRiverAllowed
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Stretch.Replace(Stretch.Replace(new CodeMatcher(instructions, (ILGenerator)null), OpCodes.Ldfld), OpCodes.Ldfld).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "FindStreamStartPoint")]
	public class FindStreamStartPoint
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Helper.Replace(Helper.Replace(Helper.Replace(Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), -10000f, 0f - Configuration.WorldRadius), 10000f, Configuration.WorldRadius), -10000f, 0f - Configuration.WorldRadius), 10000f, Configuration.WorldRadius).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "AddRivers")]
	public class AddRivers
	{
		public static void Prefix(ref float wx, ref float wy)
		{
			wx *= Configuration.WorldStretch;
			wy *= Configuration.WorldStretch;
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch]
	public class Stretch
	{
		[HarmonyPatch(typeof(WorldGenerator), "GetAshlandsOceanGradient", new Type[] { typeof(Vector3) })]
		[HarmonyPrefix]
		[HarmonyPriority(500)]
		public static void GetAshlandsOceanGradient(ref Vector3 pos)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			Vector3 val = pos;
			val.x = pos.x / Configuration.WorldStretch;
			val.z = pos.z / Configuration.WorldStretch;
			pos = val;
		}

		[HarmonyPatch(typeof(Minimap), "GetMaskColor")]
		[HarmonyPrefix]
		[HarmonyPriority(500)]
		public static void GetMaskColor(ref float wx, ref float wy)
		{
			wx /= Configuration.WorldStretch;
			wy /= Configuration.WorldStretch;
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetBiomeHeight")]
		[HarmonyPrefix]
		[HarmonyPriority(500)]
		public static void GetBiomeHeight(ref float wx, ref float wy)
		{
			wx /= Configuration.WorldStretch;
			wy /= Configuration.WorldStretch;
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetBiome", new Type[]
		{
			typeof(float),
			typeof(float),
			typeof(float),
			typeof(bool)
		})]
		[HarmonyPrefix]
		[HarmonyPriority(500)]
		public static void GetBiome(ref float wx, ref float wy)
		{
			wx /= Configuration.WorldStretch;
			wy /= Configuration.WorldStretch;
		}

		public static CodeMatcher Replace(CodeMatcher matcher, OpCode code)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			if (Configuration.WorldStretch == 1f)
			{
				return matcher;
			}
			return matcher.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)code, (object)null, (string)null)
			}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldc_R4, (object)Configuration.WorldStretch)
			})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Div, (object)null)
				});
		}

		public static CodeMatcher ReplaceBiome(CodeMatcher matcher)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			if (Configuration.BiomeStretch == 1f)
			{
				return matcher;
			}
			return matcher.MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Conv_R8, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null)
			}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldc_R4, (object)Configuration.BiomeStretch)
			})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Div, (object)null)
				})
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_2, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Conv_R8, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null)
				})
				.Advance(1)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldc_R4, (object)Configuration.BiomeStretch)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Div, (object)null)
				});
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetBiome", new Type[]
		{
			typeof(float),
			typeof(float),
			typeof(float),
			typeof(bool)
		})]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			CodeMatcher val = new CodeMatcher(ReplaceBiome(ReplaceBiome(ReplaceBiome(ReplaceBiome(new CodeMatcher(instructions, (ILGenerator)null))))).InstructionEnumeration(), (ILGenerator)null);
			AccessTools.Field(typeof(WorldGenerator), "ashlandsMinDistance").SetValue(null, 1.2f * Configuration.StrechedWorldRadius);
			AccessTools.Field(typeof(WorldGenerator), "ashlandsYOffset").SetValue(null, -0.4f * Configuration.StrechedWorldRadius);
			return Helper.Replace(Helper.Replace(Helper.Replace(Helper.Replace(Helper.Replace(Helper.Replace(Helper.Replace(Helper.Replace(val, 2000f, 0.2f * Configuration.StrechedWorldRadius), 6000.0, 0.6 * (double)Configuration.StrechedWorldRadius), 10000f, Configuration.StrechedWorldRadius), 3000.0, 0.3 * (double)Configuration.StrechedWorldRadius), 8000f, 0.8f * Configuration.StrechedWorldRadius), 600.0, 0.06 * (double)Configuration.StrechedWorldRadius), 6000f, 0.6f * Configuration.StrechedWorldRadius), 5000.0, 0.5 * (double)Configuration.StrechedWorldRadius).InstructionEnumeration();
		}

		[HarmonyPatch(typeof(WorldGenerator), "IsDeepnorth")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TranspilerIsDeepnorth(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Helper.Replace(Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 4000.0, 0.4 * (double)Configuration.StrechedWorldRadius), 12000.0, 1.2 * (double)Configuration.StrechedWorldRadius).InstructionEnumeration();
		}

		[HarmonyPatch(typeof(WorldGenerator), "CreateAshlandsGap")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TranspilerCreateAshlandsGap(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 400.0, 0.04 * (double)Configuration.StrechedWorldRadius).InstructionEnumeration();
		}

		[HarmonyPatch(typeof(WorldGenerator), "CreateDeepNorthGap")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TranspilerCreateDeepNorthGap(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Helper.Replace(Helper.Replace(Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 4000f, 0.4f * Configuration.StrechedWorldRadius), 12000.0, 1.2f * Configuration.StrechedWorldRadius), 400.0, 0.04 * (double)Configuration.StrechedWorldRadius).InstructionEnumeration();
		}

		[HarmonyPatch(typeof(WorldGenerator), "GetBiomeHeight")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TranspilerGetBiomeHeight(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 10500f, Configuration.StrechedWorldTotalRadius).InstructionEnumeration();
		}
	}
	public class WorldSizeHelper
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		public static IEnumerable<CodeInstruction> EdgeCheck(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			return Helper.Replace(Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 10420f, Configuration.WorldTotalRadius - 80f), 10500f, Configuration.WorldTotalRadius).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(Ship), "ApplyEdgeForce")]
	public class ApplyEdgeForce
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return WorldSizeHelper.EdgeCheck(instructions);
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(Player), "EdgeOfWorldKill")]
	public class EdgeOfWorldKill
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return WorldSizeHelper.EdgeCheck(instructions);
		}

		private static bool Prefix(Player __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)__instance).transform.position.y < 4000f;
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "GetAshlandsHeight")]
	public class GetAshlandsHeight
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			return Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 10150.0, (Configuration.WorldTotalRadius + 150f) / Configuration.WorldStretch).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "GetBaseHeight")]
	public class GetBaseHeight
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if (Patcher.IsMenu)
			{
				return instructions;
			}
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val = val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(WorldGenerator), "m_offset1"), (string)null)
			});
			if (Configuration.OffsetX.HasValue)
			{
				val = Helper.ReplaceSeed(val, "m_offset0", Configuration.OffsetX.Value);
			}
			if (Configuration.OffsetY.HasValue)
			{
				val = Helper.ReplaceSeed(val, "m_offset1", Configuration.OffsetY.Value);
			}
			val = Helper.Replace(val, 10000f, Configuration.StrechedWorldRadius);
			val = Helper.Replace(val, 10000f, Configuration.StrechedWorldRadius);
			val = Helper.Replace(val, 10500f, Configuration.StrechedWorldTotalRadius);
			val = Helper.Replace(val, 10490f, (Configuration.WorldTotalRadius - 10f) / Configuration.WorldStretch);
			val = Helper.Replace(val, 10500f, Configuration.StrechedWorldTotalRadius);
			return val.InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WaterVolume), "SetupMaterial")]
	public class SetupMaterial
	{
		public static void Refresh()
		{
			WaterVolume[] array = Object.FindObjectsOfType<WaterVolume>();
			for (int i = 0; i < array.Length; i++)
			{
				((Renderer)array[i].m_waterSurface).material.SetFloat("_WaterEdge", Configuration.WorldTotalRadius);
			}
		}

		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		public static void Prefix(WaterVolume __instance)
		{
			((Renderer)__instance.m_waterSurface).material.SetFloat("_WaterEdge", Configuration.WorldTotalRadius);
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(EnvMan), "Awake")]
	public class ScaleGlobalWaterSurface
	{
		public static void Refresh(EnvMan obj)
		{
			((Renderer)((Component)((Component)obj).transform.Find("WaterPlane").Find("watersurface")).GetComponent<MeshRenderer>()).material.SetFloat("_WaterEdge", Configuration.WorldTotalRadius);
		}

		public static void Postfix(EnvMan __instance)
		{
			Refresh(__instance);
		}
	}
	[HarmonyPatch(typeof(EnvMan), "UpdateWind")]
	public class UpdateWind
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Helper.Replace(Helper.Replace(Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 10500f, Configuration.WorldRadius).SetOpcodeAndAdvance(OpCodes.Nop).SetOpcodeAndAdvance(OpCodes.Nop)
				.SetOpcodeAndAdvance(OpCodes.Nop), 10500f, Configuration.WorldRadius).SetOpcodeAndAdvance(OpCodes.Nop).SetOpcodeAndAdvance(OpCodes.Nop)
				.SetOpcodeAndAdvance(OpCodes.Nop), 10500f, Configuration.WorldTotalRadius).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WaterVolume), "GetWaterSurface")]
	public class GetWaterSurface
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Helper.Replace(new CodeMatcher(instructions, (ILGenerator)null), 10500f, Configuration.WorldTotalRadius).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(WorldGenerator), "Pregenerate")]
	[HarmonyPriority(500)]
	public class Pregenerate
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static void Prefix(WorldGenerator __instance)
		{
			//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)
			__instance.m_riverCacheLock.EnterWriteLock();
			__instance.m_riverPoints = new Dictionary<Vector2i, RiverPoint[]>();
			__instance.m_rivers = new List<River>();
			__instance.m_streams = new List<River>();
			__instance.m_lakes = new List<Vector2>();
			__instance.m_cachedRiverGrid = new Vector2i(-999999, -999999);
			__instance.m_cachedRiverPoints = (RiverPoint[])(object)new RiverPoint[0];
			__instance.m_riverCacheLock.ExitWriteLock();
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(Minimap), "TryLoadMinimapTextureData")]
	public class PatchTryLoadMinimapTextureData
	{
		private static bool Prefix(Minimap __instance, ref bool __result)
		{
			__result = TryLoadMinimapTextureData(__instance);
			return false;
		}

		private static bool TryLoadMinimapTextureData(Minimap obj)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if (string.IsNullOrEmpty(obj.m_forestMaskTexturePath) || !File.Exists(obj.m_forestMaskTexturePath) || !File.Exists(obj.m_mapTexturePath) || !File.Exists(obj.m_heightTexturePath) || 33 != ZNet.World.m_worldVersion)
			{
				return false;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			Texture2D val = new Texture2D(((Texture)obj.m_forestMaskTexture).width, ((Texture)obj.m_forestMaskTexture).height, (TextureFormat)5, false);
			if (!ImageConversion.LoadImage(val, File.ReadAllBytes(obj.m_forestMaskTexturePath)))
			{
				return false;
			}
			if (((Texture)obj.m_forestMaskTexture).width != ((Texture)val).width || ((Texture)obj.m_forestMaskTexture).height != ((Texture)val).height)
			{
				return false;
			}
			obj.m_forestMaskTexture.SetPixels(val.GetPixels());
			obj.m_forestMaskTexture.Apply();
			if (!ImageConversion.LoadImage(val, File.ReadAllBytes(obj.m_mapTexturePath)))
			{
				return false;
			}
			if (((Texture)obj.m_mapTexture).width != ((Texture)val).width || ((Texture)obj.m_mapTexture).height != ((Texture)val).height)
			{
				return false;
			}
			obj.m_mapTexture.SetPixels(val.GetPixels());
			obj.m_mapTexture.Apply();
			if (!ImageConversion.LoadImage(val, File.ReadAllBytes(obj.m_heightTexturePath)))
			{
				return false;
			}
			if (((Texture)obj.m_heightTexture).width != ((Texture)val).width || ((Texture)obj.m_heightTexture).height != ((Texture)val).height)
			{
				return false;
			}
			Color[] pixels = val.GetPixels();
			for (int i = 0; i < obj.m_textureSize; i++)
			{
				for (int j = 0; j < obj.m_textureSize; j++)
				{
					int num = i * obj.m_textureSize + j;
					int num2 = (int)(pixels[num].r * 255f);
					int num3 = (int)(pixels[num].g * 255f);
					int num4 = (num2 << 8) + num3;
					float num5 = 127.5f;
					pixels[num].r = (float)num4 / num5;
				}
			}
			obj.m_heightTexture.SetPixels(pixels);
			obj.m_heightTexture.Apply();
			ZLog.Log((object)("Loading minimap textures done [" + stopwatch.ElapsedMilliseconds + "ms]"));
			return true;
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(Minimap), "GenerateWorldMap")]
	public class MapGeneration
	{
		private static bool DoFakeGenerate;

		[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(2)]
		private static CancellationTokenSource CTS;

		public static bool Generating => CTS != null;

		private static bool Prefix(Minimap __instance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType == 4)
			{
				return true;
			}
			if (DoFakeGenerate)
			{
				DoFakeGenerate = false;
				return false;
			}
			if (BetterContinents.IsEnabled())
			{
				EWS.Log.LogInfo((object)"Better Contintents enabled, skipping map generation.");
				return true;
			}
			((MonoBehaviour)Game.instance).StartCoroutine(Coroutine(__instance));
			return false;
		}

		public static void Cancel()
		{
			if (CTS != null)
			{
				EWS.Log.LogInfo((object)"Cancelling previous map generation.");
				CTS.Cancel();
				CTS = null;
			}
		}

		public static void UpdateTextureSize(Minimap map, int textureSize)
		{
			//IL_0020: 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_0031: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//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_0092: Expected O, but got Unknown
			if (map.m_textureSize != textureSize)
			{
				map.m_textureSize = textureSize;
				map.m_mapTexture = new Texture2D(map.m_textureSize, map.m_textureSize, (TextureFormat)3, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				map.m_forestMaskTexture = new Texture2D(map.m_textureSize, map.m_textureSize, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				map.m_heightTexture = new Texture2D(map.m_textureSize, map.m_textureSize, (TextureFormat)18, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				map.m_fogTexture = new Texture2D(map.m_textureSize, map.m_textureSize, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				map.m_explored = new bool[map.m_textureSize * map.m_textureSize];
				map.m_exploredOthers = new bool[map.m_textureSize * map.m_textureSize];
				((Graphic)map.m_mapImageLarge).material.SetTexture("_MainTex", (Texture)(object)map.m_mapTexture);
				((Graphic)map.m_mapImageLarge).material.SetTexture("_MaskTex", (Texture)(object)map.m_forestMaskTexture);
				((Graphic)map.m_mapImageLarge).material.SetTexture("_HeightTex", (Texture)(object)map.m_heightTexture);
				((Graphic)map.m_mapImageLarge).material.SetTexture("_FogTex", (Texture)(object)map.m_fogTexture);
				((Graphic)map.m_mapImageSmall).material.SetTexture("_MainTex", (Texture)(object)map.m_mapTexture);
				((Graphic)map.m_mapImageSmall).material.SetTexture("_MaskTex", (Texture)(object)map.m_forestMaskTexture);
				((Graphic)map.m_mapImageSmall).material.SetTexture("_HeightTex", (Texture)(object)map.m_heightTexture);
				((Graphic)map.m_mapImageSmall).material.SetTexture("_FogTex", (Texture)(object)map.m_fogTexture);
				map.Reset();
			}
		}

		private static IEnumerator Coroutine(Minimap map)
		{
			Cancel();
			EWS.Log.LogInfo((object)"Starting map generation.");
			Stopwatch stopwatch = Stopwatch.StartNew();
			Minimap.DeleteMapTextureData(ZNet.World.m_name);
			int num = map.m_textureSize * map.m_textureSize;
			Color32[] mapTexture = (Color32[])(object)new Color32[num];
			Color32[] forestMaskTexture = (Color32[])(object)new Color32[num];
			Color[] heightTexture = (Color[])(object)new Color[num];
			Color32[] cachedTexture = (Color32[])(object)new Color32[num];
			CancellationTokenSource cts = new CancellationTokenSource();
			CancellationToken ct = cts.Token;
			while (Marketplace.IsLoading())
			{
				yield return null;
			}
			Task task = Generate(map, mapTexture, forestMaskTexture, heightTexture, cachedTexture, ct);
			CTS = cts;
			while (!task.IsCompleted)
			{
				yield return null;
			}
			if (task.IsFaulted)
			{
				EWS.Log.LogError((object)$"Map generation failed!\n{task.Exception}");
			}
			else if (!ct.IsCancellationRequested)
			{
				map.m_mapTexture.SetPixels32(mapTexture);
				yield return null;
				map.m_mapTexture.Apply();
				yield return null;
				map.m_forestMaskTexture.SetPixels32(forestMaskTexture);
				yield return null;
				map.m_forestMaskTexture.Apply();
				yield return null;
				map.m_heightTexture.SetPixels(heightTexture);
				yield return null;
				map.m_heightTexture.Apply();
				yield return null;
				DoFakeGenerate = true;
				map.GenerateWorldMap();
				Texture2D val = new Texture2D(map.m_textureSize, map.m_textureSize);
				val.SetPixels32(cachedTexture);
				val.Apply();
				EWS.Log.LogInfo((object)$"Map generation finished ({stopwatch.Elapsed.TotalSeconds:F0} seconds).");
				map.SaveMapTextureDataToDisk(map.m_forestMaskTexture, map.m_mapTexture, val);
			}
			stopwatch.Stop();
			cts.Dispose();
			if (CTS == cts)
			{
				CTS = null;
			}
		}

		private static async Task Generate(Minimap map, Color32[] mapTexture, Color32[] forestMaskTexture, Color[] heightTexture, Color32[] cachedtexture, CancellationToken ct)
		{
			await Task.Run(delegate
			{
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: 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)
				if (ct.IsCancellationRequested)
				{
					ct.ThrowIfCancellationRequested();
				}
				WorldGenerator instance = WorldGenerator.m_instance;
				int textureSize = map.m_textureSize;
				int num = textureSize / 2;
				float pixelSize = map.m_pixelSize;
				float num2 = pixelSize / 2f;
				float num3 = 127.5f;
				Color val = default(Color);
				for (int i = 0; i < textureSize; i++)
				{
					for (int j = 0; j < textureSize; j++)
					{
						float num4 = (float)(j - num) * pixelSize + num2;
						float num5 = (float)(i - num) * pixelSize + num2;
						while (Marketplace.IsLoading())
						{
							EWS.Log.LogInfo((object)"Waiting 100 ms for Marketplace to load...");
							Thread.Sleep(100);
						}
						Biome biome = instance.GetBiome(num4, num5, 0.02f, false);
						float biomeHeight = instance.GetBiomeHeight(biome, num4, num5, ref val, false);
						mapTexture[i * textureSize + j] = Color32.op_Implicit(map.GetPixelColor(biome));
						forestMaskTexture[i * textureSize + j] = Color32.op_Implicit(map.GetMaskColor(num4, num5, biomeHeight, biome));
						heightTexture[i * textureSize + j] = new Color(biomeHeight, 0f, 0f);
						int num6 = Mathf.Clamp((int)(biomeHeight * num3), 0, 65025);
						byte b = (byte)(num6 >> 8);
						byte b2 = (byte)((uint)num6 & 0xFFu);
						cachedtexture[i * textureSize + j] = new Color32(b, b2, (byte)0, byte.MaxValue);
						if (ct.IsCancellationRequested)
						{
							ct.ThrowIfCancellationRequested();
						}
					}
				}
			}).ConfigureAwait(continueOnCapturedContext: false);
		}
	}
	[HarmonyPatch(typeof(Game), "Logout")]
	public class CancelOnLogout
	{
		private static void Prefix()
		{
			MapGeneration.Cancel();
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	public static class Helper
	{
		public static CodeMatcher Replace(CodeMatcher instructions, double value, double newValue)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			return instructions.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R8, (object)value, (string)null)
			}).SetOperandAndAdvance((object)newValue);
		}

		public static CodeMatcher Replace(CodeMatcher instructions, float value, float newValue)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			return instructions.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)value, (string)null)
			}).SetOperandAndAdvance((object)newValue);
		}

		public static CodeMatcher ReplaceSeed(CodeMatcher instructions, string name, float value)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			return instructions.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(WorldGenerator), name), (string)null)
			}).Advance(-1).SetAndAdvance(OpCodes.Ldc_R4, (object)value)
				.RemoveInstruction();
		}

		public static float HeightToBaseHeight(float altitude)
		{
			return altitude / 200f;
		}

		public static bool IsServer()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return ZNet.instance.IsServer();
			}
			return false;
		}

		public static bool IsClient()
		{
			return !IsServer();
		}
	}
	[HarmonyPatch(typeof(Minimap), "Awake")]
	public class MinimapAwake
	{
		public static float OriginalPixelSize;

		public static int OriginalTextureSize;

		public static float OriginalMinZoom;

		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		public static void Postfix(Minimap __instance)
		{
			OriginalTextureSize = __instance.m_textureSize;
			__instance.m_textureSize = (int)((float)__instance.m_textureSize * Configuration.MapSize);
			OriginalMinZoom = __instance.m_maxZoom;
			__instance.m_maxZoom = Mathf.Max(1f, Configuration.MapSize);
			OriginalPixelSize = __instance.m_pixelSize;
			__instance.m_pixelSize *= Configuration.MapPixelSize;
		}
	}
	[HarmonyPatch(typeof(Minimap), "SetMapData")]
	public class InitializeWhenDimensionsChange
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		public static bool Prefix(Minimap __instance, byte[] data)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			ZPackage val = new ZPackage(data);
			if (val.ReadInt() >= 7)
			{
				val = val.ReadCompressedPackage();
			}
			int num = val.ReadInt();
			if (__instance.m_textureSize == num)
			{
				return true;
			}
			__instance.Reset();
			__instance.m_fogTexture.Apply();
			return false;
		}
	}
	[HarmonyPatch(typeof(Minimap), "Awake")]
	public class Minimap_Alignment
	{
		[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
		private static void Postfix(Minimap __instance)
		{
			__instance.m_biomeNameSmall.alignment = (TextAlignmentOptions)260;
			__instance.m_biomeNameLarge.alignment = (TextAlignmentOptions)260;
		}
	}
	[<c4b36d76-6cb1-44b6-9a59-26963b89a60d>NullableContext(1)]
	[<d4b92b1d-d7d8-4d52-8be1-44cf41ed231e>Nullable(0)]
	[HarmonyPatch(typeof(Minimap), "UpdateBiome")]
	public class Minimap_ShowLoading
	{
		private static string PreviousSmallText = "";

		private static string PreviousLargeText = "";

		private static void AddText(TMP_Text input, string text)
		{
			if (!input.text.Contains(text))
			{
				input.text += text;
			}
		}

		private static void CleanUp(TMP_Text input, string text)
		{
			if (!(text == "") && input.text.Contains(text))
			{
				input.text = input.text.Replace(text, "");
			}
		}

		private static string GetText()
		{
			return "\nLoading..";
		}

		private static void Postfix(Minimap __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_0080: Invalid comparison between Unknown and I4
			MapMode mode = __instance.m_mode;
			if (PreviousSmallText != "")
			{
				CleanUp(__instance.m_biomeNameSmall, PreviousSmallText);
				PreviousSmallText = "";
			}
			if (PreviousLargeText != "")
			{
				CleanUp(__instance.m_biomeNameLarge, PreviousLargeText);
				PreviousLargeText = "";
			}
			if ((int)mode == 1 && MapGeneration.Generating)
			{
				string text = GetText();
				AddText(__instance.m_biomeNameSmall, text);
				PreviousSmallText = text;
			}
			if ((int)mode == 2 && MapGeneration.Generating)
			{
				string text2 = GetText();
				AddText(__instance.m_biomeNameLarge, text2);
				PreviousLargeText = text2;
			}
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ServerSync
{
	[PublicAPI]
	public abstract class OwnConfigEntryBase
	{
		public object? LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[PublicAPI]
	public class SyncedConfigEntry<T> : OwnConfigEntryBase
	{
		public readonly ConfigEntry<T> SourceConfig;

		public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;

		public T Value
		{
			get
			{
				return SourceConfig.Value;
			}
			set
			{
				SourceConfig.Value = value;
			}
		}

		public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
		{
			SourceConfig = sourceConfig;
		}

		public void AssignLocalValue(T value)
		{
			if (LocalBaseValue == null)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal abstract class CustomSyncedValueBase
	{
		public object? LocalBaseValue;

		public readonly string Identifier;

		public readonly Type Type;

		private object? boxedValue;

		protected bool localIsOwner;

		public readonly int Priority;

		public object? BoxedValue
		{
			get
			{
				return boxedValue;
			}
			set
			{
				boxedValue = value;
				this.ValueChanged?.Invoke();
			}
		}

		public event Action? ValueChanged;

		protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority)
		{
			Priority = priority;
			Identifier = identifier;
			Type = type;
			configSync.AddCustomValue(this);
			localIsOwner = configSync.IsSourceOfTruth;
			configSync.SourceOfTruthChanged += delegate(bool truth)
			{
				localIsOwner = truth;
			};
		}
	}
	[PublicAPI]
	internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase
	{
		public T Value
		{
			get
			{
				return (T)base.BoxedValue;
			}
			set
			{
				base.BoxedValue = value;
			}
		}

		public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0)
			: base(configSync, identifier, typeof(T), priority)
		{
			Value = value;
		}

		public void AssignLocalValue(T value)
		{
			if (localIsOwner)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal class ConfigurationManagerAttributes
	{
		[UsedImplicitly]
		public bool? ReadOnly = false;
	}
	[PublicAPI]
	public class ConfigSync
	{
		[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
		private static class SnatchCurrentlyHandlingRPC
		{
			public static ZRpc? currentRpc;

			[HarmonyPrefix]
			private static void Prefix(ZRpc __instance)
			{
				currentRpc = __instance;
			}
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		internal static class RegisterRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance)
			{
				isServer = __instance.IsServer();
				foreach (ConfigSync configSync2 in configSyncs)
				{
					ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
					if (isServer)
					{
						configSync2.InitialSyncDone = true;
						Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
					}
				}
				if (isServer)
				{
					((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
				}
				static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
				{
					ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
					{
						new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = isAdmin
						}
					});
					ConfigSync configSync = configSyncs.First();
					if (configSync != null)
					{
						((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
					}
				}
				static IEnumerator WatchAdminListChanges()
				{
					MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
					SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
					List<string> CurrentList = new List<string>(adminList.GetList());
					while (true)
					{
						yield return (object)new WaitForSeconds(30f);
						if (!adminList.GetList().SequenceEqual(CurrentList))
						{
							CurrentList = new List<string>(adminList.GetList());
							List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p)
							{
								string hostName = p.m_rpc.GetSocket().GetHostName();
								return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName }));
							}).ToList();
							List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList();
							SendAdmin(nonAdminPeer, isAdmin: false);
							SendAdmin(adminPeer, isAdmin: true);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class RegisterClientRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (__instance.IsServer())
				{
					return;
				}
				foreach (ConfigSync configSync in configSyncs)
				{
					peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
				}
			}
		}

		private class ParsedConfigs
		{
			public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>();

			public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>();
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		private class ResetConfigsOnShutdown
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ProcessingServerUpdate = true;
				foreach (ConfigSync configSync in configSyncs)
				{
					configSync.resetConfigsFromServer();
					configSync.IsSourceOfTruth = true;
					configSync.InitialSyncDone = false;
				}
				ProcessingServerUpdate = false;
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		private class SendConfigsAfterLogin
		{
			private class BufferingSocket : ISocket
			{
				public volatile bool finished = false;

				public volatile int versionMatchQueued = -1;

				public readonly List<ZPackage> Package = new List<ZPackage>();

				public readonly ISocket Original;

				public BufferingSocket(ISocket original)
				{
					Original = original;
				}

				public bool IsConnected()
				{
					return Original.IsConnected();
				}

				public ZPackage Recv()
				{
					return Original.Recv();
				}

				public int GetSendQueueSize()
				{
					return Original.GetSendQueueSize();
				}

				public int GetCurrentSendRate()
				{
					return Original.GetCurrentSendRate();
				}

				public bool IsHost()
				{
					return Original.IsHost();
				}

				public void Dispose()
				{
					Original.Dispose();
				}

				public bool GotNewData()
				{
					return Original.GotNewData();
				}

				public void Close()
				{
					Original.Close();
				}

				public string GetEndPointString()
				{
					return Original.GetEndPointString();
				}

				public void GetAndResetStats(out int totalSent, out int totalRecv)
				{
					Original.GetAndResetStats(ref totalSent, ref totalRecv);
				}

				public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
				{
					Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
				}

				public ISocket Accept()
				{
					return Original.Accept();
				}

				public int GetHostPort()
				{
					return Original.GetHostPort();
				}

				public bool Flush()
				{
					return Original.Flush();
				}

				public string GetHostName()
				{
					return Original.GetHostName();
				}

				public void VersionMatch()
				{
					if (finished)
					{
						Original.VersionMatch();
					}
					else
					{
						versionMatchQueued = Package.Count;
					}
				}

				public void Send(ZPackage pkg)
				{
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_005d: Expected O, but got Unknown
					int pos = pkg.GetPos();
					pkg.SetPos(0);
					int num = pkg.ReadInt();
					if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
					{
						ZPackage val = new ZPackage(pkg.GetArray());
						val.SetPos(pos);
						Package.Add(val);
					}
					else
					{
						pkg.SetPos(pos);
						Original.Send(pkg);
					}
				}
			}

			[HarmonyPriority(800)]
			[HarmonyPrefix]
			private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Invalid comparison between Unknown and I4
				if (__instance.IsServer())
				{
					BufferingSocket value = new BufferingSocket(rpc.GetSocket());
					AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value);
					object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
					ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (val != null && (int)ZNet.m_onlineBackend > 0)
					{
						AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value);
					}
					if (__state == null)
					{
						__state = new Dictionary<Assembly, BufferingSocket>();
					}
					__state[Assembly.GetExecutingAssembly()] = value;
				}
			}

			[HarmonyPostfix]
			private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
			{
				ZRpc rpc2 = rpc;
				ZNet __instance2 = __instance;
				Dictionary<Assembly, BufferingSocket> __state2 = __state;
				ZNetPeer peer;
				if (__instance2.IsServer())
				{
					object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
					peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (peer == null)
					{
						SendBufferedData();
					}
					else
					{
						((MonoBehaviour)__instance2).StartCoroutine(sendAsync());
					}
				}
				void SendBufferedData()
				{
					if (rpc2.GetSocket() is BufferingSocket bufferingSocket)
					{
						AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original);
						object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
						ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null);
						if (val != null)
						{
							AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
						}
					}
					BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()];
					bufferingSocket2.finished = true;
					for (int i = 0; i < bufferingSocket2.Package.Count; i++)
					{
						if (i == bufferingSocket2.versionMatchQueued)
						{
							bufferingSocket2.Original.VersionMatch();
						}
						bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
					}
					if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
					{
						bufferingSocket2.Original.VersionMatch();
					}
				}
				IEnumerator sendAsync()
				{
					foreach (ConfigSync configSync in configSyncs)
					{
						List<PackageEntry> entries = new List<PackageEntry>();
						if (configSync.CurrentVersion != null)
						{
							entries.Add(new PackageEntry
							{
								section = "Internal",
								key = "serverversion",
								type = typeof(string),
								value = configSync.CurrentVersion
							});
						}
						MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						entries.Add(new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2]
							{
								adminList,
								rpc2.GetSocket().GetHostName()
							}))
						});
						ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false);
						yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package));
					}
					SendBufferedData();
				}
			}
		}

		private class PackageEntry
		{
			public string section = null;

			public string key = null;

			public Type type = null;

			public object? value;
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")]
		private static class PreventSavingServerInfo
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, ref string __result)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase))
				{
					return true;
				}
				__result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType);
				return false;
			}
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")]
		private static class PreventConfigRereadChangingValues
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, string value)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null)
				{
					return true;
				}
				try
				{
					ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType);
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
				}
				return false;
			}
		}

		private class InvalidDeserializationTypeException : Exception
		{
			public string expected = null;

			public string received = null;

			public string field = "";
		}

		public static bool ProcessingServerUpdate;

		public readonly string Name;

		public string? DisplayName;

		public string? CurrentVersion;

		public string? MinimumRequiredVersion;

		public bool ModRequired = false;

		private bool? forceConfigLocking;

		private bool isSourceOfTruth = true;

		private static readonly HashSet<ConfigSync> configSyncs;

		private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>();

		private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>();

		private static bool isServer;

		private static bool lockExempt;

		private OwnConfigEntryBase? lockedConfig = null;

		private const byte PARTIAL_CONFIGS = 1;

		private const byte FRAGMENTED_CONFIG = 2;

		private const byte COMPRESSED_CONFIG = 4;

		private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>();

		private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>();

		private static long packageCounter;

		public bool IsLocked
		{
			get
			{
				bool? flag = forceConfigLocking;
				bool num;
				if (!flag.HasValue)
				{
					if (lockedConfig == null)
					{
						goto IL_0052;
					}
					num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0;
				}
				else
				{
					num = flag.GetValueOrDefault();
				}
				if (!num)
				{
					goto IL_0052;
				}
				int result = ((!lockExempt) ? 1 : 0);
				goto IL_0053;
				IL_0053:
				return (byte)result != 0;
				IL_0052:
				result = 0;
				goto IL_0053;
			}
			set
			{
				forceConfigLocking = value;
			}
		}

		public bool IsAdmin => lockExempt || isSourceOfTruth;

		public bool IsSourceOfTruth
		{
			get
			{
				return isSourceOfTruth;
			}
			private set
			{
				if (value != isSourceOfTruth)
				{
					isSourceOfTruth = value;
					this.SourceOfTruthChanged?.Invoke(value);
				}
			}
		}

		public bool InitialSyncDone { get; private set; } = false;


		public event Action<bool>? SourceOfTruthChanged;

		private event Action? lockedConfigChanged;

		static ConfigSync()
		{
			ProcessingServerUpdate = false;
			configSyncs = new HashSet<ConfigSync>();
			lockExempt = false;
			packageCounter = 0L;
			RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle);
		}

		public ConfigSync(string name)
		{
			Name = name;
			configSyncs.Add(this);
			new VersionCheck(this);
		}

		public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			ConfigEntry<T> configEntry2 = configEntry;
			OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2);
			SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>;
			if (syncedEntry == null)
			{
				syncedEntry = new SyncedConfigEntry<T>(configEntry2);
				AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, new object[1]
				{
					new ConfigurationManagerAttributes()
				}.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()).Concat(new SyncedConfigEntry<T>[1] { syncedEntry }).ToArray());
				configEntry2.SettingChanged += delegate
				{
					if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig)
					{
						Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2);
					}
				};
				allConfigs.Add(syncedEntry);
			}
			return syncedEntry;
		}

		public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible
		{
			if (lockedConfig != null)
			{
				throw new Exception("Cannot initialize locking ConfigEntry twice");
			}
			lockedConfig = AddConfigEntry<T>(lockingConfig);
			lockingConfig.SettingChanged += delegate
			{
				this.lockedConfigChanged?.Invoke();
			};
			return (SyncedConfigEntry<T>)lockedConfig;
		}

		internal void AddCustomValue(CustomSyncedValueBase customValue)
		{
			CustomSyncedValueBase customValue2 = customValue;
			if (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue2.Identifier))
			{
				throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)");
			}
			allCustomValues.Add(customValue2);
			allCustomValues = new HashSet<CustomSyncedValueBase>(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority));
			customValue2.ValueChanged += delegate
			{
				if (!ProcessingServerUpdate)
				{
					Broadcast(ZRoutedRpc.Everybody, customValue2);
				}
			};
		}

		private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package)
		{
			lockedConfigChanged += serverLockedSettingChanged;
			IsSourceOfTruth = false;
			if (HandleConfigSyncRPC(0L, package, clientUpdate: false))
			{
				InitialSyncDone = true;
			}
		}

		private void RPC_FromOtherClientConfigSync(long sender, ZPackage package)
		{
			HandleConfigSyncRPC(sender, package, clientUpdate: true);
		}

		private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			try
			{
				if (isServer && IsLocked)
				{
					ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc;
					object obj;
					if (currentRpc == null)
					{
						obj = null;
					}
					else
					{
						ISocket socket = currentRpc.GetSocket();
						obj = ((socket != null) ? socket.GetHostName() : null);
					}
					string text = (string)obj;
					if (text != null)
					{
						MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text }))))
						{
							return false;
						}
					}
				}
				cacheExpirations.RemoveAll(delegate(KeyValuePair<long, string> kv)
				{
					if (kv.Key < DateTimeOffset.Now.Ticks)
					{
						configValueCache.Remove(kv.Value);
						return true;
					}
					return false;
				});
				byte b = package.ReadByte();
				if ((b & 2u) != 0)
				{
					long num = package.ReadLong();
					string text2 = sender.ToString() + num;
					if (!configValueCache.TryGetValue(text2, out SortedDictionary<int, byte[]> value))
					{
						value = new SortedDictionary<int, byte[]>();
						configValueCache[text2] = value;
						cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2));
					}
					int key = package.ReadInt();
					int num2 = package.ReadInt();
					value.Add(key, package.ReadByteArray());
					if (value.Count < num2)
					{
						return false;
					}
					configValueCache.Remove(text2);
					package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray());
					b = package.ReadByte();
				}
				ProcessingServerUpdate = true;
				if ((b & 4u) != 0)
				{
					byte[] buffer = package.ReadByteArray();
					MemoryStream stream = new MemoryStream(buffer);
					MemoryStream memoryStream = new MemoryStream();
					using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
					{
						deflateStream.CopyTo(memoryStream);
					}
					package = new ZPackage(memoryStream.ToArray());
					b = package.ReadByte();
				}
				if ((b & 1) == 0)
				{
					resetConfigsFromServer();
				}
				ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package);
				ConfigFile val2 = null;
				bool saveOnConfigSet = false;
				foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues)
				{
					if (!isServer && configValue.Key.LocalBaseValue == null)
					{
						configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue;
					}
					if (val2 == null)
					{
						val2 = configValue.Key.BaseConfig.ConfigFile;
						saveOnConfigSet = val2.SaveOnConfigSet;
						val2.SaveOnConfigSet = false;
					}
					configValue.Key.BaseConfig.BoxedValue = configValue.Value;
				}
				if (val2 != null)
				{
					val2.SaveOnConfigSet = saveOnConfigSet;
				}
				foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues)
				{
					if (!isServer)
					{
						CustomSyncedValueBase key2 = customValue.Key;
						if (key2.LocalBaseValue == null)
						{
							key2.LocalBaseValue = customValue.Key.BoxedValue;
						}
					}
					customValue.Key.BoxedValue = customValue.Value;
				}
				Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name));
				if (!isServer)
				{
					serverLockedSettingChanged();
				}
				return true;
			}
			finally
			{
				ProcessingServerUpdate = false;
			}
		}

		private ParsedConfigs ReadConfigsFromPackage(ZPackage package)
		{
			ParsedConfigs parsedConfigs = new ParsedConfigs();
			Dictionary<string, OwnConfigEntryBase> dictionary = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c);
			Dictionary<string, CustomSyncedValueBase> dictionary2 = allCustomValues.ToDictionary((CustomSyncedValueBase c) => c.Identifier, (CustomSyncedValueBase c) => c);
			int num = package.ReadInt();
			for (int i = 0; i < num; i++)
			{
				string text = package.ReadString();
				string text2 = package.ReadString();
				string text3 = package.ReadString();
				Type type = Type.GetType(text3);
				if (text3 == "" || type != null)
				{
					object obj;
					try
					{
						obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type));
					}
					catch (InvalidDeserializationTypeException ex)
					{
						Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected));
						continue;
					}
					OwnConfigEntryBase value2;
					if (text == "Internal")
					{
						CustomSyncedValueBase value;
						if (text2 == "serverversion")
						{
							if (obj?.ToString() != CurrentVersion)
							{
								Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown")));
							}
						}
						else if (text2 == "lockexempt")
						{
							if (obj is bool flag)
							{
								lockExempt = flag;
							}
						}
						else if (dictionary2.TryGetValue(text2, out value))
						{
							if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3)
							{
								parsedConfigs.customValues[value] = obj;
								continue;
							}
							Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName));
						}
					}
					else if (dictionary.TryGetValue(text + "_" + text2, out value2))
					{
						Type type2 = configType(value2.BaseConfig);
						if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3)
						{
							parsedConfigs.configValues[value2] = obj;
							continue;
						}
						Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName));
					}
					else
					{
						Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match."));
					}
					continue;
				}
				Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs"));
				return new ParsedConfigs();
			}
			return parsedConfigs;
		}

		private static bool isWritableConfig(OwnConfigEntryBase config)
		{
			OwnConfigEntryBase config2 = config;
			ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config2));
			if (configSync == null)
			{
				return true;
			}
			return configSync.IsSourceOfTruth || !config2.SynchronizedConfig || config2.LocalBaseValue == null || (!configSync.IsLocked && (config2 != configSync.lockedConfig || lockExempt));
		}

		private void serverLockedSettingChanged()
		{
			foreach (OwnConfigEntryBase allConfig in allConfigs)
			{
				configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig);
			}
		}

		private void resetConfigsFromServer()
		{
			ConfigFile val = null;
			bool saveOnConfigSet = false;
			foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null))
			{
				if (val == null)
				{
					val = item.BaseConfig.ConfigFile;
					saveOnConfigSet = val.SaveOnConfigSet;
					val.SaveOnConfigSet = false;
				}
				item.BaseConfig.BoxedValue = item.LocalBaseValue;
				item.LocalBaseValue = null;
			}
			if (val != null)
			{
				val.SaveOnConfigSet = saveOnConfigSet;
			}
			foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null))
			{
				item2.BoxedValue = item2.LocalBaseValue;
				item2.LocalBaseValue = null;
			}
			lockedConfigChanged -= serverLockedSettingChanged;
			serverLockedSettingChanged();
		}

		private IEnumerator<bool> distributeConfigToPeers(ZNetPeer peer, ZPackage package)
		{
			ZNetPeer peer2 = peer;
			ZRoutedRpc rpc = ZRoutedRpc.instance;
			if (rpc == null)
			{
				yield break;
			}
			byte[] data = package.GetArray();
			if (data != null && data.LongLength > 250000)
			{
				int fragments = (int)(1 + (data.LongLength - 1) / 250000);
				long packageIdentifier = ++pack