Decompiled source of NaNNaVH v0.12.0

NaNNaVH/NaNNaVH.dll

Decompiled 5 months ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using System.Timers;
using BepInEx;
using HarmonyLib;
using NaNNaVH.slib;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("NaNNaVH")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NaNNaVH")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("61d604dd-aa6b-408a-94bb-3ed50aa0844f")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public static class ZNetExtensions
{
	public enum ZNetInstanceType
	{
		Local,
		Client,
		Server
	}

	public static bool IsLocalInstance(this ZNet znet)
	{
		return znet.IsServer() && !znet.IsDedicated();
	}

	public static bool IsClientInstance(this ZNet znet)
	{
		return !znet.IsServer() && !znet.IsDedicated();
	}

	public static bool IsServerInstance(this ZNet znet)
	{
		return znet.IsServer() && znet.IsDedicated();
	}

	public static ZNetInstanceType GetInstanceType(this ZNet znet)
	{
		if (znet.IsLocalInstance())
		{
			return ZNetInstanceType.Local;
		}
		if (znet.IsClientInstance())
		{
			return ZNetInstanceType.Client;
		}
		return ZNetInstanceType.Server;
	}
}
namespace NaNNaVH
{
	[BepInPlugin("nb.wackjob.NaNNaVH", "NaNNaVH", "0.12.0")]
	public class NaNNaVH : BaseUnityPlugin
	{
		public static Timer mapSyncSaveTimer = new Timer(TimeSpan.FromMinutes(5.0).TotalMilliseconds);

		public static readonly string nVHDataDirectoryPath;

		public static Harmony harmony;

		private void Awake()
		{
			harmony.PatchAll();
			if (!Directory.Exists(nVHDataDirectoryPath))
			{
				Directory.CreateDirectory(nVHDataDirectoryPath);
			}
			if (ZNet.m_isServer)
			{
				mapSyncSaveTimer.AutoReset = true;
				mapSyncSaveTimer.Elapsed += delegate
				{
					MapSync.SaveMapDataToDisk();
				};
			}
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		static NaNNaVH()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			string bepInExRootPath = Paths.BepInExRootPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			nVHDataDirectoryPath = bepInExRootPath + directorySeparatorChar + "nvh-data";
			harmony = new Harmony("nb.wackjob.NaNNaVH");
		}
	}
}
namespace NaNNaVH.slib
{
	public class MapSync
	{
		public class MapRange
		{
			public int StartingX;

			public int EndingX;

			public int Y;
		}

		public static bool[] ServerMapData;

		public static bool ShouldSyncOnSpawn = true;

		public static void RPC_nVHMapSync(long sender, ZPackage mapPkg)
		{
			if (ZNet.m_isServer)
			{
				if (sender == ZRoutedRpc.instance.GetServerPeerID() || mapPkg == null)
				{
					return;
				}
				int num = mapPkg.ReadInt();
				if (num > 0)
				{
					for (int i = 0; i < num; i++)
					{
						MapRange mapRange = mapPkg.ReadnVHMapRange();
						for (int j = mapRange.StartingX; j < mapRange.EndingX; j++)
						{
							ServerMapData[mapRange.Y * Minimap.instance.m_textureSize + j] = true;
						}
					}
					ZLog.Log((object)$"Received {num} map ranges from peer #{sender}.");
					nVHAck.SendAck(sender);
				}
				if (!mapPkg.ReadBool())
				{
					return;
				}
				List<MapRange> list = ExplorationDataToMapRanges(ServerMapData);
				List<ZPackage> list2 = ChunkMapData(list);
				foreach (ZPackage item in list2)
				{
					RpcData rpcData = new RpcData();
					rpcData.Name = "nVHMapSync";
					rpcData.Payload = new object[1] { item };
					rpcData.Target = ZRoutedRpc.Everybody;
					RpcQueue.Enqueue(rpcData);
				}
				ZLog.Log((object)$"-------------------------- Packages: {list2.Count}");
				ZLog.Log((object)$"Sent map updates to all clients ({list.Count} map ranges, {list2.Count} chunks)");
			}
			else
			{
				if (sender != ZRoutedRpc.instance.GetServerPeerID())
				{
					return;
				}
				if (mapPkg == null)
				{
					ZLog.LogWarning((object)"Warning: Got empty map sync package from server.");
					return;
				}
				int num2 = mapPkg.ReadInt();
				if (num2 > 0)
				{
					for (int k = 0; k < num2; k++)
					{
						MapRange mapRange2 = mapPkg.ReadnVHMapRange();
						for (int l = mapRange2.StartingX; l < mapRange2.EndingX; l++)
						{
							Minimap.instance.Explore(l, mapRange2.Y);
						}
					}
					Minimap.instance.m_fogTexture.Apply();
					ZLog.Log((object)$"I got {num2} map ranges from the server!");
					nVHAck.SendAck(sender);
				}
				else
				{
					ZLog.Log((object)"Server has no explored areas to sync, continuing.");
				}
			}
		}

