Decompiled source of Render Limits v1.16.0

RenderLimits.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Service;
using UnityEngine;

[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("RenderLimits")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2e65b4f5dfcef7b4fedd99da69e19c534635a09c")]
[assembly: AssemblyProduct("RenderLimits")]
[assembly: AssemblyTitle("RenderLimits")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Service
{
	public class ConfigWrapper
	{
		private readonly ConfigFile ConfigFile;

		private readonly Dictionary<string, Action<Terminal, string>> SettingHandlers = new Dictionary<string, Action<Terminal, string>>();

		public ConfigWrapper(string command, ConfigFile configFile)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0044: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			ConfigFile = configFile;
			new ConsoleCommand(command, "[key] [value] - Toggles or sets a config value.", (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				if (args.Length >= 2 && SettingHandlers.TryGetValue(args[1].ToLower(), out Action<Terminal, string> value))
				{
					if (args.Length == 2)
					{
						value(args.Context, "");
					}
					else
					{
						value(args.Context, string.Join(" ", args.Args.Skip(2)));
					}
				}
			}, false, false, false, false, false, false, (ConsoleOptionsFetcher)(() => SettingHandlers.Keys.ToList()), false, false, false);
		}

		private void HandleChange(ConfigEntry<string> configEntry, Action onChange)
		{
			configEntry.SettingChanged += delegate
			{
				onChange();
			};
		}

		private void HandleChange(ConfigEntry<string> configEntry, Action<string> onChange)
		{
			configEntry.SettingChanged += delegate
			{
				onChange(configEntry.Value);
			};
			onChange(configEntry.Value);
		}

		private void HandleChange(ConfigEntry<string> configEntry, Action<int> onChange)
		{
			HandleChange(configEntry, onSettingChanged);
			void onSettingChanged(string value)
			{
				if (TryParseInt(value, out var result))
				{
					onChange(result);
				}
			}
		}

		private void HandleChange(ConfigEntry<string> configEntry, Action<float> onChange)
		{
			HandleChange(configEntry, onSettingChanged);
			void onSettingChanged(string value)
			{
				if (TryParseFloat(value, out var result))
				{
					onChange(result);
				}
			}
		}

		public ConfigEntry<bool> Bind(string group, string name, bool value, string description)
		{
			ConfigEntry<bool> val = ConfigFile.Bind<bool>(group, name, value, description);
			Register<bool>(val);
			return val;
		}

		public ConfigEntry<bool> Bind(string group, string name, bool value, string description, Action onChange)
		{
			ConfigEntry<bool> obj = Bind(group, name, value, description);
			obj.SettingChanged += delegate
			{
				onChange();
			};
			return obj;
		}

		public ConfigEntry<string> Bind(string group, string name, string value, string description, Action onChange)
		{
			ConfigEntry<string> val = ConfigFile.Bind<string>(group, name, value, description);
			Register(val);
			HandleChange(val, onChange);
			return val;
		}

		public ConfigEntry<string> Bind(string group, string name, string value, string description, Action<string> onChange)
		{
			ConfigEntry<string> val = ConfigFile.Bind<string>(group, name, value, description);
			Register(val);
			HandleChange(val, onChange);
			return val;
		}

		public ConfigEntry<string> Bind(string group, string name, string value, string description, Action<int> onChange)
		{
			ConfigEntry<string> val = ConfigFile.Bind<string>(group, name, value, description);
			Register(val);
			HandleChange(val, onChange);
			return val;
		}

		public ConfigEntry<string> Bind(string group, string name, string value, string description, Action<float> onChange)
		{
			ConfigEntry<string> val = ConfigFile.Bind<string>(group, name, value, description);
			Register(val);
			HandleChange(val, onChange);
			return val;
		}

		private static void AddMessage(Terminal context, string message)
		{
			context.AddString(message);
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)1, message, 0, (Sprite)null, false);
			}
		}

		private void Register(ConfigEntry<string> setting)
		{
			string name = ((ConfigEntryBase)setting).Definition.Key;
			string key = name.ToLower().Replace(' ', '_');
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				SetValue<string>(terminal, setting, name, value);
			});
		}

		private void Register<T>(ConfigEntry<T> setting)
		{
			string name = ((ConfigEntryBase)setting).Definition.Key;
			string key = name.ToLower().Replace(' ', '_');
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				SetValue<T>(terminal, setting, name, value);
			});
		}

		public static int ParseInt(string value, int defaultValue)
		{
			if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static bool TryParseInt(ConfigEntry<string> setting, out int result)
		{
			return TryParseInt(setting.Value, out result);
		}

		public static bool TryParseInt(string value, out int result)
		{
			return int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
		}

		public static int ParseInt(ConfigEntry<string> setting)
		{
			if (int.TryParse(setting.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return ParseInt((string)((ConfigEntryBase)setting).DefaultValue, 0);
		}

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

		public static float ParseFloat(ConfigEntry<string> setting)
		{
			if (float.TryParse(setting.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return ParseFloat((string)((ConfigEntryBase)setting).DefaultValue, 0f);
		}

		public static bool TryParseFloat(string value, out float result)
		{
			return float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
		}

		private static void SetValue<T>(Terminal context, ConfigEntry<T> setting, string name, string value)
		{
			if (value == "")
			{
				AddMessage(context, $"{name}: {setting.Value}.");
				return;
			}
			((ConfigEntryBase)setting).SetSerializedValue(value);
			AddMessage(context, name + " set to " + value + ".");
		}
	}
	public class Helper
	{
		public static void AddMessage(Terminal context, string message, bool priority = true)
		{
			context.AddString(message);
			MessageHud instance = MessageHud.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return;
			}
			if (priority)
			{
				MsgData[] array = instance.m_msgQeue.ToArray();
				instance.m_msgQeue.Clear();
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)1, message, 0, (Sprite)null, false);
				}
				MsgData[] array2 = array;
				foreach (MsgData item in array2)
				{
					instance.m_msgQeue.Enqueue(item);
				}
				instance.m_msgQueueTimer = 10f;
			}
			else
			{
				Player localPlayer2 = Player.m_localPlayer;
				if (localPlayer2 != null)
				{
					((Character)localPlayer2).Message((MessageType)1, message, 0, (Sprite)null, false);
				}
			}
		}

		public static void Command(string name, string description, ConsoleEvent action, ConsoleOptionsFetcher? fetcher = null)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand(name, description, Catch(action), false, false, false, false, false, false, fetcher, false, false, false);
		}

		public static void AddError(Terminal context, string message, bool priority = true)
		{
			AddMessage(context, "Error: " + message, priority);
		}

		public static ConsoleEvent Catch(ConsoleEvent action)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				try
				{
					if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
					{
						throw new InvalidOperationException("Player not found.");
					}
					action.Invoke(args);
				}
				catch (InvalidOperationException ex)
				{
					AddError(args.Context, ex.Message);
				}
			};
		}
	}
}
namespace RenderLimits
{
	public class Configuration
	{
		public static ConfigEntry<string> configActivateArea;

