Decompiled source of DadsQoL v1.4.0

DadsQoL.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DadsQoL.MassFarming;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DadsQoL")]
[assembly: AssemblyDescription("Configurable Valheim quality-of-life features")]
[assembly: AssemblyCompany("Dad_Is_Bored")]
[assembly: AssemblyProduct("DadsQoL")]
[assembly: AssemblyCopyright("Copyright 2026 Dad_Is_Bored")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.4.0.0")]
[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 DadsQoL
{
	[BepInPlugin("com.dadisbored.dadsqol", "DadsQoL", "1.4.0")]
	public sealed class DadsQoLPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.dadisbored.dadsqol";

		public const string PluginName = "DadsQoL";

		public const string PluginVersion = "1.4.0";

		internal static ConfigEntry<bool> ModEnabled;

		internal static ManualLogSource ModLog;

		internal static ConfigEntry<bool> CarryWeightEnabled;

		internal static ConfigEntry<float> CarryWeight;

		internal static ConfigEntry<bool> PickupRadiusEnabled;

		internal static ConfigEntry<float> PickupRadius;

		internal static ConfigEntry<bool> AttractFish;

		internal static ConfigEntry<bool> EquipmentInWaterEnabled;

		internal static ConfigEntry<bool> MassFarmingEnabled;

		internal static ConfigEntry<KeyboardShortcut> MassFarmingKeyboardShortcut;

		internal static ConfigEntry<KeyboardShortcut> MassFarmingControllerShortcut;

		internal static ConfigEntry<float> MassHarvestRadius;

		internal static ConfigEntry<int> PlantGridWidth;

		internal static ConfigEntry<int> PlantGridLength;

		internal static ConfigEntry<bool> IgnorePlantingStamina;

		internal static ConfigEntry<bool> IgnorePlantingDurability;

		internal static ConfigEntry<bool> CenterPlantingGridWidth;

		internal static ConfigEntry<bool> CenterPlantingGridLength;

		internal static ConfigEntry<bool> EternalFuelEnabled;

		internal static ConfigEntry<bool> EternalCampfires;

		internal static ConfigEntry<bool> EternalBonfires;

		internal static ConfigEntry<bool> EternalHearths;

		internal static ConfigEntry<bool> EternalSconces;

		internal static ConfigEntry<bool> EternalStandingIronTorches;

		internal static ConfigEntry<bool> EternalStandingWoodTorches;

		internal static ConfigEntry<bool> EternalStandingGreenTorches;

		internal static ConfigEntry<bool> EternalStandingBlueTorches;

		internal static ConfigEntry<bool> EternalStandingBraziers;

		internal static ConfigEntry<bool> EternalHangingBraziers;

		internal static ConfigEntry<bool> EternalJackOTurnips;

		internal static ConfigEntry<bool> EternalStoneOvens;

		internal static ConfigEntry<bool> EternalHotTubs;

		internal static ConfigEntry<bool> EternalSmelters;

		internal static ConfigEntry<bool> EternalBlastFurnaces;

		internal static ConfigEntry<bool> EternalFrostFoundries;

		internal static ConfigEntry<bool> EternalEitrRefineries;

		internal static ConfigEntry<string> EternalCustomPrefabs;

		internal static ConfigEntry<bool> SharedRecipes;

		internal static ConfigEntry<bool> AutomaticMapSharing;

		private Harmony? _harmony;

		internal static bool MassFarmingActive => FeatureEnabled(MassFarmingEnabled);

		private void Awake()
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Expected O, but got Unknown
			ModLog = ((BaseUnityPlugin)this).Logger;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Enable or disable every DadsQoL feature.");
			CarryWeightEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Carry Weight", "Enabled", true, "Enable the configured base carry weight.");
			CarryWeight = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Carry Weight", "Base Carry Weight", 5000f, "Base carry weight before food, equipment, status-effect, and world modifiers. Vanilla is 300.");
			PickupRadiusEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Pickup Radius", "Enabled", true, "Enable the configured automatic pickup radius.");
			PickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Pickup Radius", "Radius", 6f, "Automatic pickup radius in meters. Vanilla is 2.");
			AttractFish = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Pickup Radius", "Attract Fish", false, "Allow automatic pickup to pull fish toward the player. Turn off to keep fish from following behind you; fish can still be picked up manually.");
			EquipmentInWaterEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Equipment In Water", "Enabled", true, "Allow tools, weapons, shields, bows, and other hand equipment to remain usable while swimming.");
			MassFarmingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Enabled", true, "Enable mass harvesting and grid planting.");
			MassFarmingKeyboardShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("5 - Mass Farming", "Keyboard Shortcut", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "Hold while harvesting or planting to use mass farming.");
			MassFarmingControllerShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("5 - Mass Farming", "Controller Shortcut", new KeyboardShortcut((KeyCode)334, Array.Empty<KeyCode>()), "Hold while harvesting or planting to use mass farming with a controller.");
			MassHarvestRadius = ((BaseUnityPlugin)this).Config.Bind<float>("5 - Mass Farming", "Harvest Radius", 5f, "Radius in meters for harvesting matching pickables and extracting nearby beehives.");
			PlantGridWidth = ((BaseUnityPlugin)this).Config.Bind<int>("5 - Mass Farming", "Plant Grid Width", 5, "Number of plants across the grid.");
			PlantGridLength = ((BaseUnityPlugin)this).Config.Bind<int>("5 - Mass Farming", "Plant Grid Length", 5, "Number of plants along the grid.");
			IgnorePlantingStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Ignore Planting Stamina", false, "Do not consume stamina for the additional plants.");
			IgnorePlantingDurability = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Ignore Planting Durability", false, "Do not consume cultivator durability for the additional plants.");
			CenterPlantingGridWidth = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Center Grid Width", true, "Center the grid across the first plant instead of extending to one side.");
			CenterPlantingGridLength = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Center Grid Length", true, "Center the grid along the first plant instead of extending forward.");
			EternalFuelEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Enabled", true, "Keep selected fuel-burning pieces fully fueled.");
			EternalCampfires = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Campfires", true, "Keep campfires fueled.");
			EternalBonfires = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Bonfires", true, "Keep bonfires fueled.");
			EternalHearths = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Hearths", true, "Keep hearths fueled.");
			EternalSconces = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Sconces", true, "Keep wall sconces fueled.");
			EternalStandingIronTorches = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Standing Iron Torches", true, "Keep standing iron torches fueled.");
			EternalStandingWoodTorches = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Standing Wood Torches", true, "Keep standing wood torches fueled.");
			EternalStandingGreenTorches = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Standing Green Torches", true, "Keep green-burning standing torches fueled.");
			EternalStandingBlueTorches = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Standing Blue Torches", true, "Keep blue-burning standing torches fueled.");
			EternalStandingBraziers = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Standing Braziers", true, "Keep standing braziers fueled.");
			EternalHangingBraziers = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Hanging Braziers", true, "Keep hanging braziers fueled.");
			EternalJackOTurnips = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Jack-o-turnips", true, "Keep jack-o-turnips fueled.");
			EternalStoneOvens = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Stone Ovens", true, "Keep stone ovens fueled.");
			EternalHotTubs = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Hot Tubs", true, "Keep hot tubs fueled.");
			EternalSmelters = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Smelters", false, "Keep smelters fueled.");
			EternalBlastFurnaces = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Blast Furnaces", false, "Keep blast furnaces fueled.");
			EternalFrostFoundries = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Frost Foundries", false, "Keep frost foundries fueled.");
			EternalEitrRefineries = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Eternal Fuel", "Eitr Refineries", false, "Keep eitr refineries fueled.");
			EternalCustomPrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Eternal Fuel", "Custom Prefabs", string.Empty, "Comma-separated exact prefab names whose Fireplace, CookingStation, or Smelter fuel must remain full.");
			SharedRecipes = ((BaseUnityPlugin)this).Config.Bind<bool>("7 - Multiplayer", "Shared Recipes", true, "Share discovered crafting recipes with everyone in the world.");
			AutomaticMapSharing = ((BaseUnityPlugin)this).Config.Bind<bool>("7 - Multiplayer", "Automatic Map Sharing", true, "Automatically share explored map areas with everyone in the world.");
			ModEnabled.SettingChanged += OnPickupSettingChanged;
			PickupRadiusEnabled.SettingChanged += OnPickupSettingChanged;
			PickupRadius.SettingChanged += OnPickupSettingChanged;
			_harmony = new Harmony("com.dadisbored.dadsqol");
			_harmony.PatchAll(typeof(DadsQoLPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsQoL 1.4.0 loaded.");
		}

		private static void OnPickupSettingChanged(object sender, EventArgs eventArgs)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				PlayerAwakePatch.Apply(Player.m_localPlayer);
			}
		}

		private void OnDestroy()
		{
			MultiplayerSharing.Reset();
			MassPlantingState.DestroyGhosts();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			MultiplayerSharing.Update();
		}

		internal static bool FeatureEnabled(ConfigEntry<bool> feature)
		{
			if (ModEnabled.Value)
			{
				return feature.Value;
			}
			return false;
		}

		internal static bool MassFarmingShortcutHeld()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!ShortcutHeld(MassFarmingKeyboardShortcut.Value))
			{
				return ShortcutHeld(MassFarmingControllerShortcut.Value);
			}
			return true;
		}

		private static bool ShortcutHeld(KeyboardShortcut shortcut)
		{
			//IL_0002: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class PlayerAwakePatch
	{
		private sealed class OriginalRange
		{
			internal float Value;
		}

		private static readonly ConditionalWeakTable<Player, OriginalRange> OriginalRanges = new ConditionalWeakTable<Player, OriginalRange>();

		private static void Prefix(Player __instance)
		{
			OriginalRanges.GetValue(__instance, (Player player) => new OriginalRange
			{
				Value = player.m_autoPickupRange
			});
		}

		private static void Postfix(Player __instance)
		{
			Apply(__instance);
		}

		internal static void Apply(Player player)
		{
			OriginalRange value = OriginalRanges.GetValue(player, (Player current) => new OriginalRange
			{
				Value = current.m_autoPickupRange
			});
			player.m_autoPickupRange = (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.PickupRadiusEnabled) ? Math.Max(0f, DadsQoLPlugin.PickupRadius.Value) : value.Value);
		}
	}
	[HarmonyPatch(typeof(Player), "AutoPickup")]
	internal static class AutoPickupCapacityPatch
	{
		private static readonly FieldRef<Player, Collider[]> PickupColliders = AccessTools.FieldRefAccess<Player, Collider[]>("m_colliders");

		private static readonly FieldInfo ItemInstancesField = AccessTools.Field(typeof(ItemDrop), "s_instances");

		private static readonly FieldInfo AutoPickupEnabledField = AccessTools.Field(typeof(Player), "m_enableAutoPickup");

		private static Player? _remoteScanPlayer;

		private static int _remoteScanIndex;

		private static float _lastRemotePass;

		private static float _remoteMoveDelta;

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo overlap = AccessTools.Method(typeof(Physics), "OverlapSphereNonAlloc", new Type[4]
			{
				typeof(Vector3),
				typeof(float),
				typeof(Collider[]),
				typeof(int)
			}, (Type[])null);
			MethodInfo scan = AccessTools.Method(typeof(AutoPickupCapacityPatch), "ScanPickupColliders", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, overlap))
				{
					yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					instruction.opcode = OpCodes.Call;
					instruction.operand = scan;
				}
				yield return instruction;
			}
		}

		private static int ScanPickupColliders(Vector3 position, float radius, Collider[] buffer, int mask, Player player)
		{
			//IL_001e: 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)
			if (buffer == null || buffer.Length == 0)
			{
				buffer = (Collider[])(object)new Collider[100];
				PickupColliders.Invoke(player) = buffer;
			}
			int num = Physics.OverlapSphereNonAlloc(position, radius, buffer, mask);
			while (num == buffer.Length && buffer.Length < 65536)
			{
				buffer = (Collider[])(object)new Collider[buffer.Length * 2];
				PickupColliders.Invoke(player) = buffer;
				num = Physics.OverlapSphereNonAlloc(position, radius, buffer, mask);
			}
			if (!DadsQoLPlugin.AttractFish.Value)
			{
				int num2 = 0;
				for (int i = 0; i < num; i++)
				{
					Collider val = buffer[i];
					if (!((Object)(object)val == (Object)null) && !IsFish(val))
					{
						buffer[num2++] = val;
					}
				}
				for (int j = num2; j < num; j++)
				{
					buffer[j] = null;
				}
				num = num2;
			}
			return num;
		}

		private static bool IsFish(Collider collider)
		{
			if ((Object)(object)((Component)collider).GetComponentInParent<Fish>() != (Object)null)
			{
				return true;
			}
			ItemDrop componentInParent = ((Component)collider).GetComponentInParent<ItemDrop>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return IsFish(componentInParent);
			}
			return false;
		}

		private static bool IsFish(ItemDrop item)
		{
			if ((Object)(object)((Component)item).GetComponent<Fish>() != (Object)null)
			{
				return true;
			}
			ItemData itemData = item.m_itemData;
			if (itemData != null && (Object)(object)itemData.m_dropPrefab != (Object)null)
			{
				return (Object)(object)itemData.m_dropPrefab.GetComponent<Fish>() != (Object)null;
			}
			return false;
		}

		private static bool Prefix(Player __instance, ref float __0, out float __state)
		{
			__state = (((Object)(object)__instance != (Object)null) ? __instance.m_autoPickupRange : 0f);
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			PlayerAwakePatch.Apply(__instance);
			__state = __instance.m_autoPickupRange;
			if (!DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.PickupRadiusEnabled))
			{
				return true;
			}
			Inventory inventory = ((Humanoid)__instance).GetInventory();
			if (inventory == null)
			{
				return true;
			}
			if (!inventory.HaveEmptySlot())
			{
				bool flag = false;
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (allItem?.m_shared != null && allItem.m_stack < allItem.m_shared.m_maxStackSize)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					return false;
				}
			}
			if (__instance.m_autoPickupRange > 32f)
			{
				ScanDistantItems(__instance, inventory);
				__instance.m_autoPickupRange = 12f;
			}
			return true;
		}

		private static void ScanDistantItems(Player player, Inventory inventory)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			if (!(bool)AutoPickupEnabledField.GetValue(null) || ((Character)player).IsTeleporting() || !(ItemInstancesField.GetValue(null) is List<ItemDrop> { Count: not 0 } list))
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if ((Object)(object)_remoteScanPlayer != (Object)(object)player || unscaledTime < _lastRemotePass)
			{
				_remoteScanPlayer = player;
				_remoteScanIndex = 0;
				_lastRemotePass = unscaledTime;
				_remoteMoveDelta = Time.fixedDeltaTime;
			}
			if (_remoteScanIndex >= list.Count)
			{
				_remoteScanIndex = 0;
				_remoteMoveDelta = Mathf.Min(unscaledTime - _lastRemotePass, 0.6f);
				_lastRemotePass = unscaledTime;
			}
			Vector3 val = ((Component)player).transform.position + Vector3.up;
			float num = player.m_autoPickupRange * player.m_autoPickupRange;
			float num2 = -1f;
			float num3 = 0f;
			for (int i = 0; i < 64; i++)
			{
				if (_remoteScanIndex >= list.Count)
				{
					break;
				}
				ItemDrop val2 = list[_remoteScanIndex++];
				if ((Object)(object)val2 == (Object)null || val2.m_itemData == null || !val2.m_autoPickup || (!DadsQoLPlugin.AttractFish.Value && IsFish(val2)))
				{
					continue;
				}
				Vector3 position = ((Component)val2).transform.position;
				Vector3 val3 = val - position;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				if (sqrMagnitude <= 144f || sqrMagnitude > num || val2.IsPiece() || ((Humanoid)player).HaveUniqueKey(val2.m_itemData.m_shared.m_name))
				{
					continue;
				}
				ZNetView component = ((Component)val2).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid())
				{
					continue;
				}
				if (!val2.CanPickup(true))
				{
					val2.RequestOwn();
				}
				else
				{
					if (val2.InTar())
					{
						continue;
					}
					val2.Load();
					if (!inventory.CanAddItem(val2.m_itemData, -1))
					{
						continue;
					}
					if (num2 < 0f)
					{
						num2 = inventory.GetTotalWeight();
						num3 = player.GetMaxCarryWeight();
					}
					if (!(num2 + val2.m_itemData.GetWeight(-1) > num3))
					{
						float num4 = Mathf.Sqrt(sqrMagnitude);
						float num5 = Mathf.Min(15f * _remoteMoveDelta, num4 - 11f);
						if (num5 > 0f)
						{
							((Component)val2).transform.position = position + val3 * (num5 / num4);
						}
					}
				}
			}
		}

		private static void Postfix(Player __instance, float __state)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				__instance.m_autoPickupRange = __state;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "GetMaxCarryWeight")]
	internal static class CarryWeightPatch
	{
		private static void Prefix(Player __instance, out float __state)
		{
			__state = __instance.m_maxCarryWeight;
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.CarryWeightEnabled))
			{
				__instance.m_maxCarryWeight = Math.Max(0f, DadsQoLPlugin.CarryWeight.Value);
			}
		}

		private static void Postfix(Player __instance, float __state)
		{
			__instance.m_maxCarryWeight = __state;
		}
	}
	[HarmonyPatch]
	internal static class EquipmentInWaterPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(Humanoid), "UpdateEquipment", new Type[1] { typeof(float) }, (Type[])null);
			yield return AccessTools.Method(typeof(Humanoid), "EquipItem", new Type[2]
			{
				typeof(ItemData),
				typeof(bool)
			}, (Type[])null);
		}

		private static void Prefix(Humanoid __instance, ref float ___m_swimTimer, out float __state)
		{
			__state = ___m_swimTimer;
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.EquipmentInWaterEnabled) && ((Character)__instance).IsPlayer() && ___m_swimTimer < 0.5f)
			{
				___m_swimTimer = 0.5f;
			}
		}

		private static void Postfix(ref float ___m_swimTimer, float __state)
		{
			___m_swimTimer = __state;
		}
	}
	internal static class EternalFuel
	{
		private sealed class CachedName
		{
			internal string Value = string.Empty;
		}

		private static readonly ConditionalWeakTable<Component, CachedName> PrefabNames = new ConditionalWeakTable<Component, CachedName>();

		private static string _customPrefabSource = string.Empty;

		private static HashSet<string> _customPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Func<bool>> BuiltInPrefabs = new Dictionary<string, Func<bool>>(StringComparer.OrdinalIgnoreCase)
		{
			["fire_pit"] = () => DadsQoLPlugin.EternalCampfires.Value,
			["bonfire"] = () => DadsQoLPlugin.EternalBonfires.Value,
			["hearth"] = () => DadsQoLPlugin.EternalHearths.Value,
			["piece_walltorch"] = () => DadsQoLPlugin.EternalSconces.Value,
			["piece_groundtorch"] = () => DadsQoLPlugin.EternalStandingIronTorches.Value,
			["piece_groundtorch_wood"] = () => DadsQoLPlugin.EternalStandingWoodTorches.Value,
			["piece_groundtorch_green"] = () => DadsQoLPlugin.EternalStandingGreenTorches.Value,
			["piece_groundtorch_blue"] = () => DadsQoLPlugin.EternalStandingBlueTorches.Value,
			["piece_brazierfloor01"] = () => DadsQoLPlugin.EternalStandingBraziers.Value,
			["piece_brazierceiling01"] = () => DadsQoLPlugin.EternalHangingBraziers.Value,
			["piece_jackoturnip"] = () => DadsQoLPlugin.EternalJackOTurnips.Value,
			["piece_oven"] = () => DadsQoLPlugin.EternalStoneOvens.Value,
			["piece_bathtub"] = () => DadsQoLPlugin.EternalHotTubs.Value,
			["smelter"] = () => DadsQoLPlugin.EternalSmelters.Value,
			["blastfurnace"] = () => DadsQoLPlugin.EternalBlastFurnaces.Value,
			["piece_FrostFoundry"] = () => DadsQoLPlugin.EternalFrostFoundries.Value,
			["eitrrefinery"] = () => DadsQoLPlugin.EternalEitrRefineries.Value
		};

		internal static bool EnabledFor(Component component)
		{
			if ((Object)(object)component == (Object)null || !DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.EternalFuelEnabled))
			{
				return false;
			}
			string value = PrefabNames.GetValue(component, delegate(Component current)
			{
				string name = ((Object)current.gameObject).name;
				return new CachedName
				{
					Value = (name.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase) ? name.Substring(0, name.Length - "(Clone)".Length) : name)
				};
			}).Value;
			if (BuiltInPrefabs.TryGetValue(value, out Func<bool> value2))
			{
				return value2();
			}
			return CustomPrefabs().Contains(value);
		}

		internal static void Fill(ZNetView view, float maximumFuel)
		{
			if (!((Object)(object)view == (Object)null) && view.IsValid() && view.IsOwner() && view.GetZDO() != null)
			{
				ZDO zDO = view.GetZDO();
				if (zDO.GetFloat(ZDOVars.s_fuel, 0f) != maximumFuel)
				{
					zDO.Set(ZDOVars.s_fuel, maximumFuel);
				}
			}
		}

		private static HashSet<string> CustomPrefabs()
		{
			string text = DadsQoLPlugin.EternalCustomPrefabs.Value ?? string.Empty;
			if (string.Equals(text, _customPrefabSource, StringComparison.Ordinal))
			{
				return _customPrefabs;
			}
			_customPrefabSource = text;
			_customPrefabs = new HashSet<string>(from value in text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select value.Trim() into value
				where value.Length > 0
				select value, StringComparer.OrdinalIgnoreCase);
			return _customPrefabs;
		}
	}
	[HarmonyPatch(typeof(Fireplace), "UpdateFireplace")]
	internal static class EternalFireplacePatch
	{
		private static void Prefix(Fireplace __instance, ZNetView ___m_nview, out bool __state)
		{
			__state = __instance.m_infiniteFuel;
			if (EternalFuel.EnabledFor((Component)(object)__instance))
			{
				__instance.m_infiniteFuel = true;
				EternalFuel.Fill(___m_nview, __instance.m_maxFuel);
			}
		}

		private static void Postfix(Fireplace __instance, bool __state)
		{
			__instance.m_infiniteFuel = __state;
		}
	}
	[HarmonyPatch(typeof(CookingStation), "UpdateCooking")]
	internal static class EternalCookingStationUpdatePatch
	{
		private static void Prefix(CookingStation __instance, ZNetView ___m_nview)
		{
			if (EternalFuel.EnabledFor((Component)(object)__instance))
			{
				EternalFuel.Fill(___m_nview, __instance.m_maxFuel);
			}
		}
	}
	[HarmonyPatch(typeof(CookingStation), "SetFuel")]
	internal static class EternalCookingStationSetFuelPatch
	{
		private static void Prefix(CookingStation __instance, ZNetView ___m_nview, ref float fuel)
		{
			if (EternalFuel.EnabledFor((Component)(object)__instance) && (Object)(object)___m_nview != (Object)null && ___m_nview.IsValid() && ___m_nview.IsOwner())
			{
				fuel = __instance.m_maxFuel;
			}
		}
	}
	[HarmonyPatch(typeof(Smelter), "UpdateSmelter")]
	internal static class EternalSmelterUpdatePatch
	{
		private static void Prefix(Smelter __instance, ZNetView ___m_nview)
		{
			if (EternalFuel.EnabledFor((Component)(object)__instance))
			{
				EternalFuel.Fill(___m_nview, __instance.m_maxFuel);
			}
		}
	}
	[HarmonyPatch(typeof(Smelter), "SetFuel")]
	internal static class EternalSmelterSetFuelPatch
	{
		private static void Prefix(Smelter __instance, ZNetView ___m_nview, ref float fuel)
		{
			if (EternalFuel.EnabledFor((Component)(object)__instance) && (Object)(object)___m_nview != (Object)null && ___m_nview.IsValid() && ___m_nview.IsOwner())
			{
				fuel = __instance.m_maxFuel;
			}
		}
	}
	internal static class MultiplayerSharing
	{
		private const string HelloRpc = "DadsQoL_SharingHello";

		private const string RecipeRpc = "DadsQoL_SharingRecipe";

		private const string MapRpc = "DadsQoL_SharingMap";

		private const string StateRpc = "DadsQoL_SharingState";

		private const int MaximumMapBytes = 2097152;

		private static readonly FieldInfo KnownRecipesField = AccessTools.Field(typeof(Player), "m_knownRecipes");

		private static readonly FieldInfo BuildPiecesField = AccessTools.Field(typeof(ObjectDB), "m_buildPieces");

		private static readonly FieldInfo ExploredField = AccessTools.Field(typeof(Minimap), "m_explored");

		private static readonly FieldInfo ExploredOthersField = AccessTools.Field(typeof(Minimap), "m_exploredOthers");

		private static readonly FieldInfo FogTextureField = AccessTools.Field(typeof(Minimap), "m_fogTexture");

		private static readonly MethodInfo AddKnownRecipeMethod = AccessTools.Method(typeof(Player), "AddKnownRecipe", (Type[])null, (Type[])null);

		private static readonly MethodInfo AddKnownPieceMethod = AccessTools.Method(typeof(Player), "AddKnownPiece", (Type[])null, (Type[])null);

		private static readonly HashSet<string> ServerRecipes = new HashSet<string>(StringComparer.Ordinal);

		private static byte[] _serverMap = Array.Empty<byte>();

		private static ZRoutedRpc? _router;

		private static long _worldId;

		private static bool _helloSent;

		private static bool _mapDirty;

		private static bool _applyingRecipes;

		private static float _nextMapSend;

		private static string? _savePath;

		internal static Player? LoadedPlayer;

		internal static Minimap? LoadedMap;

		internal static void Reset()
		{
			_router = null;
			_worldId = 0L;
			_helloSent = false;
			_mapDirty = false;
			_savePath = null;
			ServerRecipes.Clear();
			_serverMap = Array.Empty<byte>();
			LoadedPlayer = null;
			LoadedMap = null;
		}

		internal static void Update()
		{
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Expected O, but got Unknown
			ZNet instance = ZNet.instance;
			ZRoutedRpc instance2 = ZRoutedRpc.instance;
			if ((Object)(object)instance == (Object)null || instance2 == null || instance.GetWorld() == null)
			{
				return;
			}
			long worldUID = instance.GetWorldUID();
			if (_router != instance2 || _worldId != worldUID)
			{
				_router = instance2;
				_worldId = worldUID;
				_helloSent = false;
				_mapDirty = false;
				ServerRecipes.Clear();
				_serverMap = Array.Empty<byte>();
				_savePath = null;
				instance2.Register<ZPackage>("DadsQoL_SharingHello", (Action<long, ZPackage>)OnHello);
				instance2.Register<ZPackage>("DadsQoL_SharingRecipe", (Action<long, ZPackage>)OnRecipe);
				instance2.Register<ZPackage>("DadsQoL_SharingMap", (Action<long, ZPackage>)OnMap);
				instance2.Register<ZPackage>("DadsQoL_SharingState", (Action<long, ZPackage>)OnState);
				if (instance.IsServer() && worldUID != 0L)
				{
					LoadServerState(worldUID);
				}
			}
			Player localPlayer = Player.m_localPlayer;
			Minimap instance3 = Minimap.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance3 == (Object)null || (Object)(object)LoadedPlayer != (Object)(object)localPlayer || (Object)(object)LoadedMap != (Object)(object)instance3 || worldUID == 0L)
			{
				return;
			}
			if (!_helloSent)
			{
				if (!instance.IsServer() && instance.GetServerPeer() == null)
				{
					return;
				}
				_helloSent = true;
				if (instance.IsServer())
				{
					bool num = MergeLocal(localPlayer, instance3);
					ApplyState(localPlayer, instance3);
					if (num)
					{
						BroadcastState(0L);
					}
				}
				else
				{
					instance2.InvokeRoutedRPC(instance.GetServerPeer().m_uid, "DadsQoL_SharingHello", new object[1] { MakeHello(localPlayer, instance3) });
				}
				_nextMapSend = Time.unscaledTime + 10f;
			}
			if (!DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing) || (!_mapDirty && !(Time.unscaledTime >= _nextMapSend + 110f)) || !(Time.unscaledTime >= _nextMapSend))
			{
				return;
			}
			_mapDirty = false;
			_nextMapSend = Time.unscaledTime + 10f;
			byte[] mapBits = GetMapBits(instance3);
			if (instance.IsServer())
			{
				if (MergeMap(mapBits))
				{
					BroadcastState(0L);
				}
				return;
			}
			ZPackage val = new ZPackage();
			val.Write(Compress(mapBits));
			ZNetPeer serverPeer = instance.GetServerPeer();
			if (serverPeer != null)
			{
				instance2.InvokeRoutedRPC(serverPeer.m_uid, "DadsQoL_SharingMap", new object[1] { val });
			}
		}

		internal static void RecipeDiscovered(Player player, Recipe recipe)
		{
			string name = recipe?.m_item?.m_itemData?.m_shared?.m_name ?? string.Empty;
			KnownDiscovered(player, name);
		}

		internal static void PieceDiscovered(Player player, Piece piece)
		{
			KnownDiscovered(player, piece?.m_name ?? string.Empty);
		}

		private static void KnownDiscovered(Player player, string name)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			if (_applyingRecipes || !_helloSent || (Object)(object)player != (Object)(object)Player.m_localPlayer || !DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes) || string.IsNullOrEmpty(name))
			{
				return;
			}
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || _router == null)
			{
				return;
			}
			if (instance.IsServer())
			{
				if (ServerRecipes.Add(name))
				{
					SaveServerState();
					BroadcastState(0L);
				}
				return;
			}
			ZPackage val = new ZPackage();
			val.Write(name);
			ZNetPeer serverPeer = instance.GetServerPeer();
			if (serverPeer != null)
			{
				_router.InvokeRoutedRPC(serverPeer.m_uid, "DadsQoL_SharingRecipe", new object[1] { val });
			}
		}

		internal static void MapExplored(Minimap map)
		{
			if ((Object)(object)map == (Object)(object)Minimap.instance)
			{
				_mapDirty = true;
			}
		}

		private static ZPackage MakeHello(Player player, Minimap map)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			bool flag = DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes);
			bool flag2 = DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing);
			val.Write(flag);
			val.Write(flag2);
			HashSet<string> hashSet = (flag ? GetKnownRecipes(player) : new HashSet<string>());
			val.Write(hashSet.Count);
			foreach (string item in hashSet)
			{
				val.Write(item);
			}
			val.Write(flag2 ? Compress(GetMapBits(map)) : Array.Empty<byte>());
			return val;
		}

		private static void OnHello(long sender, ZPackage package)
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || !instance.IsServer() || instance.GetPeer(sender) == null)
			{
				return;
			}
			bool flag = package.ReadBool();
			bool flag2 = package.ReadBool();
			int num = package.ReadInt();
			if (num < 0 || num > 10000)
			{
				return;
			}
			bool flag3 = false;
			for (int i = 0; i < num; i++)
			{
				string text = package.ReadString();
				if (flag && DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes))
				{
					int length = text.Length;
					if (length > 0 && length < 256)
					{
						flag3 |= ServerRecipes.Add(text);
					}
				}
			}
			byte[] bytes = package.ReadByteArray();
			if (flag2 && DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing))
			{
				flag3 |= MergeMap(Decompress(bytes));
			}
			if (flag3)
			{
				SaveServerState();
			}
			SendState(sender);
			if (flag3)
			{
				BroadcastState(sender);
			}
		}

		private static void OnRecipe(long sender, ZPackage package)
		{
			ZNet instance = ZNet.instance;
			if (!((Object)(object)instance == (Object)null) && instance.IsServer() && instance.GetPeer(sender) != null && DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes))
			{
				string text = package.ReadString();
				int length = text.Length;
				if (length > 0 && length < 256 && ServerRecipes.Add(text))
				{
					SaveServerState();
					BroadcastState(0L);
				}
			}
		}

		private static void OnMap(long sender, ZPackage package)
		{
			ZNet instance = ZNet.instance;
			if (!((Object)(object)instance == (Object)null) && instance.IsServer() && instance.GetPeer(sender) != null && DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing) && MergeMap(Decompress(package.ReadByteArray())))
			{
				SaveServerState();
				BroadcastState(0L);
			}
		}

		private static void OnState(long sender, ZPackage package)
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || instance.IsServer() || instance.GetServerPeer() == null || sender != instance.GetServerPeer().m_uid)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			Minimap instance2 = Minimap.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance2 == (Object)null || (Object)(object)LoadedPlayer != (Object)(object)localPlayer || (Object)(object)LoadedMap != (Object)(object)instance2)
			{
				return;
			}
			int num = package.ReadInt();
			if (num >= 0 && num <= 10000)
			{
				HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
				for (int i = 0; i < num; i++)
				{
					hashSet.Add(package.ReadString());
				}
				byte[] bits = Decompress(package.ReadByteArray());
				if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes))
				{
					ApplyRecipes(localPlayer, hashSet);
				}
				if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing))
				{
					ApplyMap(instance2, bits);
				}
			}
		}

		private static bool MergeLocal(Player player, Minimap map)
		{
			bool flag = false;
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes))
			{
				foreach (string knownRecipe in GetKnownRecipes(player))
				{
					flag |= ServerRecipes.Add(knownRecipe);
				}
			}
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing))
			{
				flag |= MergeMap(GetMapBits(map));
			}
			if (flag)
			{
				SaveServerState();
			}
			return flag;
		}

		private static void ApplyState(Player player, Minimap map)
		{
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes))
			{
				ApplyRecipes(player, ServerRecipes);
			}
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing))
			{
				ApplyMap(map, _serverMap);
			}
		}

		private static void ApplyRecipes(Player player, IEnumerable<string> names)
		{
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			_applyingRecipes = true;
			try
			{
				foreach (string name in names)
				{
					if (player.IsRecipeKnown(name))
					{
						continue;
					}
					foreach (Recipe recipe in instance.m_recipes)
					{
						if (recipe?.m_item?.m_itemData?.m_shared?.m_name != name)
						{
							continue;
						}
						AddKnownRecipeMethod.Invoke(player, new object[1] { recipe });
						goto IL_0125;
					}
					foreach (Piece item in (List<Piece>)BuildPiecesField.GetValue(instance))
					{
						if (!(item?.m_name != name))
						{
							AddKnownPieceMethod.Invoke(player, new object[1] { item });
							break;
						}
					}
					IL_0125:;
				}
			}
			finally
			{
				_applyingRecipes = false;
			}
		}

		private static HashSet<string> GetKnownRecipes(Player player)
		{
			return (HashSet<string>)KnownRecipesField.GetValue(player);
		}

		private static byte[] GetMapBits(Minimap map)
		{
			BitArray obj = (BitArray)ExploredField.GetValue(map);
			BitArray bitArray = (BitArray)ExploredOthersField.GetValue(map);
			byte[] array = new byte[(obj.Length + 7) / 8];
			obj.CopyTo(array, 0);
			byte[] array2 = new byte[array.Length];
			bitArray.CopyTo(array2, 0);
			for (int i = 0; i < array.Length; i++)
			{
				array[i] |= array2[i];
			}
			return array;
		}

		private static bool MergeMap(byte[] incoming)
		{
			if (incoming.Length == 0 || incoming.Length > 2097152 || (_serverMap.Length != 0 && _serverMap.Length != incoming.Length))
			{
				return false;
			}
			if (_serverMap.Length == 0)
			{
				_serverMap = new byte[incoming.Length];
			}
			bool result = false;
			for (int i = 0; i < incoming.Length; i++)
			{
				byte b = (byte)(_serverMap[i] | incoming[i]);
				if (b != _serverMap[i])
				{
					_serverMap[i] = b;
					result = true;
				}
			}
			return result;
		}

		private static void ApplyMap(Minimap map, byte[] bits)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			BitArray bitArray = (BitArray)ExploredField.GetValue(map);
			BitArray bitArray2 = (BitArray)ExploredOthersField.GetValue(map);
			if (bits.Length != (bitArray.Length + 7) / 8)
			{
				return;
			}
			Texture2D val = (Texture2D)FogTextureField.GetValue(map);
			Color[] array = null;
			bool flag = false;
			for (int i = 0; i < bitArray.Length; i++)
			{
				if ((bits[i >> 3] & (1 << (i & 7))) != 0 && !bitArray[i] && !bitArray2[i])
				{
					if (array == null)
					{
						array = val.GetPixels();
					}
					bitArray2[i] = true;
					array[i].g = 0f;
					flag = true;
				}
			}
			if (flag)
			{
				val.SetPixels(array);
				val.Apply();
			}
		}

		private static void SendState(long peerId)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			if (_router == null)
			{
				return;
			}
			ZPackage val = new ZPackage();
			bool flag = DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.SharedRecipes);
			val.Write(flag ? ServerRecipes.Count : 0);
			if (flag)
			{
				foreach (string serverRecipe in ServerRecipes)
				{
					val.Write(serverRecipe);
				}
			}
			val.Write(DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.AutomaticMapSharing) ? Compress(_serverMap) : Array.Empty<byte>());
			_router.InvokeRoutedRPC(peerId, "DadsQoL_SharingState", new object[1] { val });
		}

		private static void BroadcastState(long except = 0L)
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || !instance.IsServer())
			{
				return;
			}
			foreach (ZNetPeer peer in instance.GetPeers())
			{
				if (peer.IsReady() && peer.m_uid != except)
				{
					SendState(peer.m_uid);
				}
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)Minimap.instance != (Object)null)
			{
				ApplyState(Player.m_localPlayer, Minimap.instance);
			}
		}

		private static byte[] Compress(byte[] bytes)
		{
			if (bytes.Length == 0)
			{
				return bytes;
			}
			using MemoryStream memoryStream = new MemoryStream();
			using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
			{
				gZipStream.Write(bytes, 0, bytes.Length);
			}
			return memoryStream.ToArray();
		}

		private static byte[] Decompress(byte[] bytes)
		{
			if (bytes.Length == 0)
			{
				return bytes;
			}
			using MemoryStream stream = new MemoryStream(bytes);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[8192];
			int num;
			while ((num = gZipStream.Read(array, 0, array.Length)) > 0)
			{
				if (memoryStream.Length + num > 2097152)
				{
					return Array.Empty<byte>();
				}
				memoryStream.Write(array, 0, num);
			}
			return memoryStream.ToArray();
		}

		private static void LoadServerState(long worldId)
		{
			_savePath = Path.Combine(Paths.ConfigPath, "DadsQoL", "multiplayer-" + worldId + ".dat");
			if (!File.Exists(_savePath))
			{
				return;
			}
			try
			{
				ReadState(File.ReadAllBytes(_savePath));
			}
			catch (Exception ex)
			{
				DadsQoLPlugin.ModLog.LogWarning((object)("Could not read multiplayer state: " + ex.Message));
			}
		}

		private static void SaveServerState()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if (_savePath == null)
			{
				return;
			}
			try
			{
				if (File.Exists(_savePath) && !ReadState(File.ReadAllBytes(_savePath)))
				{
					return;
				}
				ZPackage val = new ZPackage();
				val.Write(1);
				val.Write(ServerRecipes.Count);
				foreach (string serverRecipe in ServerRecipes)
				{
					val.Write(serverRecipe);
				}
				val.Write(_serverMap);
				Directory.CreateDirectory(Path.GetDirectoryName(_savePath));
				File.WriteAllBytes(_savePath, val.GetArray());
			}
			catch (Exception ex)
			{
				DadsQoLPlugin.ModLog.LogWarning((object)("Could not save multiplayer state: " + ex.Message));
			}
		}

		private static bool ReadState(byte[] bytes)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ZPackage val = new ZPackage(bytes);
			if (val.ReadInt() != 1)
			{
				return false;
			}
			int num = val.ReadInt();
			if (num < 0 || num > 10000)
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				ServerRecipes.Add(val.ReadString());
			}
			byte[] array = val.ReadByteArray();
			if (array.Length != 0 && _serverMap.Length != 0 && array.Length != _serverMap.Length)
			{
				return false;
			}
			MergeMap(array);
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "AddKnownRecipe")]
	internal static class SharedRecipePatch
	{
		private static void Postfix(Player __instance, Recipe recipe)
		{
			MultiplayerSharing.RecipeDiscovered(__instance, recipe);
		}
	}
	[HarmonyPatch(typeof(Player), "AddKnownPiece")]
	internal static class SharedPiecePatch
	{
		private static void Postfix(Player __instance, Piece piece)
		{
			MultiplayerSharing.PieceDiscovered(__instance, piece);
		}
	}
	[HarmonyPatch(typeof(Player), "Load", new Type[] { typeof(ZPackage) })]
	internal static class SharedRecipeLoadPatch
	{
		private static void Postfix(Player __instance)
		{
			MultiplayerSharing.LoadedPlayer = __instance;
		}
	}
	[HarmonyPatch(typeof(Minimap), "LoadMapData")]
	internal static class SharedMapLoadPatch
	{
		private static void Postfix(Minimap __instance)
		{
			MultiplayerSharing.LoadedMap = __instance;
		}
	}
	[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
	{
		typeof(int),
		typeof(int)
	})]
	internal static class SharedMapExplorePatch
	{
		private static void Postfix(Minimap __instance, bool __result)
		{
			if (__result)
			{
				MultiplayerSharing.MapExplored(__instance);
			}
		}
	}
}
namespace DadsQoL.MassFarming
{
	[HarmonyPatch(typeof(Player), "Interact")]
	internal static class MassHarvest
	{
		private static readonly FieldInfo InteractMaskField = AccessTools.Field(typeof(Player), "m_interactMask");