		public static void SendMapToServer()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			ZLog.Log((object)"-------------------- SENDING NVHMAPSYNC DATA");
			List<MapRange> list = ExplorationDataToMapRanges(Minimap.instance.m_explored);
			if (list.Count == 0)
			{
				ZPackage val = new ZPackage();
				val.Write(0);
				val.Write(true);
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "nVHMapSync", new object[1] { val });
				return;
			}
			List<ZPackage> list2 = ChunkMapData(list);
			foreach (ZPackage item in list2)
			{
				RpcData rpcData = new RpcData();
				rpcData.Name = "nVHMapSync";
				rpcData.Payload = new object[1] { item };
				rpcData.Target = ZRoutedRpc.instance.GetServerPeerID();
				RpcQueue.Enqueue(rpcData);
			}
			ZLog.Log((object)$"Sent my map data to the server ({list.Count} map ranges, {list2.Count} chunks)");
		}

		public static void LoadMapDataFromDisk()
		{
			if (ServerMapData == null)
			{
				return;
			}
			string nVHDataDirectoryPath = NaNNaVH.nVHDataDirectoryPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			if (!File.Exists(nVHDataDirectoryPath + directorySeparatorChar + ZNet.instance.GetWorldName() + "_mapSync.dat"))
			{
				return;
			}
			try
			{
				string nVHDataDirectoryPath2 = NaNNaVH.nVHDataDirectoryPath;
				directorySeparatorChar = Path.DirectorySeparatorChar;
				string text = File.ReadAllText(nVHDataDirectoryPath2 + directorySeparatorChar + ZNet.instance.GetWorldName() + "_mapSync.dat");
				string[] array = text.Split(new char[1] { ',' });
				string[] array2 = array;
				foreach (string s in array2)
				{
					if (int.TryParse(s, out var result))
					{
						ServerMapData[result] = true;
					}
				}
				ZLog.Log((object)$"Loaded {array.Length} map points from disk.");
			}
			catch (Exception ex)
			{
				ZLog.LogError((object)"Failed to load synchronized map data.");
				ZLog.LogError((object)ex);
			}
		}

		public static void SaveMapDataToDisk()
		{
			if (ServerMapData == null)
			{
				return;
			}
			List<int> list = new List<int>();
			for (int i = 0; i < Minimap.instance.m_textureSize; i++)
			{
				for (int j = 0; j < Minimap.instance.m_textureSize; j++)
				{
					if (ServerMapData[i * Minimap.instance.m_textureSize + j])
					{
						list.Add(i * Minimap.instance.m_textureSize + j);
					}
				}
			}
			if (list.Count > 0)
			{
				string nVHDataDirectoryPath = NaNNaVH.nVHDataDirectoryPath;
				char directorySeparatorChar = Path.DirectorySeparatorChar;
				File.Delete(nVHDataDirectoryPath + directorySeparatorChar + ZNet.instance.GetWorldName() + "_mapSync.dat");
				string nVHDataDirectoryPath2 = NaNNaVH.nVHDataDirectoryPath;
				directorySeparatorChar = Path.DirectorySeparatorChar;
				File.WriteAllText(nVHDataDirectoryPath2 + directorySeparatorChar + ZNet.instance.GetWorldName() + "_mapSync.dat", string.Join(",", list));
				ZLog.Log((object)$"Saved {list.Count} map points to disk.");
			}
		}

		private static List<MapRange> ExplorationDataToMapRanges(bool[] explorationData)
		{
			List<MapRange> list = new List<MapRange>();
			for (int i = 0; i < Minimap.instance.m_textureSize; i++)
			{
				int num = -1;
				int num2 = -1;
				for (int j = 0; j < Minimap.instance.m_textureSize; j++)
				{
					if (explorationData[i * Minimap.instance.m_textureSize + j] && num == -1 && num2 == -1)
					{
						num = j;
					}
					else if (!explorationData[i * Minimap.instance.m_textureSize + j] && num > -1 && num2 == -1)
					{
						num2 = j - 1;
					}
					else if (num > -1 && num2 > -1)
					{
						list.Add(new MapRange
						{
							StartingX = num,
							EndingX = num2,
							Y = i
						});
						num = -1;
						num2 = -1;
					}
				}
				if (num > -1 && num2 == -1)
				{
					list.Add(new MapRange
					{
						StartingX = num,
						EndingX = Minimap.instance.m_textureSize,
						Y = i
					});
				}
			}
			return list;
		}

		private static List<ZPackage> ChunkMapData(List<MapRange> mapData, int chunkSize = 10000)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			if (mapData == null || mapData.Count == 0)
			{
				return null;
			}
			List<List<MapRange>> list = mapData.ChunkBy(chunkSize);
			List<ZPackage> list2 = new List<ZPackage>();
			foreach (List<MapRange> item in list)
			{
				ZPackage val = new ZPackage();
				val.Write(item.Count);
				foreach (MapRange item2 in item)
				{
					val.WritenVHMapRange(item2);
				}
				if (item == list.Last())
				{
					val.Write(true);
				}
				else
				{
					val.Write(false);
				}
				list2.Add(val);
			}
			return list2;
		}
	}
	public static class ListExtensions
	{
		public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize)
		{
			return (from x in source.Select((T x, int i) => new
				{
					Index = i,
					Value = x
				})
				group x by x.Index / chunkSize into x
				select x.Select(v => v.Value).ToList()).ToList();
		}
	}
	public class nVHAck
	{
		public static void RPC_nVHAck(long sender)
		{
			RpcQueue.GotAck();
		}

		public static void SendAck(long target)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(target, "nVHAck", Array.Empty<object>());
		}
	}
	public class RpcData
	{
		public string Name;

		public long Target = ZRoutedRpc.Everybody;

		public object[] Payload;
	}
	public static class RpcQueue
	{
		private static Queue<RpcData> _rpcQueue = new Queue<RpcData>();

		private static bool _ack = true;

		public static void Enqueue(RpcData rpc)
		{
			_rpcQueue.Enqueue(rpc);
		}

		public static bool SendNextRpc()
		{
			if (_rpcQueue.Count == 0 || !_ack)
			{
				return false;
			}
			RpcData rpcData = _rpcQueue.Dequeue();
			if (Utility.IsNullOrWhiteSpace(rpcData.Name) || rpcData.Payload == null)
			{
				return false;
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(rpcData.Target, rpcData.Name, rpcData.Payload);
			_ack = false;
			return true;
		}

		public static void GotAck()
		{
			_ack = true;
		}
	}
	internal static class sFunc
	{
		public static float applyModifierValue(float targetValue, float value)
		{
			if (value <= -100f)
			{
				value = -100f;
			}
			float num = targetValue;
			if (value >= 0f)
			{
				return targetValue + targetValue / 100f * value;
			}
			return targetValue - targetValue / 100f * (value * -1f);
		}

		public static IEnumerable<CodeInstruction> StripForcedCase(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Callvirt)
				{
					MethodBase methodBase = list[i].operand as MethodBase;
					if (methodBase != null && (methodBase.Name == "ToLowerInvariant" || methodBase.Name == "ToUpper"))
					{
						list.RemoveRange(i - 1, 3);
						i -= 2;
					}
				}
			}
			return list;
		}

		public static int Clamp(int value, int min, int max)
		{
			return Math.Min(max, Math.Max(min, value));
		}

		public static float Clamp(float value, float min, float max)
		{
			return Math.Min(max, Math.Max(min, value));
		}
	}
	internal static class versionCheck
	{
		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class PatchZNetOnNewConnection
		{
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (__instance.IsServer())
				{
					ZLog.Log((object)("========== Server Client connected by the name of: " + peer.m_playerName));
				}
			}
		}

		public static void ReceiveClientVersion(long sender, string clientVersion)
		{
			string modVersion = GetModVersion();
			ZNetPeer val = FindPeerBySenderID(sender);
			if (val != null && clientVersion != modVersion)
			{
				ZLog.Log((object)("========== Version mismatch. Kicking peer: " + ((object)val).ToString()));
				ZNet.instance.InternalKick(val);
			}
		}

		public static ZNetPeer FindPeerBySenderID(long senderID)
		{
			foreach (ZNetPeer peer in ZNet.instance.m_peers)
			{
				if (peer.m_uid == senderID)
				{
					return peer;
				}
			}
			return null;
		}

		public static string GetModVersion()
		{
			BepInPlugin customAttribute = ((MemberInfo)typeof(NaNNaVH)).GetCustomAttribute<BepInPlugin>();
			return (customAttribute != null) ? customAttribute.Version.ToString() : "Unknown";
		}
	}
	public static class ZDODataBuffer
	{
		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private class StartBufferingOnNewConnection
		{
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (!__instance.IsServer())
				{
					peer.m_rpc.Register<ZPackage>("ZDOData", (Action<ZRpc, ZPackage>)delegate(ZRpc _, ZPackage package)
					{
						packageBuffer.Add(package);
					});
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		private class ClearPackageBufferOnShutdown
		{
			private static void Postfix()
			{
				packageBuffer.Clear();
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "AddPeer")]
		private class EvaluateBufferedPackages
		{
			private static void Postfix(ZDOMan __instance, ZNetPeer netPeer)
			{
				foreach (ZPackage item in packageBuffer)
				{
					__instance.RPC_ZDOData(netPeer.m_rpc, item);
				}
				packageBuffer.Clear();
			}
		}

		private static readonly List<ZPackage> packageBuffer = new List<ZPackage>();
	}
	public static class ZPackageExtensions
	{
		public static MapSync.MapRange ReadnVHMapRange(this ZPackage pkg)
		{
			return new MapSync.MapRange
			{
				StartingX = pkg.m_reader.ReadInt32(),
				EndingX = pkg.m_reader.ReadInt32(),
				Y = pkg.m_reader.ReadInt32()
			};
		}

		public static void WritenVHMapRange(this ZPackage pkg, MapSync.MapRange mapRange)
		{
			pkg.m_writer.Write(mapRange.StartingX);
			pkg.m_writer.Write(mapRange.EndingX);
			pkg.m_writer.Write(mapRange.Y);
		}
	}
}
namespace NaNNaVH.mods
{
	[HarmonyPatch]
	internal static class AreaRepair
	{
		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		public static class Player_UpdatePlacement_Transpiler
		{
			private static readonly MethodInfo method_Player_Repair = AccessTools.Method(typeof(Player), "Repair", (Type[])null, (Type[])null);

			private static readonly FieldRef<Player, Piece> field_Player_m_hoveringPiece = AccessTools.FieldRefAccess<Player, Piece>("m_hoveringPiece");

			private static readonly MethodInfo method_RepairNearby = AccessTools.Method(typeof(Player_UpdatePlacement_Transpiler), "RepairNearby", (Type[])null, (Type[])null);

			[HarmonyTranspiler]
			public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				for (int i = 0; i < list.Count; i++)
				{
					if (CodeInstructionExtensions.Calls(list[i], method_Player_Repair))
					{
						list[i].operand = method_RepairNearby;
					}
				}
				return list.AsEnumerable();
			}

			public static void RepairNearby(Player instance, ItemData toolItem, Piece _1)
			{
				//IL_0024: 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)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				Piece hoveringPiece = instance.GetHoveringPiece();
				Vector3 val = (((Object)(object)hoveringPiece != (Object)null) ? ((Component)hoveringPiece).transform.position : ((Component)instance).transform.position);
				List<Piece> list = new List<Piece>();
				Piece.GetAllPiecesInRadius(val, m_repair_radius, list);
				m_repair_count = 0;
				Piece val2 = field_Player_m_hoveringPiece.Invoke(instance);
				MethodInfo methodInfo = AccessTools.Method(typeof(Player), "Repair", (Type[])null, (Type[])null);
				foreach (Piece item in list)
				{
					if (!((Character)instance).HaveStamina(toolItem.m_shared.m_attack.m_attackStamina) || (toolItem.m_shared.m_useDurability && toolItem.m_durability <= 0f))
					{
						break;
					}
					field_Player_m_hoveringPiece.Invoke(instance) = item;
					methodInfo.Invoke(instance, new object[2] { toolItem, _1 });
					field_Player_m_hoveringPiece.Invoke(instance) = val2;
				}
				if (m_repair_count > 0)
				{
					((Character)instance).Message((MessageType)1, $"{m_repair_count} pieces repaired", 0, (Sprite)null);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Repair")]
		public static class Player_Repair_Transpiler
		{
			private static readonly MethodInfo method_Character_Message = AccessTools.Method(typeof(Character), "Message", (Type[])null, (Type[])null);

			private static readonly MethodInfo method_MessageNoop = AccessTools.Method(typeof(Player_Repair_Transpiler), "MessageNoop", (Type[])null, (Type[])null);

			[HarmonyTranspiler]
			public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				bool flag = true;
				for (int i = 0; i < list.Count; i++)
				{
					if (CodeInstructionExtensions.Calls(list[i], method_Character_Message))
					{
						list[i].operand = method_MessageNoop;
						list.Insert(i++, new CodeInstruction(flag ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0, (object)null));
						flag = false;
					}
				}
				return list.AsEnumerable();
			}

			public static void MessageNoop(Character _0, MessageType _1, string _2, int _3, Sprite _4, int repaired)
			{
				m_repair_count += repaired;
			}
		}

		private static int m_repair_count;

		private static readonly float m_repair_radius = 10f;
	}
	internal class AutoFuel
	{
		[HarmonyPatch(typeof(Container), "Awake")]
		private static class ContainerAwakePatch
		{
			private static void Postfix(Container __instance, ZNetView ___m_nview)
			{
				AddContainer(__instance, ___m_nview);
			}
		}

		[HarmonyPatch(typeof(Container), "OnDestroyed")]
		private static class ContainerOnDestroyedPatch
		{
			private static void Prefix(Container __instance)
			{
				ContainerList.Remove(__instance);
			}
		}

		[HarmonyPatch(typeof(Smelter), "Awake")]
		public class BlastFurnacePatch
		{
			private static void Prefix(ref Smelter __instance)
			{
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Expected O, but got Unknown
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Expected O, but got Unknown
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: 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_014b: Expected O, but got Unknown
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: Unknown result type (might be due to invalid IL or missing references)
				//IL_0167: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Expected O, but got Unknown
				//IL_0183: 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)
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Expected O, but got Unknown
				if (__instance.m_name != "$piece_blastfurnace")
				{
					return;
				}
				ObjectDB instance = ObjectDB.instance;
				List<ItemDrop> allItems = instance.GetAllItems((ItemType)1, "");
				foreach (ItemDrop item in allItems)
				{
					if (metals.Keys.Contains(item.m_itemData.m_shared.m_name))
					{
						metals[item.m_itemData.m_shared.m_name] = item;
					}
				}
				List<ItemConversion> list = new List<ItemConversion>
				{
					new ItemConversion
					{
						m_from = metals["$item_copperore"],
						m_to = metals["$item_copper"]
					},
					new ItemConversion
					{
						m_from = metals["$item_tinore"],
						m_to = metals["$item_tin"]
					},
					new ItemConversion
					{
						m_from = metals["$item_ironscrap"],
						m_to = metals["$item_iron"]
					},
					new ItemConversion
					{
						m_from = metals["$item_silverore"],
						m_to = metals["$item_silver"]
					},
					new ItemConversion
					{
						m_from = metals["$item_copperscrap"],
						m_to = metals["$item_copper"]
					}
				};
				foreach (ItemConversion item2 in list)
				{
					__instance.m_conversion.Add(item2);
				}
			}
		}

		[HarmonyPatch(typeof(Smelter), "UpdateSmelter")]
		private static class Smelter_FixedUpdate_Patch
		{
			private static void Postfix(Smelter __instance, ZNetView ___m_nview)
			{
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsOwner())
				{
					if ((double)(Time.time - lastFuel) < 0.1)
					{
						fuelCount++;
						RefuelSmelter(__instance, ___m_nview, fuelCount * 33);
					}
					else
					{
						fuelCount = 0;
						lastFuel = Time.time;
						RefuelSmelter(__instance, ___m_nview, 0);
					}
				}
			}
		}

		public static float lastFuel;

		public static int fuelCount;

		internal static string fuelDisallowTypes = "RoundLog,FineWood";

		internal static string oreDisallowTypes = "RoundLog,FineWood";

		internal static bool distributedFilling = true;

		internal static readonly List<Container> ContainerList = new List<Container>();

		private static Dictionary<string, ItemDrop> metals = new Dictionary<string, ItemDrop>
		{
			{ "$item_copperore", null },
			{ "$item_copper", null },
			{ "$item_ironscrap", null },
			{ "$item_iron", null },
			{ "$item_tinore", null },
			{ "$item_tin", null },
			{ "$item_silverore", null },
			{ "$item_silver", null },
			{ "$item_copperscrap", null }
		};

		private void OnDestroy()
		{
		}

		public static string GetPrefabName(string name)
		{
			char[] anyOf = new char[2] { '(', ' ' };
			int num = name.IndexOfAny(anyOf);
			return (num >= 0) ? name.Substring(0, num) : name;
		}

		public static void AddContainer(Container container, ZNetView nview)
		{
			try
			{
				if (container.GetInventory() != null && ((nview != null) ? nview.GetZDO() : null) != null && (((Object)container).name.StartsWith("piece_", StringComparison.Ordinal) || ((Object)container).name.StartsWith("Container", StringComparison.Ordinal) || nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) != 0))
				{
					ContainerList.Add(container);
				}
			}
			catch
			{
			}
		}

		public static List<Container> GetNearbyContainers(Vector3 center, float range)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = new List<Container>();
			foreach (Container item in ContainerList.Where((Container container) => (Object)(object)container != (Object)null && (Object)(object)((Component)container).GetComponentInParent<Piece>() != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)((container != null) ? ((Component)container).transform : null) != (Object)null && container.GetInventory() != null && (range <= 0f || Vector3.Distance(center, ((Component)container).transform.position) < range) && container.CheckAccess(Player.m_localPlayer.GetPlayerID()) && !container.IsInUse()))
			{
				Vector3 position = ((Component)item).transform.position;
				if (PrivateArea.CheckAccess(position, 0f, false, false))
				{
					if (!PrivateArea.InsideFactionArea(((Component)item).transform.position, (Faction)0))
					{
						item.Load();
						list.Add(item);
					}
					else
					{
						item.Load();
						list.Add(item);
					}
				}
			}
			return list;
		}

		public static async void RefuelSmelter(Smelter __instance, ZNetView ___m_nview, int delay)
		{
			await Task.Delay(delay);
			if (!Object.op_Implicit((Object)(object)__instance) || !Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsValid())
			{
				return;
			}
			int maxOre = __instance.m_maxOre - Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>();
			int maxFuel = __instance.m_maxFuel - Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f));
			List<Container> nearbyOreContainers = GetNearbyContainers(((Component)__instance).transform.position, 10f);
			List<Container> nearbyFuelContainers = GetNearbyContainers(((Component)__instance).transform.position, 10f);
			if (((Object)__instance).name.Contains("charcoal_kiln"))
			{
				string outputName = __instance.m_conversion[0].m_to.m_itemData.m_shared.m_name;
				int maxOutput = 50 - Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>();
				foreach (Container c in nearbyOreContainers)
				{
					List<ItemData> itemList = new List<ItemData>();
					c.GetInventory().GetAllItems(outputName, itemList);
					foreach (ItemData outputItem in itemList)
					{
						if (outputItem != null)
						{
							maxOutput -= outputItem.m_stack;
						}
					}
				}
				if (maxOutput < 0)
				{
					maxOutput = 0;
				}
				if (maxOre > maxOutput)
				{
					maxOre = maxOutput;
				}
			}
			bool fueled = false;
			bool ored = false;
			Vector3 position = ((Component)__instance).transform.position + Vector3.up;
			Collider[] array = Physics.OverlapSphere(position, 10f);
			foreach (Collider collider in array)
			{
				if (!Object.op_Implicit((Object)(object)((collider != null) ? collider.attachedRigidbody : null)))
				{
					continue;
				}
				ItemDrop item = ((Component)collider.attachedRigidbody).GetComponent<ItemDrop>();
				int num;
				if (item == null)
				{
					num = 1;
				}
				else
				{
					ZNetView component = ((Component)item).GetComponent<ZNetView>();
					num = ((((component != null) ? new bool?(component.IsValid()) : null) != true) ? 1 : 0);
				}
				if (num != 0)
				{
					continue;
				}
				string name = GetPrefabName(((Object)((Component)item).gameObject).name);
				foreach (ItemConversion itemConversion in __instance.m_conversion)
				{
					if (ored)
					{
						break;
					}
					if (!(item.m_itemData.m_shared.m_name == itemConversion.m_from.m_itemData.m_shared.m_name) || maxOre <= 0 || oreDisallowTypes.Split(new char[1] { ',' }).Contains(name))
					{
						continue;
					}
					int amount2 = Mathf.Min(item.m_itemData.m_stack, maxOre);
					maxOre -= amount2;
					for (int j = 0; j < amount2; j++)
					{
						if (item.m_itemData.m_stack <= 1)
						{
							if (___m_nview.GetZDO() == null)
							{
								Object.Destroy((Object)(object)((Component)item).gameObject);
							}
							else
							{
								ZNetScene.instance.Destroy(((Component)item).gameObject);
							}
							___m_nview.InvokeRPC("RPC_AddOre", new object[1] { name });
							if (distributedFilling)
							{
								ored = true;
							}
							break;
						}
						ItemData itemData = item.m_itemData;
						itemData.m_stack--;
						___m_nview.InvokeRPC("RPC_AddOre", new object[1] { name });
						Traverse.Create((object)item).Method("Save", Array.Empty<object>()).GetValue();
						if (distributedFilling)
						{
							ored = true;
						}
					}
				}
				if (!Object.op_Implicit((Object)(object)__instance.m_fuelItem) || !(item.m_itemData.m_shared.m_name == __instance.m_fuelItem.m_itemData.m_shared.m_name) || maxFuel <= 0 || fueled || fuelDisallowTypes.Split(new char[1] { ',' }).Contains(name))
				{
					continue;
				}
				int amount = Mathf.Min(item.m_itemData.m_stack, maxFuel);
				maxFuel -= amount;
				for (int i = 0; i < amount; i++)
				{
					if (item.m_itemData.m_stack <= 1)
					{
						if (___m_nview.GetZDO() == null)
						{
							Object.Destroy((Object)(object)((Component)item).gameObject);
						}
						else
						{
							ZNetScene.instance.Destroy(((Component)item).gameObject);
						}
						___m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
						if (distributedFilling)
						{
							fueled = true;
						}
						break;
					}
					ItemData itemData2 = item.m_itemData;
					itemData2.m_stack--;
					___m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
					Traverse.Create((object)item).Method("Save", Array.Empty<object>()).GetValue();
					if (distributedFilling)
					{
						fueled = true;
						break;
					}
				}
			}
			foreach (Container c3 in nearbyOreContainers)
			{
				foreach (ItemConversion itemConversion2 in __instance.m_conversion)
				{
					if (ored)
					{
						break;
					}
					List<ItemData> itemList3 = new List<ItemData>();
					c3.GetInventory().GetAllItems(itemConversion2.m_from.m_itemData.m_shared.m_name, itemList3);
					foreach (ItemData oreItem in itemList3)
					{
						if (oreItem != null && maxOre > 0 && !oreDisallowTypes.Split(new char[1] { ',' }).Contains(((Object)oreItem.m_dropPrefab).name))
						{
							maxOre--;
							object[] array2 = new object[1];
							GameObject dropPrefab = oreItem.m_dropPrefab;
							array2[0] = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
							___m_nview.InvokeRPC("RPC_AddOre", array2);
							c3.GetInventory().RemoveItem(itemConversion2.m_from.m_itemData.m_shared.m_name, 1, -1, true);
							typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(c3, new object[0]);
							typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(c3.GetInventory(), new object[0]);
							if (distributedFilling)
							{
								ored = true;
								break;
							}
						}
					}
				}
			}
			foreach (Container c2 in nearbyFuelContainers)
			{
				if (!Object.op_Implicit((Object)(object)__instance.m_fuelItem) || maxFuel <= 0 || fueled)
				{
					break;
				}
				List<ItemData> itemList2 = new List<ItemData>();
				c2.GetInventory().GetAllItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, itemList2);
				foreach (ItemData fuelItem in itemList2)
				{
					if (fuelItem == null)
					{
						continue;
					}
					maxFuel--;
					if (!fuelDisallowTypes.Split(new char[1] { ',' }).Contains(((Object)fuelItem.m_dropPrefab).name))
					{
						___m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
						c2.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, 1, -1, true);
						typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(c2, new object[0]);
						typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(c2.GetInventory(), new object[0]);
						if (distributedFilling)
						{
							fueled = true;
							break;
						}
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	public static class PlayerUpdatePatch
	{
		private static void Postfix(Player __instance)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				ApplyModerBuff(__instance);
			}
		}

		private static void ApplyModerBuff(Player player)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			SEMan sEMan = ((Character)player).GetSEMan();
			int stableHashCode = StringExtensionMethods.GetStableHashCode("GP_Moder");
			if (sEMan != null && !sEMan.HaveStatusEffect(stableHashCode))
			{
				StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(stableHashCode);
				statusEffect.m_ttl = 0f;
				statusEffect.m_startMessage = "";
				statusEffect.m_startEffects = new EffectList();
				sEMan.AddStatusEffect(statusEffect, false, 0, 0f);
			}
		}
	}
	[HarmonyPatch(typeof(ItemStand), "IsGuardianPowerActive")]
	public static class ItemStandIsGuardianPowerActivePatch
	{
		private static void Postfix(ItemStand __instance, ref bool __result, Humanoid user)
		{
			if (((Object)__instance.m_guardianPower).name == "GP_Moder")
			{
				__result = true;
			}
		}
	}
	public static class PlayerExtensions
	{
		public static SEMan GetSEMan(this Player player)
		{
			return ((Component)player).GetComponent<SEMan>();
		}

		public static bool HaveStatusEffect(this SEMan seman, int effectHash)
		{
			foreach (StatusEffect statusEffect in seman.m_statusEffects)
			{
				if (statusEffect.m_nameHash == effectHash)
				{
					return true;
				}
			}
			return false;
		}

		public static void AddStatusEffect(this SEMan seman, StatusEffect effect)
		{
			seman.AddStatusEffect(effect, false, 0, 0f);
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public static class Chat_MixedCase_Terminal_Patch
	{
		[HarmonyPatch("AddString", new Type[]
		{
			typeof(string),
			typeof(string),
			typeof(Type),
			typeof(bool)
		})]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> AddString_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return sFunc.StripForcedCase(instructions);
		}
	}
	[HarmonyPatch(typeof(Chat))]
	public static class Chat_MixedCase_Chat_Patch
	{
		[HarmonyPatch("AddInworldText")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> AddInworldText_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return sFunc.StripForcedCase(instructions);
		}
	}
	[HarmonyPatch(typeof(Chat))]
	public static class Chat_Shout_Patch
	{
		[HarmonyPatch("InputText")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> InputText_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldstr && instruction.operand.Equals("say "))
				{
					instruction.operand = "s ";
				}
				yield return instruction;
			}
		}
	}
	[HarmonyPatch(typeof(Minimap))]
	public static class Minimap_Patches
	{
		[HarmonyPatch("UpdateDynamicPins")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i + 1].opcode == OpCodes.Call)
				{
					MethodBase methodBase = (MethodBase)list[i + 1].operand;
					if (methodBase.Name == "UpdateShoutPins")
					{
						list.RemoveRange(i, 2);
						break;
					}
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	public static class Player_Update_Patch
	{
		private static GameObject timeObj = null;

		private static double savedEnvMinutes = -1.0;

		private const float ColorRatio = 0.5882353f;

		private const float AlphaRatio = 44f / 51f;

		private const int FontSize = 24;

		private static void Postfix(ref Player __instance)
		{
			if (((Character)__instance).m_nview.IsValid() && ((Character)__instance).m_nview.IsOwner())
			{
				Hud instance = Hud.instance;
				if ((Object)(object)timeObj == (Object)null)
				{
					InitializeTimeObject(instance);
				}
				UpdateTimeText(instance, EnvMan.instance);
			}
		}

		private static void InitializeTimeObject(Hud hud)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			MessageHud instance = MessageHud.instance;
			timeObj = new GameObject("TimeText");
			timeObj.transform.SetParent(((Component)hud.m_statusEffectListRoot).transform.parent);
			timeObj.AddComponent<RectTransform>();
			TMP_Text val = (TMP_Text)(object)timeObj.AddComponent<TextMeshProUGUI>();
			((Graphic)val).color = new Color(0.5882353f, 0.5882353f, 0.5882353f, 44f / 51f);
			val.font = instance.m_messageCenterText.font;
			val.fontSize = 24f;
			val.alignment = (TextAlignmentOptions)514;
			val.overflowMode = (TextOverflowModes)0;
			((Behaviour)val).enabled = true;
		}

		private static void UpdateTimeText(Hud hud, EnvMan env)
		{
			double num = env.m_totalSeconds / 60.0;
			if (savedEnvMinutes != num)
			{
				TMP_Text component = timeObj.GetComponent<TMP_Text>();
				int currentDay = env.GetCurrentDay();
				float num2 = Mathf.Lerp(0f, 24f, env.GetDayFraction());
				int num3 = Mathf.FloorToInt(num2);
				int num4 = Mathf.FloorToInt((num2 - (float)num3) * 60f);
				string text = ((num3 < 12) ? " AM" : " PM");
				if (num3 > 12)
				{
					num3 -= 12;
				}
				component.text = $"Day {currentDay}, {num3:00}:{num4:00}{text}";
				PositionTimeText(hud);
				savedEnvMinutes = num;
			}
		}

		private static void PositionTimeText(Hud hud)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)hud.m_staminaBar2Root).transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			Transform transform2 = ((Component)hud.m_statusEffectListRoot).transform;
			RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
			RectTransform component = timeObj.GetComponent<RectTransform>();
			((Transform)component).position = Vector2.op_Implicit(new Vector2(((Transform)val).position.x, ((Transform)val2).position.y));
			timeObj.SetActive(true);
		}
	}
	public class Crafting
	{
		public static bool cfWorkbench = true;

		public static bool paCheck = false;
	}
	public static class Inventory_NearbyChests_Cache
	{
		public static List<Container> chests = new List<Container>();

		public static readonly Stopwatch delta = new Stopwatch();
	}
	[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
	public static class InventoryGui_SetupRequirement_Patch
	{
		private static bool Prefix(Transform elementRoot, Requirement req, Player player, bool craft, int quality, ref bool __result)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			Image component = ((Component)((Component)elementRoot).transform.Find("res_icon")).GetComponent<Image>();
			TMP_Text component2 = ((Component)((Component)elementRoot).transform.Find("res_name")).GetComponent<TMP_Text>();
			TMP_Text component3 = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TMP_Text>();
			UITooltip component4 = ((Component)elementRoot).GetComponent<UITooltip>();
			if ((Object)(object)req.m_resItem != (Object)null)
			{
				((Component)component).gameObject.SetActive(true);
				((Component)component2).gameObject.SetActive(true);
				((Component)component3).gameObject.SetActive(true);
				component.sprite = req.m_resItem.m_itemData.GetIcon();
				((Graphic)component).color = Color.white;
				component4.m_text = Localization.instance.Localize(req.m_resItem.m_itemData.m_shared.m_name);
				component2.text = Localization.instance.Localize(req.m_resItem.m_itemData.m_shared.m_name);
				int num = ((Humanoid)player).GetInventory().CountItems(req.m_resItem.m_itemData.m_shared.m_name, -1, true);
				int num2 = ((Humanoid)player).GetInventory().CountItems(req.m_resItem.m_itemData.m_shared.m_name, -1, true);
				int amount = req.GetAmount(quality);
				if (amount <= 0)
				{
					InventoryGui.HideRequirement(elementRoot);
					__result = false;
					return false;
				}
				CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
				GameObject val = ((currentCraftingStation != null) ? ((Component)currentCraftingStation).gameObject : null);
				Stopwatch stopwatch;
				if (!Object.op_Implicit((Object)(object)val) || !Crafting.cfWorkbench)
				{
					val = ((Component)player).gameObject;
					stopwatch = Inventory_NearbyChests_Cache.delta;
				}
				else
				{
					stopwatch = GameObjectAssistant.GetStopwatch(val);
				}
				int num3 = sFunc.Clamp(3, 1, 10) * 1000;
				if (!stopwatch.IsRunning || stopwatch.ElapsedMilliseconds > num3)
				{
					Inventory_NearbyChests_Cache.chests = InventoryAssistant.GetNearbyChests(val, sFunc.Clamp(20, 1, 50), !Crafting.paCheck);
					stopwatch.Restart();
				}
				num2 += InventoryAssistant.GetItemAmountInItemList(InventoryAssistant.GetNearbyChestItemsByContainerList(Inventory_NearbyChests_Cache.chests), req.m_resItem.m_itemData);
				component3.text = num2 + "/" + amount;
				if (num2 < amount)
				{
					((Graphic)component3).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : Color.white);
				}
				else if (num < amount)
				{
					((Graphic)component3).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? Color.yellow : Color.white);
				}
				else
				{
					((Graphic)component3).color = Color.white;
				}
				component3.fontSize = 14f;
				if (component3.text.Length > 5)
				{
					component3.fontSize -= (float)(component3.text.Length - 5);
				}
			}
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
	public static class InventoryGui_DoCrafting_Transpiler
	{
		private static MethodInfo method_Player_Inventory_RemoveItem = AccessTools.Method(typeof(Inventory), "RemoveItem", new Type[4]
		{
			typeof(string),
			typeof(int),
			typeof(int),
			typeof(bool)
		}, (Type[])null);

		private static MethodInfo method_UseItemFromInventoryOrChest = AccessTools.Method(typeof(InventoryGui_DoCrafting_Transpiler), "UseItemFromInventoryOrChest", (Type[])null, (Type[])null);

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], method_Player_Inventory_RemoveItem))
				{
					list[i] = new CodeInstruction(OpCodes.Call, (object)method_UseItemFromInventoryOrChest);
					list.RemoveAt(i - 8);
					return list.AsEnumerable();
				}
			}
			return instructions;
		}

		private static void UseItemFromInventoryOrChest(Player player, string itemName, int quantity, int quality, bool worldLevelBased)
		{
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory.CountItems(itemName, quality, true) >= quantity)
			{
				inventory.RemoveItem(itemName, quantity, quality, worldLevelBased);
				return;
			}
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			GameObject val = ((currentCraftingStation != null) ? ((Component)currentCraftingStation).gameObject : null);
			if (!Object.op_Implicit((Object)(object)val) || !Crafting.cfWorkbench)
			{
				val = ((Component)player).gameObject;
			}
			List<Container> nearbyChests = InventoryAssistant.GetNearbyChests(val, sFunc.Clamp(20, 1, 50), !Crafting.paCheck);
			int num = quantity;
			foreach (Container item in nearbyChests)
			{
				Inventory inventory2 = item.GetInventory();
				if (inventory2.CountItems(itemName, quality, true) > 0)
				{
					num -= InventoryAssistant.RemoveItemFromChest(item, itemName, num);
					if (num == 0)
					{
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirementItems", new Type[]
	{
		typeof(Recipe),
		typeof(bool),
		typeof(int)
	})]
	public static class Player_HaveRequirementItems_Transpiler
	{
		private static MethodInfo method_Inventory_CountItems = AccessTools.Method(typeof(Inventory), "CountItems", (Type[])null, (Type[])null);

		private static MethodInfo method_ComputeItemQuantity = AccessTools.Method(typeof(Player_HaveRequirementItems_Transpiler), "ComputeItemQuantity", (Type[])null, (Type[])null);

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], method_Inventory_CountItems))
				{
					list.Insert(++i, new CodeInstruction(OpCodes.Ldloc_2, (object)null));
					list.Insert(++i, new CodeInstruction(OpCodes.Ldarg_0, (object)null));
					list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)method_ComputeItemQuantity));
				}
			}
			return list.AsEnumerable();
		}

		private static int ComputeItemQuantity(int fromInventory, Requirement item, Player player)
		{
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			GameObject val = ((currentCraftingStation != null) ? ((Component)currentCraftingStation).gameObject : null);
			Stopwatch stopwatch;
			if (!Object.op_Implicit((Object)(object)val) || !Crafting.cfWorkbench)
			{
				val = ((Component)player).gameObject;
				stopwatch = Inventory_NearbyChests_Cache.delta;
			}
			else
			{
				stopwatch = GameObjectAssistant.GetStopwatch(val);
			}
			int num = sFunc.Clamp(3, 1, 10) * 1000;
			if (!stopwatch.IsRunning || stopwatch.ElapsedMilliseconds > num)
			{
				Inventory_NearbyChests_Cache.chests = InventoryAssistant.GetNearbyChests(val, sFunc.Clamp(20, 1, 50), !Crafting.paCheck);
				stopwatch.Restart();
			}
			return fromInventory + InventoryAssistant.GetItemAmountInItemList(InventoryAssistant.GetNearbyChestItemsByContainerList(Inventory_NearbyChests_Cache.chests), item.m_resItem.m_itemData);
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Piece),
		typeof(RequirementMode)
	})]
	public static class Player_HaveRequirements_Transpiler
	{
		private static MethodInfo method_Inventory_CountItems = AccessTools.Method(typeof(Inventory), "CountItems", (Type[])null, (Type[])null);

		private static MethodInfo method_ComputeItemQuantity = AccessTools.Method(typeof(Player_HaveRequirements_Transpiler), "ComputeItemQuantity", (Type[])null, (Type[])null);

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], method_Inventory_CountItems))
				{
					list.Insert(++i, new CodeInstruction(OpCodes.Ldloc_2, (object)null));
					list.Insert(++i, new CodeInstruction(OpCodes.Ldarg_0, (object)null));
					list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)method_ComputeItemQuantity));
				}
			}
			return list.AsEnumerable();
		}

		private static int ComputeItemQuantity(int fromInventory, Requirement item, Player player)
		{
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			GameObject val = ((currentCraftingStation != null) ? ((Component)currentCraftingStation).gameObject : null);
			Stopwatch stopwatch;
			if (!Object.op_Implicit((Object)(object)val) || !Crafting.cfWorkbench)
			{
				val = ((Component)player).gameObject;
				stopwatch = Inventory_NearbyChests_Cache.delta;
			}
			else
			{
				stopwatch = GameObjectAssistant.GetStopwatch(val);
			}
			int num = sFunc.Clamp(3, 1, 10) * 1000;
			if (!stopwatch.IsRunning || stopwatch.ElapsedMilliseconds > num)
			{
				Inventory_NearbyChests_Cache.chests = InventoryAssistant.GetNearbyChests(val, sFunc.Clamp(20, 1, 50), !Crafting.paCheck);
				stopwatch.Restart();
			}
			return fromInventory + InventoryAssistant.GetItemAmountInItemList(InventoryAssistant.GetNearbyChestItemsByContainerList(Inventory_NearbyChests_Cache.chests), item.m_resItem.m_itemData);
		}
	}
	[HarmonyPatch(typeof(Player), "ConsumeResources", new Type[]
	{
		typeof(Requirement[]),
		typeof(int),
		typeof(int)
	})]
	public static class Player_ConsumeResources_Transpiler
	{
		private static MethodInfo method_Inventory_RemoveItem = AccessTools.Method(typeof(Inventory), "RemoveItem", new Type[4]
		{
			typeof(string),
			typeof(int),
			typeof(int),
			typeof(bool)
		}, (Type[])null);

		private static MethodInfo method_RemoveItemsFromInventoryAndNearbyChests = AccessTools.Method(typeof(Player_ConsumeResources_Transpiler), "RemoveItemsFromInventoryAndNearbyChests", (Type[])null, (Type[])null);

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = -1;
			int num2 = -1;
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldarg_0)
				{
					num = i;
				}
				else if (CodeInstructionExtensions.Calls(list[i], method_Inventory_RemoveItem))
				{
					num2 = i;
					break;
				}
			}
			if (num == -1 || num2 == -1)
			{
				return instructions;
			}
			list.RemoveRange(num + 1, num2 - num);
			list.Insert(++num, new CodeInstruction(OpCodes.Ldloc_2, (object)null));
			list.Insert(++num, new CodeInstruction(OpCodes.Ldloc_3, (object)null));
			list.Insert(++num, new CodeInstruction(OpCodes.Ldarg_3, (object)null));
			list.Insert(++num, new CodeInstruction(OpCodes.Call, (object)method_RemoveItemsFromInventoryAndNearbyChests));
			return list.AsEnumerable();
		}

		private static void RemoveItemsFromInventoryAndNearbyChests(Player player, Requirement item, int amount, int itemQuality)
		{
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			GameObject val = ((currentCraftingStation != null) ? ((Component)currentCraftingStation).gameObject : null);
			if (!Object.op_Implicit((Object)(object)val) || !Crafting.cfWorkbench)
			{
				val = ((Component)player).gameObject;
			}
			int num = ((Humanoid)player).m_inventory.CountItems(item.m_resItem.m_itemData.m_shared.m_name, -1, true);
			((Humanoid)player).m_inventory.RemoveItem(item.m_resItem.m_itemData.m_shared.m_name, amount, itemQuality, true);
			amount -= num;
			if (amount > 0)
			{
				InventoryAssistant.RemoveItemInAmountFromAllNearbyChests(val, sFunc.Clamp(20, 1, 50), item.m_resItem.m_itemData, amount, !Crafting.paCheck);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "GetFirstRequiredItem")]
	public static class Player_GetFirstRequiredItem_Transpiler
	{
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldarg_0)
				{
					list[i].opcode = OpCodes.Ldarg_1;
					list.RemoveAt(i + 1);
					return list.AsEnumerable();
				}
			}
			return instructions;
		}
	}
	internal static class InventoryAssistant
	{
		public static List<Container> GetNearbyChests(GameObject target, float range, bool checkWard = true)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[1] { "piece" };
			Collider[] source = Physics.OverlapSphere(target.transform.position, range, LayerMask.GetMask(array));
			IOrderedEnumerable<Collider> orderedEnumerable = source.OrderBy((Collider x) => Vector3.Distance(((Component)x).gameObject.transform.position, target.transform.position));
			List<Container> list = new List<Container>();
			foreach (Collider item in orderedEnumerable)
			{
				try
				{
					Container componentInParent = ((Component)item).GetComponentInParent<Container>();
					if (Object.op_Implicit((Object)(object)componentInParent) && !list.Contains(componentInParent))
					{
						bool flag = componentInParent.CheckAccess(Player.m_localPlayer.GetPlayerID());
						if (checkWard)
						{
							flag = flag && PrivateArea.CheckAccess(((Component)item).gameObject.transform.position, 0f, false, true);
						}
						Piece componentInParent2 = ((Component)componentInParent).GetComponentInParent<Piece>();
						bool flag2 = (Object)(object)((Component)componentInParent).GetComponentInParent<Vagon>() != (Object)null;
						bool flag3 = (Object)(object)((Component)componentInParent).GetComponentInParent<Ship>() != (Object)null;
						if ((Object)(object)componentInParent2 != (Object)null && flag && componentInParent.GetInventory() != null && (componentInParent2.IsPlacedByPlayer() || (flag3 && Crafting.cfWorkbench)))
						{
							list.Add(componentInParent);
						}
					}
				}
				catch
				{
				}
			}
			return list;
		}

		public static List<Container> GetNearbyChestsWithItem(GameObject target, float range, ItemData itemInfo, bool checkWard = true)
		{
			List<Container> nearbyChests = GetNearbyChests(target, range, checkWard);
			List<Container> list = new List<Container>();
			foreach (Container item in nearbyChests)
			{
				if (ChestContainsItem(item, itemInfo))
				{
					list.Add(item);
				}
			}
			return list;
		}

		public static bool ChestContainsItem(Container chest, ItemData needle)
		{
			List<ItemData> allItems = chest.GetInventory().GetAllItems();
			foreach (ItemData item in allItems)
			{
				if (item.m_shared.m_name == needle.m_shared.m_name)
				{
					return true;
				}
			}
			return false;
		}

		public static bool ChestContainsItem(Container chest, string needle)
		{
			List<ItemData> allItems = chest.GetInventory().GetAllItems();
			foreach (ItemData item in allItems)
			{
				if (item.m_shared.m_name == needle)
				{
					return true;
				}
			}
			return false;
		}

		public static List<ItemData> GetNearbyChestItems(GameObject target, float range = 10f, bool checkWard = true)
		{
			List<ItemData> list = new List<ItemData>();
			List<Container> nearbyChests = GetNearbyChests(target, range, checkWard);
			foreach (Container item in nearbyChests)
			{
				List<ItemData> allItems = item.GetInventory().GetAllItems();
				foreach (ItemData item2 in allItems)
				{
					list.Add(item2);
				}
			}
			return list;
		}

		public static List<ItemData> GetNearbyChestItemsByContainerList(List<Container> nearbyChests)
		{
			List<ItemData> list = new List<ItemData>();
			foreach (Container nearbyChest in nearbyChests)
			{
				List<ItemData> allItems = nearbyChest.GetInventory().GetAllItems();
				foreach (ItemData item in allItems)
				{
					list.Add(item);
				}
			}
			return list;
		}

		public static int GetItemAmountInItemList(List<ItemData> itemList, ItemData needle)
		{
			int num = 0;
			foreach (ItemData item in itemList)
			{
				if (item.m_shared.m_name == needle.m_shared.m_name)
				{
					num += item.m_stack;
				}
			}
			return num;
		}

		public static int GetItemAmountInItemList(List<ItemData> itemList, string needle)
		{
			int num = 0;
			foreach (ItemData item in itemList)
			{
				if (item.m_shared.m_name == needle)
				{
					num += item.m_stack;
				}
			}
			return num;
		}

		public static int RemoveItemInAmountFromAllNearbyChests(GameObject target, float range, ItemData needle, int amount, bool checkWard = true)
		{
			List<Container> nearbyChests = GetNearbyChests(target, range, checkWard);
			List<ItemData> nearbyChestItemsByContainerList = GetNearbyChestItemsByContainerList(nearbyChests);
			int itemAmountInItemList = GetItemAmountInItemList(nearbyChestItemsByContainerList, needle);
			if (amount == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (Container item in nearbyChests)
			{
				if (num != amount)
				{
					int num2 = RemoveItemFromChest(item, needle, amount);
					num += num2;
					amount -= num2;
				}
			}
			return num;
		}

		public static int RemoveItemInAmountFromAllNearbyChests(GameObject target, float range, string needle, int amount, bool checkWard = true)
		{
			List<Container> nearbyChests = GetNearbyChests(target, range, checkWard);
			List<ItemData> nearbyChestItemsByContainerList = GetNearbyChestItemsByContainerList(nearbyChests);
			int itemAmountInItemList = GetItemAmountInItemList(nearbyChestItemsByContainerList, needle);
			if (amount == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (Container item in nearbyChests)
			{
				if (num != amount)
				{
					int num2 = RemoveItemFromChest(item, needle, amount);
					num += num2;
					amount -= num2;
				}
			}
			return num;
		}

		public static int RemoveItemFromChest(Container chest, ItemData needle, int amount = 1)
		{
			if (!ChestContainsItem(chest, needle))
			{
				return 0;
			}
			int num = 0;
			List<ItemData> allItems = chest.GetInventory().GetAllItems();
			foreach (ItemData item in allItems)
			{
				if (item.m_shared.m_name == needle.m_shared.m_name)
				{
					int num2 = Mathf.Min(item.m_stack, amount);
					item.m_stack -= num2;
					amount -= num2;
					num += num2;
					if (amount <= 0)
					{
						break;
					}
				}
			}
			if (num == 0)
			{
				return 0;
			}
			allItems.RemoveAll((ItemData x) => x.m_stack <= 0);
			chest.m_inventory.m_inventory = allItems;
			ConveyContainerToNetwork(chest);
			return num;
		}

		public static int RemoveItemFromChest(Container chest, string needle, int amount = 1)
		{
			if (!ChestContainsItem(chest, needle))
			{
				return 0;
			}
			int num = 0;
			List<ItemData> allItems = chest.GetInventory().GetAllItems();
			foreach (ItemData item in allItems)
			{
				if (item.m_shared.m_name == needle)
				{
					int num2 = Mathf.Min(item.m_stack, amount);
					item.m_stack -= num2;
					amount -= num2;
					num += num2;
					if (amount <= 0)
					{
						break;
					}
				}
			}
			if (num == 0)
			{
				return 0;
			}
			allItems.RemoveAll((ItemData x) => x.m_stack <= 0);
			chest.m_inventory.m_inventory = allItems;
			ConveyContainerToNetwork(chest);
			return num;
		}

		public static void ConveyContainerToNetwork(Container c)
		{
			c.Save();
			c.GetInventory().Changed();
		}
	}
	internal static class GameObjectAssistant
	{
		private static ConcurrentDictionary<float, Stopwatch> stopwatches = new ConcurrentDictionary<float, Stopwatch>();

		public static Stopwatch GetStopwatch(GameObject o)
		{
			float gameObjectPosHash = GetGameObjectPosHash(o);
			Stopwatch value = null;
			if (!stopwatches.TryGetValue(gameObjectPosHash, out value))
			{
				value = new Stopwatch();
				stopwatches.TryAdd(gameObjectPosHash, value);
			}
			return value;
		}

		private static float GetGameObjectPosHash(GameObject o)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			return 1000f * o.transform.position.x + o.transform.position.y + 0.001f * o.transform.position.z;
		}

		public static T GetChildComponentByName<T>(string name, GameObject objected) where T : Component
		{
			T[] componentsInChildren = objected.GetComponentsInChildren<T>(true);
			foreach (T val in componentsInChildren)
			{
				if (((Object)((Component)val).gameObject).name == name)
				{
					return val;
				}
			}
			return default(T);
		}
	}
	public class Crops
	{
		public static KeyCode MassActionHotkey = (KeyCode)304;

		public static KeyCode ControllerPickupHotkey = (KeyCode)334;

		public static float MassInteractRange = 5f;

		public static int PlantGridWidth = 5;

		public static int PlantGridLength = 5;

		public static bool IgnoreStamina = false;

		public static bool IgnoreDurability = false;

		public static bool GridAnchorWidth = true;

		public static bool GridAnchorLength = true;
	}
	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	public static class MassPlant
	{
		private static readonly FieldInfo m_noPlacementCostField = AccessTools.Field(typeof(Player), "m_noPlacementCost");

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

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

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

		private static Vector3 placedPosition;

		private static Quaternion placedRotation;

		private static Piece placedPiece;

		private static bool placeSuccessful = false;

		private static int? massFarmingRotation = null;

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

		private static GameObject[] _placementGhosts = (GameObject[])(object)new GameObject[1];

		private static readonly Piece _fakeResourcePiece;

		private static bool IsHotKeyPressed => Input.GetKey(Crops.ControllerPickupHotkey) || Input.GetKey(Crops.MassActionHotkey);

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "PlacePiece")]
		public static void PlacePiecePrefix(int ___m_placeRotation)
		{
			if (IsHotKeyPressed)
			{
				int? num = massFarmingRotation;
				if (!num.HasValue)
				{
					massFarmingRotation = ___m_placeRotation;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "PlacePiece")]
		public static void PlacePiecePostfix(Player __instance, ref bool __result, Piece piece, ref int ___m_placeRotation)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			placeSuccessful = __result;
			if (__result)
			{
				GameObject val = (GameObject)m_placementGhostField.GetValue(__instance);
				placedPosition = val.transform.position;
				placedRotation = val.transform.rotation;
				placedPiece = piece;
			}
			if (IsHotKeyPressed)
			{
				___m_placeRotation = massFarmingRotation.Value;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		public static void UpdatePlacementPrefix(bool takeInput, float dt, ref int ___m_placeRotation)
		{
			placeSuccessful = false;
			if (IsHotKeyPressed && massFarmingRotation.HasValue)
			{
				___m_placeRotation = massFarmingRotation.Value;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		public static void UpdatePlacementPostfix(Player __instance, bool takeInput, float dt, int ___m_placeRotation)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			if (IsHotKeyPressed)
			{
				massFarmingRotation = ___m_placeRotation;
			}
			if (!placeSuccessful)
			{
				return;
			}
			Plant component = ((Component)placedPiece).gameObject.GetComponent<Plant>();
			if (!Object.op_Implicit((Object)(object)component) || !IsHotKeyPressed)
			{
				return;
			}
			Heightmap val = Heightmap.FindHeightmap(placedPosition);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			foreach (Vector3 item in BuildPlantingGridPositions(placedPosition, component, placedRotation))
			{
				if ((placedPiece.m_cultivatedGroundOnly && !val.IsCultivated(item)) || placedPosition == item)
				{
					continue;
				}
				object? obj = _GetRightItemMethod.Invoke(__instance, Array.Empty<object>());
				ItemData val2 = (ItemData)((obj is ItemData) ? obj : null);
				if (val2 == null)
				{
					continue;
				}
				if (!Crops.IgnoreStamina && !((Character)__instance).HaveStamina(val2.m_shared.m_attack.m_attackStamina))
				{
					Hud.instance.StaminaBarUppgradeFlash();
					break;
				}
				if (!(bool)m_noPlacementCostField.GetValue(__instance) && !__instance.HaveRequirements(placedPiece, (RequirementMode)0))
				{
					break;
				}
				if (!HasGrowSpace(item, ((Component)placedPiece).gameObject))
				{
					continue;
				}
				GameObject val3 = Object.Instantiate<GameObject>(((Component)placedPiece).gameObject, item, placedRotation);
				Piece component2 = val3.GetComponent<Piece>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					component2.SetCreator(__instance.GetPlayerID());
				}
				placedPiece.m_placeEffect.Create(item, placedRotation, val3.transform, 1f, -1);
				Game.instance.IncrementPlayerStat((PlayerStatType)2, 1f);
				__instance.ConsumeResources(placedPiece.m_resources, 0, -1);
				if (!Crops.IgnoreStamina)
				{
					((Character)__instance).UseStamina(val2.m_shared.m_attack.m_attackStamina, false);
				}
				if (!Crops.IgnoreDurability && val2.m_shared.m_useDurability)
				{
					val2.m_durability -= val2.m_shared.m_useDurabilityDrain;
					if (val2.m_durability <= 0f)
					{
						break;
					}
				}
			}
		}

		private static List<Vector3> BuildPlantingGridPositions(Vector3 originPos, Plant placedPlant, Quaternion rotation)
		{
			//IL_001f: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			float num = placedPlant.m_growRadius * 2f;
			List<Vector3> list = new List<Vector3>(Crops.PlantGridWidth * Crops.PlantGridLength);
			Vector3 val = rotation * Vector3.left * num;
			Vector3 val2 = rotation * Vector3.forward * num;
			Vector3 val3 = originPos;
			if (Crops.GridAnchorLength)
			{
				val3 -= val2 * (float)(Crops.PlantGridLength / 2);
			}
			if (Crops.GridAnchorWidth)
			{
				val3 -= val * (float)(Crops.PlantGridWidth / 2);
			}
			for (int i = 0; i < Crops.PlantGridLength; i++)
			{
				Vector3 val4 = val3;
				for (int j = 0; j < Crops.PlantGridWidth; j++)
				{
					val4.y = ZoneSystem.instance.GetGroundHeight(val4);
					list.Add(val4);
					val4 += val;
				}
				val3 += val2;
			}
			return list;
		}

		private static bool HasGrowSpace(Vector3 newPos, GameObject go)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Plant component = go.GetComponent<Plant>();
			if (component != null)
			{
				Collider[] array = Physics.OverlapSphere(newPos, component.m_growRadius, _plantSpaceMask);
				return array.Length == 0;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		public static void SetupPlacementGhostPrefix(Player __instance, int ___m_placeRotation)
		{
			if (IsHotKeyPressed)
			{
				int? num = massFarmingRotation;
				if (!num.HasValue)
				{
					massFarmingRotation = ___m_placeRotation;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		public static void SetupPlacementGhostPostfix(Player __instance, ref int ___m_placeRotation)
		{
			if (IsHotKeyPressed && massFarmingRotation.HasValue)
			{
				___m_placeRotation = massFarmingRotation.Value;
			}
			DestroyGhosts();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		public static void UpdatePlacementGhostPostfix(Player __instance, bool flashGuardStone)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (GameObject)m_placementGhostField.GetValue(__instance);
			if (!Object.op_Implicit((Object)(object)val) || !val.activeSelf)
			{
				SetGhostsActive(active: false);
				return;
			}
			if (!Input.GetKey(Crops.ControllerPickupHotkey) && !Input.GetKey(Crops.MassActionHotkey))
			{
				SetGhostsActive(active: false);
				return;
			}
			Plant component = val.GetComponent<Plant>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				SetGhostsActive(active: false);
				return;
			}
			if (!EnsureGhostsBuilt(__instance))
			{
				SetGhostsActive(active: false);
				return;
			}
			Requirement val2 = ((IEnumerable<Requirement>)val.GetComponent<Piece>().m_resources).FirstOrDefault((Func<Requirement, bool>)((Requirement r) => Object.op_Implicit((Object)(object)r.m_resItem) && r.m_amount > 0));
			_fakeResourcePiece.m_resources[0].m_resItem = val2.m_resItem;
			_fakeResourcePiece.m_resources[0].m_amount = val2.m_amount;
			float num = __instance.GetStamina();
			object? obj = _GetRightItemMethod.Invoke(__instance, Array.Empty<object>());
			ItemData val3 = (ItemData)((obj is ItemData) ? obj : null);
			if (val3 == null)
			{
				return;
			}
			Heightmap val4 = Heightmap.FindHeightmap(val.transform.position);
			List<Vector3> list = BuildPlantingGridPositions(val.transform.position, component, val.transform.rotation);
			for (int i = 0; i < _placementGhosts.Length; i++)
			{
				Vector3 val5 = list[i];
				if (val.transform.position == val5)
				{
					_placementGhosts[i].SetActive(false);
					continue;
				}
				Requirement obj2 = _fakeResourcePiece.m_resources[0];
				obj2.m_amount += val2.m_amount;
				_placementGhosts[i].transform.position = val5;
				_placementGhosts[i].transform.rotation = val.transform.rotation;
				_placementGhosts[i].SetActive(true);
				bool invalidPlacementHeightlight = false;
				if (val.GetComponent<Piece>().m_cultivatedGroundOnly && !val4.IsCultivated(val5))
				{
					invalidPlacementHeightlight = true;
				}
				else if (!HasGrowSpace(val5, val.gameObject))
				{
					invalidPlacementHeightlight = true;
				}
				else if (!Crops.IgnoreStamina && num < val3.m_shared.m_attack.m_attackStamina)
				{
					Hud.instance.StaminaBarUppgradeFlash();
					invalidPlacementHeightlight = true;
				}
				else if (!(bool)m_noPlacementCostField.GetValue(__instance) && !__instance.HaveRequirements(_fakeResourcePiece, (RequirementMode)0))
				{
					invalidPlacementHeightlight = true;
				}
				num -= val3.m_shared.m_attack.m_attackStamina;
				_placementGhosts[i].GetComponent<Piece>().SetInvalidPlacementHeightlight(invalidPlacementHeightlight);
			}
		}

		private static bool EnsureGhostsBuilt(Player player)
		{
			int num = Crops.PlantGridWidth * Crops.PlantGridLength;
			if (!Object.op_Implicit((Object)(object)_placementGhosts[0]) || _placementGhosts.Length != num)
			{
				DestroyGhosts();
				if (_placementGhosts.Length != num)
				{
					_placementGhosts = (GameObject[])(object)new GameObject[num];
				}
				object? value = m_buildPiecesField.GetValue(player);
				PieceTable val = (PieceTable)((value is PieceTable) ? value : null);
				if (val != null)
				{
					GameObject selectedPrefab = val.GetSelectedPrefab();
					if (selectedPrefab != null)
					{
						if (selectedPrefab.GetComponent<Piece>().m_repairPiece)
						{
							return false;
						}
						for (int i = 0; i < _placementGhosts.Length; i++)
						{
							_placementGhosts[i] = SetupMyGhost(player, selectedPrefab);
						}
						goto IL_00d6;
					}
				}
				return false;
			}
			goto IL_00d6;
			IL_00d6:
			return true;
		}

		private static void DestroyGhosts()
		{
			for (int i = 0; i < _placementGhosts.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)_placementGhosts[i]))
				{
					Object.Destroy((Object)(object)_placementGhosts[i]);
					_placementGhosts[i] = null;
				}
			}
		}

		private static void SetGhostsActive(bool active)
		{
			GameObject[] placementGhosts = _placementGhosts;
			foreach (GameObject val in placementGhosts)
			{
				if (val != null)
				{
					val.SetActive(active);
				}
			}
		}

		private static GameObject SetupMyGhost(Player player, GameObject prefab)
		{
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			ZNetView.m_forceDisableInit = true;
			GameObject val = Object.Instantiate<GameObject>(prefab);
			ZNetView.m_forceDisableInit = false;
			((Object)val).name = ((Object)prefab).name;
			Joint[] componentsInChildren = val.GetComponentsInChildren<Joint>();
			foreach (Joint val2 in componentsInChildren)
			{
				Object.Destroy((Object)(object)val2);
			}
			Rigidbody[] componentsInChildren2 = val.GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody val3 in componentsInChildren2)
			{
				Object.Destroy((Object)(object)val3);
			}
			int layer = LayerMask.NameToLayer("ghost");
			Transform[] componentsInChildren3 = val.GetComponentsInChildren<Transform>();
			foreach (Transform val4 in componentsInChildren3)
			{
				((Component)val4).gameObject.layer = layer;
			}
			TerrainModifier[] componentsInChildren4 = val.GetComponentsInChildren<TerrainModifier>();
			foreach (TerrainModifier val5 in componentsInChildren4)
			{
				Object.Destroy((Object)(object)val5);
			}
			GuidePoint[] componentsInChildren5 = val.GetComponentsInChildren<GuidePoint>();
			foreach (GuidePoint val6 in componentsInChildren5)
			{
				Object.Destroy((Object)(object)val6);
			}
			Light[] componentsInChildren6 = val.GetComponentsInChildren<Light>();
			foreach (Light val7 in componentsInChildren6)
			{
				Object.Destroy((Object)(object)val7);
			}
			Transform val8 = val.transform.Find("_GhostOnly");
			if (Object.op_Implicit((Object)(object)val8))
			{
				((Component)val8).gameObject.SetActive(true);
			}
			MeshRenderer[] componentsInChildren7 = val.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val9 in componentsInChildren7)
			{
				if (!((Object)(object)((Renderer)val9).sharedMaterial == (Object)null))
				{
					Material[] sharedMaterials = ((Renderer)val9).sharedMaterials;
					for (int num2 = 0; num2 < sharedMaterials.Length; num2++)
					{
						Material val10 = new Material(sharedMaterials[num2]);
						val10.SetFloat("_RippleDistance", 0f);
						val10.SetFloat("_ValueNoise", 0f);
						sharedMaterials[num2] = val10;
					}
					((Renderer)val9).sharedMaterials = sharedMaterials;
					((Renderer)val9).shadowCastingMode = (ShadowCastingMode)0;
				}
			}
			return val;
		}

		static MassPlant()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			Piece val = new Piece();
			val.m_dlc = string.Empty;
			val.m_resources = (Requirement[])(object)new Requirement[1]
			{
				new Requirement()
			};
			_fakeResourcePiece = val;
		}
	}
	[HarmonyPatch(typeof(Player), "Interact")]
	public static class MassPickup
	{
		private static FieldInfo m_interactMaskField = AccessTools.Field(typeof(Player), "m_interactMask");

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

		[HarmonyPrefix]
		public static void Prefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			if (((Character)__instance).InAttack() || ((Character)__instance).InDodge() || hold || (!Input.GetKey(Crops.ControllerPickupHotkey) && !Input.GetKey(Crops.MassActionHotkey)))
			{
				return;
			}
			Interactable componentInParent = go.GetComponentInParent<Interactable>();
			Pickable val = (Pickable)(object)((componentInParent is Pickable) ? componentInParent : null);
			if (val != null)
			{
				int num = (int)m_interactMaskField.GetValue(__instance);
				Collider[] array = Physics.OverlapSphere(go.transform.position, Crops.MassInteractRange, num);
				Collider[] array2 = array;
				foreach (Collider val2 in array2)
				{
					object obj;
					if (val2 == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = ((Component)val2).gameObject;
						obj = ((gameObject != null) ? gameObject.GetComponentInParent<Pickable>() : null);
					}
					Pickable val3 = (Pickable)obj;
					if (val3 != null && (Object)(object)val3 != (Object)(object)val && ((Object)val3.m_itemPrefab).name == ((Object)val.m_itemPrefab).name)
					{
						val3.Interact((Humanoid)(object)__instance, false, alt);
					}
				}
				return;
			}
			Beehive val4 = (Beehive)(object)((componentInParent is Beehive) ? componentInParent : null);
			if (val4 == null)
			{
				return;
			}
			int num2 = (int)m_interactMaskField.GetValue(__instance);
			Collider[] array3 = Physics.OverlapSphere(go.transform.position, Crops.MassInteractRange, num2);
			Collider[] array4 = array3;
			foreach (Collider val5 in array4)
			{
				object obj2;
				if (val5 == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)val5).gameObject;
					obj2 = ((gameObject2 != null) ? gameObject2.GetComponentInParent<Beehive>() : null);
				}
				Beehive val6 = (Beehive)obj2;
				if (val6 != null && (Object)(object)val6 != (Object)(object)val4 && PrivateArea.CheckAccess(((Component)val6).transform.position, 0f, true, false))
				{
					_ExtractMethod.Invoke(val6, null);
				}
			}
		}
	}
	internal class Demister
	{
		[HarmonyPatch(typeof(Mister), "OnEnable")]
		internal static class MisterOnEnablePatch
		{
			private static bool Prefix()
			{
				return false;
			}
		}

		[HarmonyPatch(typeof(ParticleMist), "Awake")]
		internal static class ParticleMistAwakePatch
		{
			private static void Postfix(ParticleMist __instance)
			{
				try
				{
					if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.m_ps != (Object)null)
					{
						MistEmitter component = ((Component)__instance).GetComponent<MistEmitter>();
						if ((Object)(object)component != (Object)null)
						{
							component.SetEmit(false);
						}
					}
				}
				catch (Exception ex)
				{
					ZLog.LogWarning((object)ex);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "StartGuardianPower")]
	public static class Player_StartGuardianPower_Patch
	{
		private static bool Prefix(ref Player __instance, ref bool __result)
		{
			if ((Object)(object)__instance.m_guardianSE == (Object)null)
			{
				__result = false;
				return false;
			}
			if (__instance.m_guardianPowerCooldown > 0f)
			{
				((Character)__instance).Message((MessageType)2, "$hud_powernotready", 0, (Sprite)null);
				__result = false;
				return false;
			}
			__instance.ActivateGuardianPower();
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(EnvMan), "SetEnv")]
	public static class AshEnvMan_SetEnv_Patch
	{
		private static readonly string targetEnvironment = "Mistlands_clear";

		[HarmonyPrefix]
		public static void Prefix(EnvMan __instance, ref EnvSetup env)
		{
			if (env.m_name.StartsWith("Ashlands"))
			{
				EnvSetup val = __instance.m_environments.Find((EnvSetup e) => e.m_name == targetEnvironment);
				if (val != null && !env.m_name.Equals(targetEnvironment))
				{
					env = val;
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
	public static class InventoryGui_RepairOneItem_Transpiler
	{
		private static readonly MethodInfo method_EffectList_Create = AccessTools.Method(typeof(EffectList), "Create", (Type[])null, (Type[])null);

		private static readonly MethodInfo method_CreateNoop = AccessTools.Method(typeof(InventoryGui_RepairOneItem_Transpiler), "CreateNoop", (Type[])null, (Type[])null);

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], method_EffectList_Create))
				{
					list[i] = new CodeInstruction(OpCodes.Call, (object)method_CreateNoop);
				}
			}
			return list.AsEnumerable();
		}

		private static GameObject[] CreateNoop(Vector3 _0, Quaternion _1, Transform _2, float _3, int _4)
		{
			return null;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "UpdateRepair")]
	public static class InventoryGui_UpdateRepair_Patch
	{
		[HarmonyPrefix]
		public static void Prefix(InventoryGui __instance)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation();
			if ((Object)(object)currentCraftingStation == (Object)null)
			{
				return;
			}
			int num = 0;
			foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems())
			{
				if (ItemRepair.CanRepair(allItem) && allItem.m_durability < allItem.GetMaxDurability())
				{
					allItem.m_durability = allItem.GetMaxDurability();
					num++;
				}
			}
			if (num > 0)
			{
				currentCraftingStation.m_repairItemDoneEffects.Create(((Component)currentCraftingStation).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
			}
		}
	}
	public static class ItemRepair
	{
		public static bool CanRepair(ItemData item)
		{
			Recipe recipe = ObjectDB.instance.GetRecipe(item);
			CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation();
			if ((Object)(object)recipe == (Object)null || (Object)(object)currentCraftingStation == (Object)null)
			{
				return false;
			}
			return (((Object)(object)recipe.m_repairStation != (Object)null && recipe.m_repairStation.m_name == currentCraftingStation.m_name) || ((Object)(object)recipe.m_craftingStation != (Object)null && recipe.m_craftingStation.m_name == currentCraftingStation.m_name)) && currentCraftingStation.GetLevel(true) >= recipe.m_minStationLevel;
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	public static class Game_Start_Patch
	{
		private static void Prefix()
		{
			ZRoutedRpc.instance.Register<ZPackage>("nVHMapSync", (Action<long, ZPackage>)MapSync.RPC_nVHMapSync);
			ZRoutedRpc.instance.Register("nVHAck", (Action<long>)nVHAck.RPC_nVHAck);
		}
	}
	[HarmonyPatch(typeof(Minimap))]
	public class HookExplore
	{
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
		{
			typeof(Vector3),
			typeof(float)
		})]
		public static void call_Explore(object instance, Vector3 p, float radius)
		{
			throw new NotImplementedException();
		}
	}
	[HarmonyPatch(typeof(Minimap), "UpdateExplore")]
	public static class ChangeMapBehavior
	{
		private static void Prefix(ref float dt, ref Player player, ref Minimap __instance, ref float ___m_exploreTimer, ref float ___m_exploreInterval)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			float num = ___m_exploreTimer;
			num += Time.deltaTime;
			float radius = 200f;
			if (num > ___m_exploreInterval && ZNet.instance.m_players.Any())
			{
				foreach (PlayerInfo player2 in ZNet.instance.m_players)
				{
					HookExplore.call_Explore(__instance, player2.m_position, radius);
				}
			}
			HookExplore.call_Explore(__instance, ((Component)player).transform.position, radius);
		}
	}
	[HarmonyPatch(typeof(Minimap), "Awake")]
	public static class MinimapAwake
	{
		private static void Postfix()
		{
			if (ZNet.m_isServer)
			{
				MapSync.ServerMapData = new bool[Minimap.instance.m_textureSize * Minimap.instance.m_textureSize];
				MapSync.LoadMapDataFromDisk();
				NaNNaVH.mapSyncSaveTimer.Start();
			}
		}
	}
	[HarmonyPatch(typeof(ZNet))]
	public class HookZNet
	{
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(ZNet), "GetOtherPublicPlayers", new Type[] { typeof(List<PlayerInfo>) })]
		public static void GetOtherPublicPlayers(object instance, List<PlayerInfo> playerList)
		{
			throw new NotImplementedException();
		}
	}
	[HarmonyPatch(typeof(ZNet), "SendPeriodicData")]
	public static class PeriodicDataHandler
	{
		private static void Postfix()
		{
			RpcQueue.SendNextRpc();
		}
	}
	[HarmonyPatch(typeof(ZNet), "Shutdown")]
	public static class OnErrorLoadOwnIni
	{
		private static void Prefix(ref ZNet __instance)
		{
			if (!__instance.IsServer())
			{
				NaNNaVH.harmony.UnpatchSelf();
				NaNNaVH.harmony.PatchAll();
				MapSync.ShouldSyncOnSpawn = true;
			}
			else
			{
				MapSync.SaveMapDataToDisk();
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "SetPublicReferencePosition")]
	public static class PreventPublicPositionToggle
	{
		private static void Postfix(ref bool pub, ref bool ___m_publicReferencePosition)
		{
			___m_publicReferencePosition = true;
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_ServerSyncedPlayerData")]
	public static class PlayerPositionWatcher
	{
		private static void Postfix(ref ZNet __instance, ZRpc rpc)
		{
			//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)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsServer())
			{
				return;
			}
			ZNetPeer peer = __instance.GetPeer(rpc);
			if (peer == null)
			{
				return;
			}
			Vector3 refPos = peer.m_refPos;
			int num = default(int);
			int num2 = default(int);
			Minimap.instance.WorldToPixel(refPos, ref num, ref num2);
			int num3 = (int)Mathf.Ceil(200f / Minimap.instance.m_pixelSize);
			for (int i = num2 - num3; i <= num2 + num3; i++)
			{
				for (int j = num - num3; j <= num + num3; j++)
				{
					if (j >= 0 && i >= 0 && j < Minimap.instance.m_textureSize && i < Minimap.instance.m_textureSize)
					{
						Vector2 val = new Vector2((float)(j - num), (float)(i - num2));
						if ((double)((Vector2)(ref val)).magnitude <= (double)num3)
						{
							MapSync.ServerMapData[i * Minimap.instance.m_textureSize + j] = true;
						}
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	public static class Player_OnSpawned_Patch
	{
		private static void Prefix(ref Player __instance)
		{
			MapSync.SendMapToServer();
			MapSync.ShouldSyncOnSpawn = false;
		}
	}
	public class DisplayCartsAndBoatsOnMap
	{
		[HarmonyPatch(typeof(Minimap), "OnDestroy")]
		public static class Minimap_OnDestroy_Patch
		{
			private static void Postfix()
			{
				customPins.Clear();
				icons.Clear();
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdateMap")]
		public static class Minimap_UpdateMap_Patch
		{
			private static float timeCounter = updateInterval;

			private static void FindIcons()
			{
				GameObject val = ObjectDB.instance.m_itemByHash[hammerHashCode];
				if (!Object.op_Implicit((Object)(object)val))
				{
					return;
				}
				ItemDrop component = val.GetComponent<ItemDrop>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					return;
				}
				PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces;
				foreach (GameObject piece in buildPieces.m_pieces)
				{
					Piece component2 = piece.GetComponent<Piece>();
					icons.Add(StringExtensionMethods.GetStableHashCode(((Object)component2).name), component2.m_icon);
				}
			}

			private static bool CheckPin(Minimap __instance, Player player, ZDO zdo, int hashCode, string pinName)
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				if (zdo.m_prefab != hashCode)
				{
					return false;
				}
				PinData value;
				bool flag = customPins.TryGetValue(zdo, out value);
				Ship controlledShip = player.GetControlledShip();
				if (Object.op_Implicit((Object)(object)controlledShip) && Vector3.Distance(((Component)controlledShip).transform.position, zdo.m_position) < 0.01f)
				{
					if (flag)
					{
						__instance.RemovePin(value);
						customPins.Remove(zdo);
					}
					return true;
				}
				if (!flag)
				{
					value = __instance.AddPin(zdo.m_position, (PinType)4, pinName, false, false, 0L, "");
					if (icons.TryGetValue(hashCode, out var value2))
					{
						value.m_icon = value2;
					}
					value.m_doubleSize = true;
					customPins.Add(zdo, value);
				}
				else
				{
					value.m_pos = zdo.m_position;
				}
				return true;
			}

			public static void Postfix(ref Minimap __instance, Player player, float dt, bool takeInput)
			{
				timeCounter += dt;
				if (timeCounter < updateInterval)
				{
					return;
				}
				timeCounter -= updateInterval;
				if (icons.Count == 0)
				{
					FindIcons();
				}
				List<ZDO>[] objectsBySector = ZDOMan.instance.m_objectsBySector;
				foreach (List<ZDO> list in objectsBySector)
				{
					if (list == null)
					{
						continue;
					}
					foreach (ZDO item in list)
					{
						for (int j = 0; j < HashCodes.Length && !CheckPin(__instance, player, item, HashCodes[j], PinNames[j]); j++)
						{
						}
					}
				}
				List<ZDO> list2 = new List<ZDO>();
				foreach (KeyValuePair<ZDO, PinData> customPin in customPins)
				{
					if (!customPin.Key.IsValid())
					{
						__instance.RemovePin(customPin.Value);
						list2.Add(customPin.Key);
					}
				}
				foreach (ZDO item2 in list2)
				{
					customPins.Remove(item2);
				}
			}
		}

		private static Dictionary<ZDO, PinData> customPins = new Dictionary<ZDO, PinData>();

		private static Dictionary<int, Sprite> icons = new Dictionary<int, Sprite>();

		private static int[] HashCodes = new int[4]
		{
			StringExtensionMethods.GetStableHashCode("Cart"),
			StringExtensionMethods.GetStableHashCode("Raft"),
			StringExtensionMethods.GetStableHashCode("Karve"),
			StringExtensionMethods.GetStableHashCode("VikingShip")
		};

		private static string[] PinNames = new string[4] { "Cart", "Raft", "Karve", "Longship" };

		private static int hammerHashCode = StringExtensionMethods.GetStableHashCode("Hammer");

		private static float updateInterval = 5f;
	}
	public class Network
	{
		[HarmonyPatch(typeof(ZSteamSocket), "RegisterGlobalCallbacks")]
		private static class IncreaseSendingLimit
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				foreach (CodeInstruction instruction in instructions)
				{
					if (instruction.opcode == OpCodes.Ldc_I4 && CodeInstructionExtensions.OperandIs(instruction, (object)153600))
					{
						instruction.operand = 50000000;
					}
					yield return instruction;
				}
			}

			private static void Postfix()
			{
				if (!(CSteamAPIContext.GetSteamClient() != IntPtr.Zero))
				{
					return;
				}
				GCHandle gCHandle = default(GCHandle);
				try
				{
					gCHandle = GCHandle.Alloc(100000000, GCHandleType.Pinned);
					SteamNetworkingUtils.SetConfigValue((ESteamNetworkingConfigValue)9, (ESteamNetworkingConfigScope)1, IntPtr.Zero, (ESteamNetworkingConfigDataType)1, gCHandle.AddrOfPinnedObject());
				}
				finally
				{
					if (gCHandle.IsAllocated)
					{
						gCHandle.Free();
					}
				}
			}
		}

		private const int NewLimit = 50000000;

		private const int BufferSize = 100000000;
	}
	[HarmonyPatch(typeof(EnvMan), "SetEnv")]
	public static class EnvMan_SetEnv_Patch
	{
		private const float NightBrightnessMultiplier = 1.5f;

		private static void Prefix(ref EnvMan __instance, ref EnvSetup env)
		{
			env.m_fogDensityNight = 0f;
			env.m_fogDensityMorning = 0f;
			env.m_fogDensityEvening = 0f;
			ApplyEnvModifier(env);
		}

		private static void ApplyEnvModifier(EnvSetup env)
		{
			//IL_0003: 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)
			//IL_0012: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			env.m_ambColorNight = ApplyBrightnessModifier(env.m_ambColorNight, 1.5f);
			env.m_fogColorNight = ApplyBrightnessModifier(env.m_fogColorNight, 1.5f);
			env.m_fogColorSunNight = ApplyBrightnessModifier(env.m_fogColorSunNight, 1.5f);
			env.m_sunColorNight = ApplyBrightnessModifier(env.m_sunColorNight, 1.5f);
		}

		private static Color ApplyBrightnessModifier(Color color, float multiplier)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 =