		public static ConfigEntry<string> configLoadedArea;

		public static ConfigEntry<string> configGeneratedArea;

		public static ConfigEntry<bool> configClassicShape;

		public static ConfigEntry<string> configRealTerrainVisibility;

		public static ConfigEntry<string> configClutterVisibility;

		public static ConfigEntry<string> configForceActive;

		public static HashSet<Vector2s> ForceActive = new HashSet<Vector2s>();

		private static readonly Dictionary<long, HashSet<Vector2s>> forceActiveByWorld = new Dictionary<long, HashSet<Vector2s>>();

		private static long world;

		public static ConfigEntry<string> configMaximumGeneratedArea;

		public static ConfigEntry<bool> configAllowForceActive;

		public static ConfigEntry<string> configMaximumForceActive;

		public static ConfigEntry<string> configPixelLightCount;

		public static ConfigEntry<string> configShadowCascades;

		public static ConfigEntry<string> configShadowQuality;

		public static ConfigEntry<string> configShadowDistance;

		public static ConfigEntry<string> configShadowResolution;

		public static ConfigEntry<string> configLodBias;

		public static int ActiveArea => ConfigWrapper.ParseInt(configActivateArea);

		public static int LoadedArea => ConfigWrapper.ParseInt(configLoadedArea);

		public static int GeneratedArea => ConfigWrapper.ParseInt(configGeneratedArea);

		public static bool ClassicShape => configClassicShape.Value;

		public static int RealTerrainVisibility => ConfigWrapper.ParseInt(configRealTerrainVisibility);

		public static int ClutterVisibility => ConfigWrapper.ParseInt(configClutterVisibility);

		public static int MaximumGeneratedArea => Math.Max(1, ConfigWrapper.ParseInt(configMaximumGeneratedArea));

		public static bool AllowForceActive => configAllowForceActive.Value;

		public static int MaximumForceActive => Math.Max(0, ConfigWrapper.ParseInt(configMaximumForceActive));