		private static readonly MethodInfo ExtractMethod = AccessTools.Method(typeof(Beehive), "Extract", Type.EmptyTypes, (Type[])null);

		private static bool _processingMassInteraction;

		private static Collider[] _colliders = (Collider[])(object)new Collider[64];

		private static void Prefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			if (!DadsQoLPlugin.MassFarmingActive || _processingMassInteraction || hold || ((Character)__instance).InAttack() || ((Character)__instance).InDodge() || !DadsQoLPlugin.MassFarmingShortcutHeld())
			{
				return;
			}
			Interactable componentInParent = go.GetComponentInParent<Interactable>();
			float num = Mathf.Max(0f, DadsQoLPlugin.MassHarvestRadius.Value);
			int num2 = (int)InteractMaskField.GetValue(__instance);
			int num3;
			while (true)
			{
				num3 = Physics.OverlapSphereNonAlloc(go.transform.position, num, _colliders, num2);
				if (num3 < _colliders.Length)
				{
					break;
				}
				Array.Resize(ref _colliders, _colliders.Length * 2);
			}
			_processingMassInteraction = true;
			try
			{
				Pickable val = (Pickable)(object)((componentInParent is Pickable) ? componentInParent : null);
				if (val != null)
				{
					string text = (((Object)(object)val.m_itemPrefab != (Object)null) ? ((Object)val.m_itemPrefab).name : string.Empty);
					for (int i = 0; i < num3; i++)
					{
						Collider val2 = _colliders[i];
						Pickable val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject.GetComponentInParent<Pickable>() : null);
						if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val && (Object)(object)val3.m_itemPrefab != (Object)null && ((Object)val3.m_itemPrefab).name == text)
						{
							val3.Interact((Humanoid)(object)__instance, false, alt);
						}
					}
					return;
				}
				Beehive val4 = (Beehive)(object)((componentInParent is Beehive) ? componentInParent : null);
				if (val4 == null)
				{
					return;
				}
				for (int j = 0; j < num3; j++)
				{
					Collider val5 = _colliders[j];
					Beehive val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).gameObject.GetComponentInParent<Beehive>() : null);
					if ((Object)(object)val6 != (Object)null && (Object)(object)val6 != (Object)(object)val4 && PrivateArea.CheckAccess(((Component)val6).transform.position, 0f, true, false))
					{
						ExtractMethod.Invoke(val6, null);
					}
				}
			}
			finally
			{
				Array.Clear(_colliders, 0, num3);
				_processingMassInteraction = false;
			}
		}
	}
	internal static class MassPlantingState
	{
		private static readonly FieldInfo NoPlacementCostField = AccessTools.Field(typeof(Player), "m_noPlacementCost");

		private static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

		private static readonly FieldInfo BuildPiecesField = AccessTools.Field(typeof(Player), "m_buildPieces");

		private static readonly MethodInfo GetRightItemMethod = AccessTools.Method(typeof(Humanoid), "GetRightItem", (Type[])null, (Type[])null);

		internal static Vector3 PlacedPosition;

		internal static Quaternion PlacedRotation;

		internal static Piece PlacedPiece = null;

		internal static bool PlaceSuccessful;

		internal static int? SavedRotation;

		internal static GameObject[] PlacementGhosts = (GameObject[])(object)new GameObject[1];

		internal static Piece[] PlacementGhostPieces = (Piece[])(object)new Piece[1];

		private static readonly List<Material> GhostMaterials = new List<Material>();

		internal static Piece FakeResourcePiece = null;

		internal static readonly int PlantSpaceMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid" });

		internal static bool Active
		{
			get
			{
				if (DadsQoLPlugin.MassFarmingActive)
				{
					return DadsQoLPlugin.MassFarmingShortcutHeld();
				}
				return false;
			}
		}

		internal static bool NoPlacementCost(Player player)
		{
			return (bool)NoPlacementCostField.GetValue(player);
		}

		internal static GameObject? PlacementGhost(Player player)
		{
			object? value = PlacementGhostField.GetValue(player);
			return (GameObject?)((value is GameObject) ? value : null);
		}

		internal static PieceTable? BuildPieces(Player player)
		{
			object? value = BuildPiecesField.GetValue(player);
			return (PieceTable?)((value is PieceTable) ? value : null);
		}

		internal static ItemData? RightItem(Player player)
		{
			object? obj = GetRightItemMethod.Invoke(player, Array.Empty<object>());
			return (ItemData?)((obj is ItemData) ? obj : null);
		}

		internal static IEnumerable<Vector3> BuildGridPositions(Vector3 origin, Plant plant, Quaternion rotation)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			int width = Math.Max(1, DadsQoLPlugin.PlantGridWidth.Value);
			int length = Math.Max(1, DadsQoLPlugin.PlantGridLength.Value);
			float num = plant.m_growRadius * 2f;
			Vector3 across = rotation * Vector3.left * num;
			Vector3 forward = rotation * Vector3.forward * num;
			Vector3 gridOrigin = origin;
			if (DadsQoLPlugin.CenterPlantingGridLength.Value)
			{
				gridOrigin -= forward * (float)(length / 2);
			}
			if (DadsQoLPlugin.CenterPlantingGridWidth.Value)
			{
				gridOrigin -= across * (float)(width / 2);
			}
			for (int x = 0; x < length; x++)
			{
				Vector3 position = gridOrigin;
				for (int z = 0; z < width; z++)
				{
					position.y = ZoneSystem.instance.GetGroundHeight(position);
					yield return position;
					position += across;
				}
				gridOrigin += forward;
			}
		}

		internal static bool HasGrowSpace(Vector3 position, GameObject prefab)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Plant component = prefab.GetComponent<Plant>();
			if (!((Object)(object)component == (Object)null))
			{
				return !Physics.CheckSphere(position, component.m_growRadius, PlantSpaceMask);
			}
			return true;
		}

		internal static bool EnsureGhostsBuilt(Player player)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			int num = Math.Max(1, DadsQoLPlugin.PlantGridWidth.Value) * Math.Max(1, DadsQoLPlugin.PlantGridLength.Value);
			if (PlacementGhosts.Length != num || (Object)(object)PlacementGhosts[0] == (Object)null)
			{
				DestroyGhosts();
				PlacementGhosts = (GameObject[])(object)new GameObject[num];
				PlacementGhostPieces = (Piece[])(object)new Piece[num];
				PieceTable val = BuildPieces(player);
				GameObject val2 = (((Object)(object)val != (Object)null) ? val.GetSelectedPrefab() : null);
				if ((Object)(object)val2 == (Object)null || val2.GetComponent<Piece>().m_repairPiece)
				{
					return false;
				}
				for (int i = 0; i < PlacementGhosts.Length; i++)
				{
					PlacementGhosts[i] = CreateGhost(val2);
					PlacementGhostPieces[i] = PlacementGhosts[i].GetComponent<Piece>();
				}
			}
			if ((Object)(object)FakeResourcePiece == (Object)null)
			{
				FakeResourcePiece = PlacementGhostPieces[0];
				FakeResourcePiece.m_dlc = string.Empty;
				FakeResourcePiece.m_resources = (Requirement[])(object)new Requirement[1]
				{
					new Requirement()
				};
			}
			return true;
		}

		internal static void DestroyGhosts()
		{
			GameObject[] placementGhosts = PlacementGhosts;
			foreach (GameObject val in placementGhosts)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			foreach (Material ghostMaterial in GhostMaterials)
			{
				if ((Object)(object)ghostMaterial != (Object)null)
				{
					Object.Destroy((Object)(object)ghostMaterial);
				}
			}
			GhostMaterials.Clear();
			FakeResourcePiece = null;
			PlacementGhostPieces = (Piece[])(object)new Piece[1];
		}

		internal static void SetGhostsActive(bool active)
		{
			GameObject[] placementGhosts = PlacementGhosts;
			foreach (GameObject val in placementGhosts)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(active);
				}
			}
		}

		private static GameObject CreateGhost(GameObject prefab)
		{
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			ZNetView.m_forceDisableInit = true;
			GameObject val;
			try
			{
				val = Object.Instantiate<GameObject>(prefab);
			}
			finally
			{
				ZNetView.m_forceDisableInit = false;
			}
			((Object)val).name = ((Object)prefab).name;
			Joint[] componentsInChildren = val.GetComponentsInChildren<Joint>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			Rigidbody[] componentsInChildren2 = val.GetComponentsInChildren<Rigidbody>();
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren2[i]);
			}
			int layer = LayerMask.NameToLayer("ghost");
			Transform[] componentsInChildren3 = val.GetComponentsInChildren<Transform>();
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				((Component)componentsInChildren3[i]).gameObject.layer = layer;
			}
			TerrainModifier[] componentsInChildren4 = val.GetComponentsInChildren<TerrainModifier>();
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren4[i]);
			}
			GuidePoint[] componentsInChildren5 = val.GetComponentsInChildren<GuidePoint>();
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren5[i]);
			}
			Light[] componentsInChildren6 = val.GetComponentsInChildren<Light>();
			for (int i = 0; i < componentsInChildren6.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren6[i]);
			}
			Transform val2 = val.transform.Find("_GhostOnly");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(true);
			}
			MeshRenderer[] componentsInChildren7 = val.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val3 in componentsInChildren7)
			{
				if (!((Object)(object)((Renderer)val3).sharedMaterial == (Object)null))
				{
					Material[] sharedMaterials = ((Renderer)val3).sharedMaterials;
					for (int j = 0; j < sharedMaterials.Length; j++)
					{
						Material val4 = new Material(sharedMaterials[j]);
						val4.SetFloat("_RippleDistance", 0f);
						val4.SetFloat("_ValueNoise", 0f);
						sharedMaterials[j] = val4;
						GhostMaterials.Add(val4);
					}
					((Renderer)val3).sharedMaterials = sharedMaterials;
					((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
				}
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(Player), "TryPlacePiece")]
	internal static class TryPlacePiecePatch
	{
		private static void Prefix(int ___m_placeRotation)
		{
			if (MassPlantingState.Active && !MassPlantingState.SavedRotation.HasValue)
			{
				MassPlantingState.SavedRotation = ___m_placeRotation;
			}
		}

		private static void Postfix(Player __instance, bool __result, Piece piece, ref int ___m_placeRotation)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			MassPlantingState.PlaceSuccessful = __result;
			GameObject val = MassPlantingState.PlacementGhost(__instance);
			if (__result && (Object)(object)val != (Object)null)
			{
				MassPlantingState.PlacedPosition = val.transform.position;
				MassPlantingState.PlacedRotation = val.transform.rotation;
				MassPlantingState.PlacedPiece = piece;
			}
			if (MassPlantingState.Active && MassPlantingState.SavedRotation.HasValue)
			{
				___m_placeRotation = MassPlantingState.SavedRotation.Value;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdatePlacement")]
	internal static class UpdatePlacementPatch
	{
		private static void Prefix(ref int ___m_placeRotation)
		{
			MassPlantingState.PlaceSuccessful = false;
			if (MassPlantingState.Active && MassPlantingState.SavedRotation.HasValue)
			{
				___m_placeRotation = MassPlantingState.SavedRotation.Value;
			}
		}

		private static void Postfix(Player __instance, int ___m_placeRotation)
		{
			//IL_0031: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			if (MassPlantingState.Active)
			{
				MassPlantingState.SavedRotation = ___m_placeRotation;
			}
			if (!MassPlantingState.PlaceSuccessful || !MassPlantingState.Active)
			{
				return;
			}
			Plant component = ((Component)MassPlantingState.PlacedPiece).gameObject.GetComponent<Plant>();
			Heightmap val = Heightmap.FindHeightmap(MassPlantingState.PlacedPosition);
			if ((Object)(object)component == (Object)null || (Object)(object)val == (Object)null)
			{
				return;
			}
			PieceTable val2 = MassPlantingState.BuildPieces(__instance);
			foreach (Vector3 item in MassPlantingState.BuildGridPositions(MassPlantingState.PlacedPosition, component, MassPlantingState.PlacedRotation))
			{
				if (MassPlantingState.PlacedPosition == item || (MassPlantingState.PlacedPiece.m_cultivatedGroundOnly && !val.IsCultivated(item)) || !MassPlantingState.HasGrowSpace(item, ((Component)MassPlantingState.PlacedPiece).gameObject))
				{
					continue;
				}
				ItemData val3 = MassPlantingState.RightItem(__instance);
				if (val3 == null)
				{
					break;
				}
				if (!DadsQoLPlugin.IgnorePlantingStamina.Value && !((Character)__instance).HaveStamina(val3.m_shared.m_attack.m_attackStamina))
				{
					Hud.instance.StaminaBarUppgradeFlash();
					break;
				}
				if (!MassPlantingState.NoPlacementCost(__instance) && !__instance.HaveRequirements(MassPlantingState.PlacedPiece, (RequirementMode)0))
				{
					break;
				}
				GameObject val4 = Object.Instantiate<GameObject>(((Component)MassPlantingState.PlacedPiece).gameObject, item, MassPlantingState.PlacedRotation);
				Piece component2 = val4.GetComponent<Piece>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.SetCreator(__instance.GetPlayerID(), ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID);
				}
				MassPlantingState.PlacedPiece.m_placeEffect.Create(item, MassPlantingState.PlacedRotation, val4.transform, 1f, -1, default(ZDOID));
				Game.instance.IncrementPlayerStat((PlayerStatType)2, 1f, false);
				__instance.ConsumeResources(MassPlantingState.PlacedPiece.m_resources, 0, -1, 1);
				if (!DadsQoLPlugin.IgnorePlantingStamina.Value)
				{
					((Character)__instance).UseStamina(val3.m_shared.m_attack.m_attackStamina);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					((Character)__instance).RaiseSkill(val2.m_skill, 1f);
				}
				if (!DadsQoLPlugin.IgnorePlantingDurability.Value && val3.m_shared.m_useDurability)
				{
					val3.m_durability -= val3.m_shared.m_useDurabilityDrain;
					if (val3.m_durability <= 0f)
					{
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
	internal static class SetupPlacementGhostPatch
	{
		private static void Prefix(int ___m_placeRotation)
		{
			if (MassPlantingState.Active && !MassPlantingState.SavedRotation.HasValue)
			{
				MassPlantingState.SavedRotation = ___m_placeRotation;
			}
		}

		private static void Postfix(ref int ___m_placeRotation)
		{
			if (MassPlantingState.Active && MassPlantingState.SavedRotation.HasValue)
			{
				___m_placeRotation = MassPlantingState.SavedRotation.Value;
			}
			MassPlantingState.DestroyGhosts();
		}
	}
	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	internal static class UpdatePlacementGhostPatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MassPlantingState.PlacementGhost(__instance);
			if (!DadsQoLPlugin.MassFarmingActive || !DadsQoLPlugin.MassFarmingShortcutHeld() || (Object)(object)val == (Object)null || !val.activeSelf)
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			Plant component = val.GetComponent<Plant>();
			if ((Object)(object)component == (Object)null || !MassPlantingState.EnsureGhostsBuilt(__instance))
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			Piece component2 = val.GetComponent<Piece>();
			Requirement val2 = ((IEnumerable<Requirement>)component2.m_resources).FirstOrDefault((Func<Requirement, bool>)((Requirement resource) => (Object)(object)resource.m_resItem != (Object)null && resource.m_amount > 0));
			if (val2 == null)
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			MassPlantingState.FakeResourcePiece.m_resources[0].m_resItem = val2.m_resItem;
			MassPlantingState.FakeResourcePiece.m_resources[0].m_amount = 0;
			ItemData val3 = MassPlantingState.RightItem(__instance);
			Heightmap val4 = Heightmap.FindHeightmap(val.transform.position);
			if (val3 == null || (Object)(object)val4 == (Object)null)
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			float num = __instance.GetStamina();
			bool flag = MassPlantingState.NoPlacementCost(__instance);
			Vector3 position = val.transform.position;
			Quaternion rotation = val.transform.rotation;
			int num2 = 0;
			foreach (Vector3 item in MassPlantingState.BuildGridPositions(position, component, rotation))
			{
				GameObject val5 = MassPlantingState.PlacementGhosts[num2];
				Piece val6 = MassPlantingState.PlacementGhostPieces[num2++];
				if (position == item)
				{
					if (val5.activeSelf)
					{
						val5.SetActive(false);
					}
					continue;
				}
				Requirement obj = MassPlantingState.FakeResourcePiece.m_resources[0];
				obj.m_amount += val2.m_amount;
				val5.transform.position = item;
				val5.transform.rotation = rotation;
				if (!val5.activeSelf)
				{
					val5.SetActive(true);
				}
				bool invalidPlacementHeightlight = (component2.m_cultivatedGroundOnly && !val4.IsCultivated(item)) || !MassPlantingState.HasGrowSpace(item, val) || (!DadsQoLPlugin.IgnorePlantingStamina.Value && num < val3.m_shared.m_attack.m_attackStamina) || (!flag && !__instance.HaveRequirements(MassPlantingState.FakeResourcePiece, (RequirementMode)0));
				num -= val3.m_shared.m_attack.m_attackStamina;
				val6.SetInvalidPlacementHeightlight(invalidPlacementHeightlight);
			}
		}
	}
}