		private static void ParseForceActive(string value)
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			forceActiveByWorld.Clear();
			string[] array = value.Split(new char[1] { ';' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ':' });
				if (array2.Length != 2 || !long.TryParse(array2[0].Trim(), out var result))
				{
					continue;
				}
				HashSet<Vector2s> hashSet = new HashSet<Vector2s>();
				foreach (string[] item in from s in array2[1].Split(new char[1] { '|' })
					select s.Trim().Split(new char[1] { ',' }) into s
					where s.Length == 2
					select s)
				{
					if (int.TryParse(item[0], out var result2) && int.TryParse(item[1], out var result3))
					{
						hashSet.Add(new Vector2s(result2, result3));
					}
				}
				forceActiveByWorld[result] = hashSet;
			}
			SelectWorld();
		}

		public static void SelectWorld()
		{
			world = ZNet.m_world?.m_uid ?? 0;
			if (!forceActiveByWorld.TryGetValue(world, out var value))
			{
				value = (forceActiveByWorld[world] = new HashSet<Vector2s>());
			}
			ForceActive = value;
		}

		public static void SaveForceActive()
		{
			forceActiveByWorld[world] = ForceActive;
			configForceActive.Value = string.Join(";", from s in forceActiveByWorld
				where s.Value.Count > 0
				select string.Format("{0}:{1}", s.Key, string.Join("|", s.Value.Select((Vector2s z) => $"{z.x},{z.y}"))));
		}

		public static void Init(ConfigFile configFile)
		{
			ConfigWrapper configWrapper = new ConfigWrapper("render_config", configFile);
			string text = "1. Zones";
			configActivateArea = configWrapper.Bind(text, "Active zones", "1", "Amounts of zones that are active around the player. Creatures are active in this area.", LimitManager.Update);
			configLoadedArea = configWrapper.Bind(text, "Loaded zones", "2", "Amounts of zones loaded around the player. Structures are visible in this area. ", LimitManager.Update);
			configGeneratedArea = configWrapper.Bind(text, "Generated zones", "4", "Amounts of zones generated around the player. Large static objects like trees are visible in this area.", LimitManager.Update);
			configClassicShape = configWrapper.Bind(text, "Classic shape", value: true, "Zones are loaded in a square. If false, the corners are cut and the area is rounded (active zones are reduced to fit).", LimitManager.Update);
			configRealTerrainVisibility = configWrapper.Bind(text, "Real terrain visibility", "0", "Visibility in meters. If 0, the game decides from loaded area.", (Action)Heightmap.ApplySettingsOnAll);
			configForceActive = configWrapper.Bind(text, "Force active", "", "Zones that are always active. Saved for each world.", (Action)delegate
			{
				ParseForceActive(configForceActive.Value);
				ForceZones.Send();
			});
			text = "2. Quality";
			configClutterVisibility = configWrapper.Bind(text, "Clutter visibility", "45", "Visibility in meters.", ClutterDistance.Update);
			configLodBias = configWrapper.Bind(text, "Lod bias", "", "Level of detail limit (increase to show smaller objects, vanilla is from 1 to 5 but even 100 works).", delegate(int value)
			{
				QualitySettings.lodBias = value;
			});
			configPixelLightCount = configWrapper.Bind(text, "Pixel light count", "", "Light detail (bigger the better, vanilla is from 2 to 8).", delegate(int value)
			{
				QualitySettings.pixelLightCount = value;
			});
			configShadowCascades = configWrapper.Bind(text, "Shadow cascades", "", "Improves shadows near the camera (bigger the better, vanilla is from 2 to 4).", delegate(int value)
			{
				QualitySettings.shadowCascades = value;
			});
			configShadowQuality = configWrapper.Bind(text, "Shadow quality", "", "0: off, 1: hard only, 2: all.", delegate(int value)
			{
				QualitySettings.shadows = (ShadowQuality)Math.Max(0, Math.Min(2, value));
			});
			configShadowDistance = configWrapper.Bind(text, "Shadow distance", "", "Max distance for shadows in meters (vanilla is from 80 to 150).", delegate(float value)
			{
				QualitySettings.shadowDistance = value;
			});
			configShadowResolution = configWrapper.Bind(text, "Shadow resolution", "", "Shadow quality. From 0 to 3.", delegate(int value)
			{
				QualitySettings.shadowResolution = (ShadowResolution)Math.Max(0, Math.Min(3, value));
			});
			text = "3. Server limits";
			configMaximumGeneratedArea = configWrapper.Bind(text, "Maximum generated zones", "10", "Maximum generated zones. Also limits loaded zones and active zones. Applies to every client.", LimitManager.UpdateMaximum);
			configAllowForceActive = configWrapper.Bind(text, "Allow force active", value: false, "Whether clients can have force active areas.");
			configMaximumForceActive = configWrapper.Bind(text, "Maximum force active zones", "64", "Maximum force active zones for each client.", (Action<int>)delegate
			{
			});
			ParseForceActive(configForceActive.Value);
			LimitManager.Update();
		}

		public static void InitSettings()
		{
			if (ConfigWrapper.TryParseInt(configLodBias.Value, out var result))
			{
				QualitySettings.lodBias = result;
			}
			if (ConfigWrapper.TryParseInt(configPixelLightCount.Value, out var result2))
			{
				QualitySettings.pixelLightCount = result2;
			}
			if (ConfigWrapper.TryParseInt(configShadowCascades.Value, out var result3))
			{
				QualitySettings.shadowCascades = result3;
			}
			if (ConfigWrapper.TryParseInt(configShadowQuality.Value, out var result4))
			{
				QualitySettings.shadows = (ShadowQuality)Math.Max(0, Math.Min(2, result4));
			}
			if (ConfigWrapper.TryParseFloat(configShadowDistance.Value, out var result5))
			{
				QualitySettings.shadowDistance = result5;
			}
			if (ConfigWrapper.TryParseInt(configShadowResolution.Value, out var result6))
			{
				QualitySettings.shadowResolution = (ShadowResolution)Math.Max(0, Math.Min(3, result6));
			}
		}
	}
	[HarmonyPatch(typeof(ClutterSystem), "Awake")]
	public class ClutterDistance
	{
		private static void Postfix(ClutterSystem __instance)
		{
			Set(__instance);
		}

		private static void Set(ClutterSystem obj)
		{
			obj.m_distance = Configuration.ClutterVisibility;
			obj.ClearAll();
		}

		public static void Update()
		{
			if (Object.op_Implicit((Object)(object)ClutterSystem.instance))
			{
				Set(ClutterSystem.instance);
			}
		}
	}
	public class ForceActiveCommand
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static Func<Vector2s, bool> <>9__0_4;

			public static Func<Vector2s, bool> <>9__0_5;

			public static Func<Vector2s, string> <>9__0_2;

			public static Func<Vector2s, string> <>9__0_3;

			public static ConsoleEvent <>9__0_1;

			internal void <.ctor>b__0_0(ConsoleEventArgs args)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_016c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				string text = "toggle";
				if (args.Length > 1)
				{
					text = args[1];
				}
				int num = 0;
				if (args.Length > 2 && int.TryParse(args[2], out var result))
				{
					num = result;
				}
				Vector2s zone = ZoneSystem.GetZone(ZNet.instance.GetReferencePosition());
				Vector2s val = default(Vector2s);
				for (int i = -num; i <= num; i++)
				{
					for (int j = -num; j <= num; j++)
					{
						((Vector2s)(ref val))..ctor(zone.x + i, zone.y + j);
						bool flag = Configuration.ForceActive.Contains(val);
						bool num2 = text == "add" || (text != "remove" && !flag);
						if (num2 && flag)
						{
							Helper.AddMessage(args.Context, $"Zone {val.x},{val.y} is already in active zones.");
						}
						if (!num2 && !flag)
						{
							Helper.AddMessage(args.Context, $"Zone {val.x},{val.y} is not in active zones.");
						}
						if (!num2 && flag)
						{
							Helper.AddMessage(args.Context, $"Zone {val.x},{val.y} removed from active zones.");
							Configuration.ForceActive.Remove(val);
						}
						if (num2 && !flag)
						{
							Helper.AddMessage(args.Context, $"Zone {val.x},{val.y} added to active zones.");
							Configuration.ForceActive.Add(val);
						}
					}
				}
				Configuration.SaveForceActive();
			}

			internal void <.ctor>b__0_1(ConsoleEventArgs args)
			{
				if (!ForceZones.Accepted)
				{
					Helper.AddMessage(args.Context, "The server did not accept the force active zones.");
				}
				Dictionary<Vector2s, ZoneData> zones = ZoneSystem.instance.m_zones;
				List<Vector2s> list = new List<Vector2s>();
				list.AddRange(zones.Keys.Where((Vector2s zone) => ForceZones.Local.Contains(zone)));
				List<Vector2s> source = list;
				List<Vector2s> list2 = new List<Vector2s>();
				list2.AddRange(zones.Keys.Where((Vector2s zone) => !ForceZones.Local.Contains(zone)));
				List<Vector2s> source2 = list2;
				Helper.AddMessage(args.Context, "Forced: " + string.Join(", ", source.Select((Vector2s zone) => $"{zone.x},{zone.y}")));
				Helper.AddMessage(args.Context, "Default: " + string.Join(", ", source2.Select((Vector2s zone) => $"{zone.x},{zone.y}")));
			}

			internal bool <.ctor>b__0_4(Vector2s zone)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				return ForceZones.Local.Contains(zone);
			}

			internal bool <.ctor>b__0_5(Vector2s zone)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				return !ForceZones.Local.Contains(zone);
			}

			internal string <.ctor>b__0_2(Vector2s zone)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				return $"{zone.x},{zone.y}";
			}

			internal string <.ctor>b__0_3(Vector2s zone)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				return $"{zone.x},{zone.y}";
			}
		}

		public ForceActiveCommand()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					//IL_0039: Unknown result type (might be due to invalid IL or missing references)
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					//IL_0058: Unknown result type (might be due to invalid IL or missing references)
					//IL_0061: Unknown result type (might be due to invalid IL or missing references)
					//IL_0074: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
					//IL_011f: Unknown result type (might be due to invalid IL or missing references)
					//IL_012b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0147: Unknown result type (might be due to invalid IL or missing references)
					//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
					//IL_0160: Unknown result type (might be due to invalid IL or missing references)
					//IL_016c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0188: Unknown result type (might be due to invalid IL or missing references)
					string text = "toggle";
					if (args.Length > 1)
					{
						text = args[1];
					}
					int num = 0;
					if (args.Length > 2 && int.TryParse(args[2], out var result))
					{
						num = result;
					}
					Vector2s zone = ZoneSystem.GetZone(ZNet.instance.GetReferencePosition());
					Vector2s val3 = default(Vector2s);
					for (int i = -num; i <= num; i++)
					{
						for (int j = -num; j <= num; j++)
						{
							((Vector2s)(ref val3))..ctor(zone.x + i, zone.y + j);
							bool flag = Configuration.ForceActive.Contains(val3);
							bool num2 = text == "add" || (text != "remove" && !flag);
							if (num2 && flag)
							{
								Helper.AddMessage(args.Context, $"Zone {val3.x},{val3.y} is already in active zones.");
							}
							if (!num2 && !flag)
							{
								Helper.AddMessage(args.Context, $"Zone {val3.x},{val3.y} is not in active zones.");
							}
							if (!num2 && flag)
							{
								Helper.AddMessage(args.Context, $"Zone {val3.x},{val3.y} removed from active zones.");
								Configuration.ForceActive.Remove(val3);
							}
							if (num2 && !flag)
							{
								Helper.AddMessage(args.Context, $"Zone {val3.x},{val3.y} added to active zones.");
								Configuration.ForceActive.Add(val3);
							}
						}
					}
					Configuration.SaveForceActive();
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			Helper.Command("force_active", "[add/remove/toggle] [around=0] - Toggles the force active of the current zone.", (ConsoleEvent)obj);
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleEvent val2 = delegate(ConsoleEventArgs args)
				{
					if (!ForceZones.Accepted)
					{
						Helper.AddMessage(args.Context, "The server did not accept the force active zones.");
					}
					Dictionary<Vector2s, ZoneData> zones = ZoneSystem.instance.m_zones;
					List<Vector2s> list = new List<Vector2s>();
					list.AddRange(zones.Keys.Where((Vector2s zone) => ForceZones.Local.Contains(zone)));
					List<Vector2s> source = list;
					List<Vector2s> list2 = new List<Vector2s>();
					list2.AddRange(zones.Keys.Where((Vector2s zone) => !ForceZones.Local.Contains(zone)));
					List<Vector2s> source2 = list2;
					Helper.AddMessage(args.Context, "Forced: " + string.Join(", ", source.Select((Vector2s zone) => $"{zone.x},{zone.y}")));
					Helper.AddMessage(args.Context, "Default: " + string.Join(", ", source2.Select((Vector2s zone) => $"{zone.x},{zone.y}")));
				};
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			Helper.Command("check_active", "- Prints currently loaded zones.", (ConsoleEvent)obj2);
		}
	}
	[HarmonyPatch]
	public static class SpawnerPatches
	{
		private static float Range(Component spawner, float triggerDistance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			HashSet<Vector2s> local = ForceZones.Local;
			if (local.Count == 0 || !local.Contains(ZoneSystem.GetZone(spawner.transform.position)))
			{
				return triggerDistance;
			}
			return 9999999f;
		}

		private static float SpawnAreaRange(SpawnArea spawner)
		{
			return Range((Component)(object)spawner, spawner.m_triggerDistance);
		}

		private static float CreatureSpawnerRange(CreatureSpawner spawner)
		{
			return Range((Component)(object)spawner, spawner.m_triggerDistance);
		}

		[HarmonyPatch(typeof(SpawnArea), "UpdateSpawn")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> SpawnAreaUpdateSpawn(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(SpawnArea), "m_triggerDistance"), (string)null)
			}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(SpawnerPatches), "SpawnAreaRange", (Type[])null, (Type[])null)).InstructionEnumeration();
		}

		[HarmonyPatch(typeof(CreatureSpawner), "UpdateSpawner")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CreatureSpawnerUpdateSpawner(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(CreatureSpawner), "m_triggerDistance"), (string)null)
			}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
			{
				matcher.SetAndAdvance(OpCodes.Call, (object)AccessTools.Method(typeof(SpawnerPatches), "CreatureSpawnerRange", (Type[])null, (Type[])null));
			}, (Action<string>)null).InstructionEnumeration();
		}
	}
	public static class ForceZones
	{
		public const string RPC_FORCE_ACTIVE = "RenderLimits_ForceActive";

		public const string RPC_FORCE_ACTIVE_REPLY = "RenderLimits_ForceActiveReply";

		private static readonly HashSet<Vector2s> None = new HashSet<Vector2s>();

		public static bool Accepted = true;

		public static HashSet<Vector2s> Local
		{
			get
			{
				if (!Accepted)
				{
					return None;
				}
				return Configuration.ForceActive;
			}
		}

		public static HashSet<Vector2s> Current => For(PeerActive.Context);

		public static HashSet<Vector2s> For(ZNetPeer? peer)
		{
			if (peer != null)
			{
				return PeerActive.Get(peer).Zones;
			}
			return Local;
		}

		public static void Send()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			ZNet instance = ZNet.instance;
			if (!Object.op_Implicit((Object)(object)instance) || instance.IsServer())
			{
				return;
			}
			ZPackage val = new ZPackage();
			val.Write(Configuration.ForceActive.Count);
			foreach (Vector2s item in Configuration.ForceActive)
			{
				val.Write(item);
			}
			ZRpc serverRPC = instance.GetServerRPC();
			if (serverRPC != null)
			{
				serverRPC.Invoke("RenderLimits_ForceActive", new object[1] { val });
			}
		}

		public static void RPC_ForceActive(ZRpc rpc, ZPackage package)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			ZNetPeer peer = ZNet.instance.GetPeer(rpc);
			PeerData peerData = PeerActive.Get(peer);
			HashSet<Vector2s> zones = peerData.Zones;
			HashSet<Vector2s> hashSet = new HashSet<Vector2s>();
			bool flag = Configuration.AllowForceActive;
			if (flag)
			{
				int num = package.ReadInt();
				int num2 = (int)(11000f / ZoneSystem.instance.m_zoneSize);
				flag = num >= 0 && num <= Configuration.MaximumForceActive;
				int num3 = 0;
				while (flag && num3 < num)
				{
					Vector2s val = package.ReadVector2s();
					flag = Math.Abs(val.x) <= num2 && Math.Abs(val.y) <= num2;
					hashSet.Add(val);
					num3++;
				}
			}
			if (!flag)
			{
				hashSet.Clear();
			}
			peerData.Zones = hashSet;
			Release(zones, hashSet, peer.m_uid);
			rpc.Invoke("RenderLimits_ForceActiveReply", new object[1] { flag });
		}

		public static void RPC_ForceActiveReply(ZRpc rpc, bool accepted)
		{
			Accepted = accepted;
		}

		private static void Release(HashSet<Vector2s> previous, HashSet<Vector2s> current, long uid)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			ZDOMan instance = ZDOMan.instance;
			HashSet<SectorIndex> hashSet = new HashSet<SectorIndex>();
			List<ZDO> list = new List<ZDO>();
			foreach (Vector2s previou in previous)
			{
				if (!current.Contains(previou))
				{
					instance.FindObjects(previou, list, hashSet);
				}
			}
			foreach (ZDO item in list)
			{
				if (item.GetOwner() == uid && !instance.IsInPeerActiveArea(item.GetPosition(), uid))
				{
					item.SetOwner(0L);
				}
			}
		}
	}
	public static class LimitManager
	{
		public static SimulationDistance Current = SimulationDistance.OriginalDistance;

		private static bool batching = false;

		private static bool changed = false;

		private static bool maximumChanged = false;

		public static int RequestedActive => Math.Max(0, Configuration.ActiveArea);

		public static void Reload(ConfigFile config)
		{
			batching = true;
			try
			{
				config.Reload();
			}
			finally
			{
				batching = false;
			}
			if (changed)
			{
				changed = false;
				Update();
			}
		}

		public static void UpdateMaximum()
		{
			maximumChanged = true;
			Update();
		}

		public static void Update()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (batching)
			{
				changed = true;
				return;
			}
			int num = Math.Min(Math.Max(1, Configuration.GeneratedArea), Configuration.MaximumGeneratedArea);
			int num2 = Math.Min(Math.Max(1, Configuration.LoadedArea), num);
			int num3 = num - num2;
			Current = new SimulationDistance(num2, num3, Configuration.ClassicShape);
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				Sync(ZNet.instance);
			}
			if (maximumChanged && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer())
			{
				PeerActive.Revalidate(ZNet.instance);
			}
			maximumChanged = false;
		}

		public static void Sync(ZNet net)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (net.IsServer())
			{
				net.ApplySimulationDistance(Current);
			}
			else
			{
				PeerActive.Send(net);
			}
		}

		public static SimulationDistance Limit(SimulationDistance requested)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			int maximumGeneratedArea = Configuration.MaximumGeneratedArea;
			int num = Math.Max(1, Math.Min(((SimulationDistance)(ref requested)).NearSimulationDistance, maximumGeneratedArea));
			int num2 = Math.Max(0, Math.Min(((SimulationDistance)(ref requested)).FarSimulationDistance, maximumGeneratedArea - num));
			return new SimulationDistance(num, num2, ((SimulationDistance)(ref requested)).IsClassic);
		}

		public static SimulationDistance Min(SimulationDistance a, SimulationDistance b)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			return new SimulationDistance(Math.Min(((SimulationDistance)(ref a)).NearSimulationDistance, ((SimulationDistance)(ref b)).NearSimulationDistance), Math.Min(((SimulationDistance)(ref a)).FarSimulationDistance, ((SimulationDistance)(ref b)).FarSimulationDistance), ((SimulationDistance)(ref a)).IsClassic && ((SimulationDistance)(ref b)).IsClassic);
		}

		public static SimulationDistance Max(SimulationDistance a, SimulationDistance b)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			return new SimulationDistance(Math.Max(((SimulationDistance)(ref a)).NearSimulationDistance, ((SimulationDistance)(ref b)).NearSimulationDistance), Math.Max(((SimulationDistance)(ref a)).FarSimulationDistance, ((SimulationDistance)(ref b)).FarSimulationDistance), ((SimulationDistance)(ref a)).IsClassic || ((SimulationDistance)(ref b)).IsClassic);
		}

		public static int MaxActive(SimulationDistance distance)
		{
			int nearSimulationDistance = ((SimulationDistance)(ref distance)).NearSimulationDistance;
			if (nearSimulationDistance <= 1)
			{
				return 0;
			}
			if (((SimulationDistance)(ref distance)).IsClassic)
			{
				return nearSimulationDistance - 1;
			}
			float num = (float)nearSimulationDistance + 0.5f;
			int i;
			for (i = 0; (float)(2 * (i + 1) * (i + 1)) < num * num; i++)
			{
			}
			return i;
		}
	}
	[HarmonyPatch]
	public static class ZNetPatches
	{
		[HarmonyPatch(typeof(GraphicsSettingsManager), "GetSimulationDistance")]
		[HarmonyPrefix]
		private static bool GetSimulationDistance(ref SimulationDistance __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			__result = LimitManager.Current;
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "SimulationDistanceServerHandshake")]
		[HarmonyPrefix]
		private static bool SimulationDistanceServerHandshake(ZNet __instance)
		{
			LimitManager.Sync(__instance);
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "GetSyncedSimulationDistance")]
		[HarmonyPrefix]
		private static bool GetSyncedSimulationDistance(ZNet __instance, ref SimulationDistance __result)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			__result = PeerActive.Context?.m_simulationDistance ?? LimitManager.Min(__instance.m_simulationDistance, LimitManager.Current);
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "RPC_ValidatedSimulationDistance")]
		[HarmonyPrefix]
		private static bool ValidatedSimulationDistance(ZNet __instance, ZPackage pkg)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			__instance.ApplySimulationDistance(SimulationDistance.Deserialize(ref pkg));
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "RPC_RequestValidSimulationDistance")]
		[HarmonyPrefix]
		private static bool RequestValidSimulationDistance(ZNet __instance, ZRpc rpc, ZPackage pkg)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsServer())
			{
				return false;
			}
			ZNetPeer peer = __instance.GetPeer(rpc);
			PeerData peerData = PeerActive.Get(peer);
			SimulationDistance val = SimulationDistance.Deserialize(ref pkg);
			peerData.Requested = val;
			if (pkg.GetPos() < pkg.Size())
			{
				peerData.RequestedActive = Math.Max(0, pkg.ReadInt());
			}
			PeerActive.Apply(peer, LimitManager.Limit(val));
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "Start")]
		[HarmonyPostfix]
		private static void Start(ZNet __instance)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Configuration.SelectWorld();
			ForceZones.Accepted = __instance.IsServer();
			if (__instance.IsDedicated())
			{
				__instance.ApplySimulationDistance(LimitManager.Current);
			}
		}

		[HarmonyPatch(typeof(ZNet), "Disconnect")]
		[HarmonyPostfix]
		private static void Disconnect(ZNetPeer peer)
		{
			PeerActive.Remove(peer);
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		[HarmonyPostfix]
		private static void PeerInfo(ZNet __instance, ZRpc rpc)
		{
			if (__instance.GetPeer(rpc).m_uid != 0L)
			{
				if (__instance.IsServer())
				{
					rpc.Register<ZPackage>("RenderLimits_ForceActive", (Action<ZRpc, ZPackage>)ForceZones.RPC_ForceActive);
					return;
				}
				rpc.Register<bool>("RenderLimits_ForceActiveReply", (Action<ZRpc, bool>)ForceZones.RPC_ForceActiveReply);
				Configuration.SelectWorld();
				PeerActive.Send(__instance);
				ForceZones.Send();
			}
		}
	}
	public class PeerData
	{
		public SimulationDistance? Requested;

		public int RequestedActive = 1;

		public HashSet<Vector2s> Zones = new HashSet<Vector2s>();
	}
	public static class PeerActive
	{
		private const string RPC_REQUEST = "RPC_RequestValidSimulationDistance";

		private const string RPC_VALIDATED = "RPC_ValidatedSimulationDistance";

		private static readonly Dictionary<ZNetPeer, PeerData> Peers = new Dictionary<ZNetPeer, PeerData>();

		public static ZNetPeer? Context;

		public static ZNetPeer? Enter(ZNetPeer? peer)
		{
			ZNetPeer? context = Context;
			Context = peer;
			return context;
		}

		public static PeerData Get(ZNetPeer peer)
		{
			if (!Peers.TryGetValue(peer, out PeerData value))
			{
				value = (Peers[peer] = new PeerData());
			}
			return value;
		}

		public static void Remove(ZNetPeer peer)
		{
			Peers.Remove(peer);
		}

		public static int Active(ZNetPeer? peer)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (peer == null)
			{
				return Math.Min(LimitManager.RequestedActive, LimitManager.MaxActive(ZNet.instance.GetSyncedSimulationDistance()));
			}
			return Math.Min(Get(peer).RequestedActive, LimitManager.MaxActive(peer.m_simulationDistance));
		}

		public static void Send(ZNet net)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ZRpc serverRPC = net.GetServerRPC();
			if (serverRPC != null)
			{
				ZPackage val = new ZPackage();
				((SimulationDistance)(ref LimitManager.Current)).Serialize(ref val);
				val.Write(LimitManager.RequestedActive);
				serverRPC.Invoke("RPC_RequestValidSimulationDistance", new object[1] { val });
			}
		}

		public static void Apply(ZNetPeer peer, SimulationDistance validated)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			peer.m_simulationDistance = validated;
			ZPackage val = new ZPackage();
			((SimulationDistance)(ref validated)).Serialize(ref val);
			peer.m_rpc.Invoke("RPC_ValidatedSimulationDistance", new object[1] { val });
		}

		public static void Revalidate(ZNet net)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			foreach (ZNetPeer peer in net.GetPeers())
			{
				if (!Peers.TryGetValue(peer, out PeerData value))
				{
					continue;
				}
				SimulationDistance? requested = value.Requested;
				if (requested.HasValue)
				{
					SimulationDistance valueOrDefault = requested.GetValueOrDefault();
					SimulationDistance validated = LimitManager.Limit(valueOrDefault);
					if (!((SimulationDistance)(ref validated)).Equals(peer.m_simulationDistance))
					{
						Apply(peer, validated);
					}
				}
			}
		}

		public static SimulationDistance Widest(SimulationDistance own)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				own = LimitManager.Max(own, peer.m_simulationDistance);
			}
			return own;
		}
	}
	[HarmonyPatch(typeof(Heightmap), "GetLodHideDistance")]
	public class TerrainVisibility
	{
		private static bool Prefix(ref float __result)
		{
			int realTerrainVisibility = Configuration.RealTerrainVisibility;
			if (realTerrainVisibility == 0)
			{
				return true;
			}
			__result = realTerrainVisibility;
			return false;
		}
	}
	[HarmonyPatch]
	public static class ZonePatches
	{
		private static float ActiveRange()
		{
			return (float)PeerActive.Active(PeerActive.Context) + 0.5f;
		}

		[HarmonyPatch(typeof(ZoneSystem), "CreateLocalZones")]
		[HarmonyPostfix]
		private static void CreateLocalZones(ZoneSystem __instance, ref bool __result)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (__result)
			{
				return;
			}
			foreach (Vector2s item in ForceZones.Local)
			{
				if (__instance.PokeLocalZone(item))
				{
					__result = true;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "CreateGhostZones")]
		[HarmonyPrefix]
		private static void CreateGhostZones_Prefix(ZoneSystem __instance, out SimulationDistance __state)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			__state = __instance.m_simulationDistance;
			__instance.m_simulationDistance = PeerActive.Widest(__state);
		}

		[HarmonyPatch(typeof(ZoneSystem), "CreateGhostZones")]
		[HarmonyFinalizer]
		private static Exception? CreateGhostZones_Finalizer(ZoneSystem __instance, SimulationDistance __state, Exception? __exception)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			__instance.m_simulationDistance = __state;
			return __exception;
		}

		[HarmonyPatch(typeof(ZNetScene), "PointInsideActiveArea")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> PointInsideActiveArea_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_002b: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)1.5f, (string)null)
			}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(ZonePatches), "ActiveRange", (Type[])null, (Type[])null)).InstructionEnumeration();
		}

		[HarmonyPatch(typeof(ZNetScene), "PointInsideActiveArea")]
		[HarmonyPostfix]
		private static void PointInsideActiveArea_Postfix(Vector3 point, ref bool __result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!__result && ForceZones.Current.Contains(ZoneSystem.GetZone(point)))
			{
				__result = true;
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "CreateObjects")]
		[HarmonyPrefix]
		private static void CreateObjects(List<ZDO> currentNearObjects)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			ZDOMan instance = ZDOMan.instance;
			foreach (Vector2s item in ForceZones.Local)
			{
				if (ZoneSystem.instance.IsZoneLoaded(item))
				{
					instance.FindObjects(item, currentNearObjects, instance.m_visitedSectorIndices);
				}
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "FindSectorObjects")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> FindSectorObjects_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(HashSet<SectorIndex>), "Clear", (Type[])null, (Type[])null), (string)null)
			}).Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldarg_3, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ZonePatches), "AddForceZones", (Type[])null, (Type[])null))
			})
				.InstructionEnumeration();
		}

		private static void AddForceZones(ZDOMan manager, List<ZDO> objects)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			foreach (Vector2s item in ForceZones.Current)
			{
				manager.FindObjects(item, objects, manager.m_visitedSectorIndices);
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "CreateSyncList")]
		[HarmonyPrefix]
		private static void CreateSyncList_Prefix(ZDOPeer peer, out ZNetPeer? __state)
		{
			__state = PeerActive.Enter(peer.m_peer);
		}

		[HarmonyPatch(typeof(ZDOMan), "ReleaseNearbyZDOS")]
		[HarmonyPatch(typeof(ZDOMan), "IsInPeerActiveArea")]
		[HarmonyPrefix]
		private static void ActiveArea_Prefix(long uid, out ZNetPeer? __state)
		{
			__state = PeerActive.Enter(ZNet.instance.GetPeer(uid));
		}

		[HarmonyPatch(typeof(ZDOPeer), "ZDOSectorInvalidated")]
		[HarmonyPrefix]
		private static void ZDOSectorInvalidated(ZDOPeer __instance, out ZNetPeer? __state)
		{
			__state = PeerActive.Enter(__instance.m_peer);
		}

		[HarmonyPatch(typeof(ZDOMan), "CreateSyncList")]
		[HarmonyPatch(typeof(ZDOMan), "ReleaseNearbyZDOS")]
		[HarmonyPatch(typeof(ZDOMan), "IsInPeerActiveArea")]
		[HarmonyPatch(typeof(ZDOPeer), "ZDOSectorInvalidated")]
		[HarmonyFinalizer]
		private static Exception? RestoreContext(ZNetPeer? __state, Exception? __exception)
		{
			PeerActive.Context = __state;
			return __exception;
		}
	}
	[BepInPlugin("render_limits", "Render Limits", "1.16")]
	public class RenderLimits : BaseUnityPlugin
	{
		public const string GUID = "render_limits";

		public const string NAME = "Render Limits";

		public const string VERSION = "1.16";

		public void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Configuration.Init(((BaseUnityPlugin)this).Config);
			new Harmony("render_limits").PatchAll();
			SetupWatcher();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath));
			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))
			{
				LimitManager.Reload(((BaseUnityPlugin)this).Config);
			}
		}
	}
	[HarmonyPatch(typeof(GraphicsSettingsManager), "ApplyQualitySettings")]
	public class ApplyQualitySettings
	{
		private static void Postfix()
		{
			Configuration.InitSettings();
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public class SetCommands
	{
		private static void Postfix()
		{
			new ForceActiveCommand();
		}
	}
}