Decompiled source of Locked Cargo v0.3.1

LockedCargo.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using LockedCargo.Compat;
using LockedCargo.Patches;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LockedCargo")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.1.0")]
[assembly: AssemblyInformationalVersion("0.3.1+57226de7cf6fdc47e0677e11e91a98f72110a81c")]
[assembly: AssemblyProduct("LockedCargo")]
[assembly: AssemblyTitle("LockedCargo")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was fully created with generative AI assistance (Claude Code by Anthropic).")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")]
[assembly: AssemblyMetadata("AI_Model", "Claude Opus 5.5 (Claude Code, all code); Claude Opus and Claude Sonnet review subagents (versions not recorded)")]
[assembly: AssemblyVersion("0.3.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LockedCargo
{
	[BepInPlugin("kim.homebrew.lockedcargo", "Locked Cargo", "0.3.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class LockedCargoPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "kim.homebrew.lockedcargo";

		public const string PluginName = "Locked Cargo";

		public const string PluginVersion = "0.3.1";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Settings.Bind(((BaseUnityPlugin)this).Config);
			Texts.Register();
			_harmony = new Harmony("kim.homebrew.lockedcargo");
			_harmony.PatchAll(typeof(LockedCargoPlugin).Assembly);
			IndirectAccessCompat.Apply(_harmony);
			WardPrecedenceCompat.Apply(_harmony);
			Log.LogInfo((object)"Locked Cargo 0.3.1 loaded");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class Settings
	{
		internal const string SectionGeneral = "1 - General";

		internal const string KeyAdminBypass = "Admins bypass ship locks";

		internal const string DescAdminBypass = "When on, server admins (and the host of a locally hosted game) can use, lock and unlock every ship. Turn off to test the lock as a normal player: admins then need to be the owner or on the ship's list, like everyone else.";

		internal static ConfigEntry<bool> AdminBypass;

		internal static void Bind(ConfigFile config)
		{
			AdminBypass = ConfigFileExtensions.BindConfig<bool>(config, "1 - General", "Admins bypass ship locks", true, "When on, server admins (and the host of a locally hosted game) can use, lock and unlock every ship. Turn off to test the lock as a normal player: admins then need to be the owner or on the ship's list, like everyone else.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}
	}
	internal static class ShipAlt
	{
		internal static void Handle(Ship ship, Player player, Vector3 position)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			long playerID = player.GetPlayerID();
			long owner = ShipLock.GetOwner(ship);
			bool flag = ShipLock.IsLocked(ship);
			if ((owner == 0L || (playerID != owner && !ShipLock.LocalAdminBypass())) && !PrivateArea.CheckAccess(position, 0f, true, false))
			{
				((Character)player).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false);
			}
			else if (owner == 0L)
			{
				ShipLock.RequestClaim(ship, player);
				((Character)player).Message((MessageType)2, "$lockedcargo_msg_claimed", 0, (Sprite)null, false);
			}
			else if (playerID == owner || ShipLock.LocalAdminBypass())
			{
				ShipLock.RequestToggleLock(ship, player);
				((Character)player).Message((MessageType)2, flag ? "$lockedcargo_msg_unlocked" : "$lockedcargo_msg_locked", 0, (Sprite)null, false);
			}
			else if (flag)
			{
				ShipLock.Deny(ship, position, "$lockedcargo_msg_onlyowner");
			}
			else
			{
				bool flag2 = ShipLock.IsPermitted(ship, playerID);
				ShipLock.RequestTogglePermitted(ship, player);
				((Character)player).Message((MessageType)2, flag2 ? "$lockedcargo_msg_removed" : "$lockedcargo_msg_added", 0, (Sprite)null, false);
			}
		}
	}
	internal static class ShipLock
	{
		internal const string KeyInitialised = "lockedcargo_initialised";

		internal const string KeyLocked = "lockedcargo_locked";

		internal const string KeyClaimedOwner = "lockedcargo_owner";

		internal const string KeyOwnerName = "lockedcargo_ownername";

		internal const string KeyPermittedCount = "lockedcargo_permitted";

		internal const string KeyPermittedIdPrefix = "lockedcargo_pu_id";

		internal const string KeyPermittedNamePrefix = "lockedcargo_pu_name";

		internal const string RpcToggleLock = "LockedCargo_ToggleLock";

		internal const string RpcTogglePermitted = "LockedCargo_TogglePermitted";

		internal const string RpcClaim = "LockedCargo_Claim";

		internal const string RpcSetOwnerName = "LockedCargo_SetOwnerName";

		internal const string RpcFlash = "LockedCargo_Flash";

		private static readonly Dictionary<int, float> s_lastFlash = new Dictionary<int, float>();

		private static EffectList s_flashEffect;

		internal static bool AdminBypassEnabled
		{
			get
			{
				if (Settings.AdminBypass != null)
				{
					return Settings.AdminBypass.Value;
				}
				return true;
			}
		}

		internal static Ship FromContainer(Container container)
		{
			if (!Object.op_Implicit((Object)(object)container))
			{
				return null;
			}
			if (Object.op_Implicit((Object)(object)container.m_rootObjectOverride))
			{
				Ship component = ((Component)container.m_rootObjectOverride).GetComponent<Ship>();
				if (Object.op_Implicit((Object)(object)component))
				{
					return component;
				}
			}
			return ((Component)container).GetComponentInParent<Ship>();
		}

		internal static Ship FromPiece(Piece piece)
		{
			if (!Object.op_Implicit((Object)(object)piece))
			{
				return null;
			}
			Ship componentInChildren = ((Component)piece).GetComponentInChildren<Ship>();
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				return ((Component)piece).GetComponentInParent<Ship>();
			}
			return componentInChildren;
		}

		internal static bool HasCargo(Ship ship)
		{
			if (Object.op_Implicit((Object)(object)ship))
			{
				return Object.op_Implicit((Object)(object)((Component)ship).GetComponentInChildren<Container>());
			}
			return false;
		}

		internal static ZNetView NetView(Ship ship)
		{
			if (!Object.op_Implicit((Object)(object)ship))
			{
				return null;
			}
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
			{
				return null;
			}
			return component;
		}

		private static ZDO Zdo(Ship ship)
		{
			ZNetView val = NetView(ship);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetZDO();
		}

		internal static long GetOwner(Ship ship)
		{
			Piece val = (Object.op_Implicit((Object)(object)ship) ? ((Component)ship).GetComponent<Piece>() : null);
			long num = (Object.op_Implicit((Object)(object)val) ? val.GetCreator() : 0);
			if (num != 0L)
			{
				return num;
			}
			ZDO val2 = Zdo(ship);
			if (val2 == null)
			{
				return 0L;
			}
			return val2.GetLong("lockedcargo_owner", 0L);
		}

		internal static bool IsLocked(Ship ship)
		{
			ZDO val = Zdo(ship);
			if (val != null)
			{
				return val.GetBool("lockedcargo_locked", false);
			}
			return false;
		}

		internal static string GetOwnerName(Ship ship)
		{
			ZDO val = Zdo(ship);
			if (val == null)
			{
				return "";
			}
			return val.GetString("lockedcargo_ownername", "");
		}

		internal static List<KeyValuePair<long, string>> GetPermitted(Ship ship)
		{
			List<KeyValuePair<long, string>> list = new List<KeyValuePair<long, string>>();
			ZDO val = Zdo(ship);
			if (val == null)
			{
				return list;
			}
			int num = val.GetInt("lockedcargo_permitted", 0);
			for (int i = 0; i < num; i++)
			{
				long num2 = val.GetLong("lockedcargo_pu_id" + i, 0L);
				string value = val.GetString("lockedcargo_pu_name" + i, "");
				if (num2 != 0L)
				{
					list.Add(new KeyValuePair<long, string>(num2, value));
				}
			}
			return list;
		}

		internal static bool IsPermitted(Ship ship, long playerID)
		{
			foreach (KeyValuePair<long, string> item in GetPermitted(ship))
			{
				if (item.Key == playerID)
				{
					return true;
				}
			}
			return false;
		}

		internal static bool HasAccess(Ship ship, long playerID, bool isAdmin)
		{
			if (!IsLocked(ship) || isAdmin)
			{
				return true;
			}
			if (playerID == 0L)
			{
				return false;
			}
			if (playerID != GetOwner(ship))
			{
				return IsPermitted(ship, playerID);
			}
			return true;
		}

		internal static long LocalPlayerID()
		{
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return 0L;
			}
			return Player.m_localPlayer.GetPlayerID();
		}

		internal static bool LocalHasAccess(Ship ship)
		{
			return HasAccess(ship, LocalPlayerID(), LocalAdminBypass());
		}

		internal static bool HasShipPrecedence(Ship ship, long playerID, bool adminBypass)
		{
			if (!Object.op_Implicit((Object)(object)ship) || playerID == 0L)
			{
				return false;
			}
			if (adminBypass)
			{
				return true;
			}
			long owner = GetOwner(ship);
			if (owner != 0L)
			{
				if (playerID != owner)
				{
					return IsPermitted(ship, playerID);
				}
				return true;
			}
			return false;
		}

		internal static bool LocalDenied(Ship ship)
		{
			if (Object.op_Implicit((Object)(object)ship) && IsLocked(ship))
			{
				return !LocalHasAccess(ship);
			}
			return false;
		}

		internal static bool LocalAdminBypass()
		{
			if (AdminBypassEnabled)
			{
				return RawIsLocalAdmin();
			}
			return false;
		}

		internal static bool AdminBypassFor(long playerID, long senderUid)
		{
			if (AdminBypassEnabled)
			{
				return RawIsAdminPlayer(playerID, senderUid);
			}
			return false;
		}

		private static bool RawIsLocalAdmin()
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return ZNet.instance.LocalPlayerIsAdminOrHost();
			}
			return false;
		}

		private static bool RawIsAdminPlayer(long playerID, long senderUid)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			if ((senderUid == 0L || senderUid == ZNet.GetUID()) && playerID != 0L && playerID == LocalPlayerID())
			{
				return RawIsLocalAdmin();
			}
			if (instance.IsServer() && senderUid != 0L)
			{
				ZNetPeer peer = instance.GetPeer(senderUid);
				if (peer != null && peer.m_socket != null && instance.IsAdmin(peer.m_socket.GetHostName()))
				{
					return true;
				}
			}
			foreach (PlayerInfo player in instance.GetPlayerList())
			{
				ZDOID characterID;
				if (senderUid != 0L)
				{
					characterID = player.m_characterID;
					if (((ZDOID)(ref characterID)).UserID == senderUid)
					{
						goto IL_009f;
					}
				}
				if (playerID == 0L || CharacterPlayerID(player) != playerID)
				{
					continue;
				}
				goto IL_009f;
				IL_009f:
				characterID = player.m_characterID;
				return IsHostSession(((ZDOID)(ref characterID)).UserID) || instance.PlayerIsAdmin(player.m_userInfo.m_id);
			}
			return false;
		}

		private static bool IsHostSession(long sessionUid)
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || sessionUid == 0L)
			{
				return false;
			}
			if (instance.IsServer())
			{
				return sessionUid == ZNet.GetUID();
			}
			ZNetPeer serverPeer = instance.GetServerPeer();
			if (serverPeer != null)
			{
				return serverPeer.m_uid == sessionUid;
			}
			return false;
		}

		internal static long ResolvePlayerID(long senderUid)
		{
			//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_0038: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			if (senderUid == ZNet.GetUID())
			{
				return LocalPlayerID();
			}
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return 0L;
			}
			foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
			{
				ZDOID characterID = player.m_characterID;
				if (((ZDOID)(ref characterID)).UserID == senderUid)
				{
					return CharacterPlayerID(player);
				}
			}
			return 0L;
		}

		private static long CharacterPlayerID(PlayerInfo info)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (((ZDOID)(ref info.m_characterID)).IsNone() || ZDOMan.instance == null)
			{
				return 0L;
			}
			ZDO zDO = ZDOMan.instance.GetZDO(info.m_characterID);
			if (zDO == null)
			{
				return 0L;
			}
			return zDO.GetLong(ZDOVars.s_playerID, 0L);
		}

		internal static void RequestToggleLock(Ship ship, Player player)
		{
			ZNetView obj = NetView(ship);
			if (obj != null)
			{
				obj.InvokeRPC("LockedCargo_ToggleLock", new object[2]
				{
					player.GetPlayerID(),
					player.GetPlayerName()
				});
			}
		}

		internal static void RequestTogglePermitted(Ship ship, Player player)
		{
			ZNetView obj = NetView(ship);
			if (obj != null)
			{
				obj.InvokeRPC("LockedCargo_TogglePermitted", new object[2]
				{
					player.GetPlayerID(),
					player.GetPlayerName()
				});
			}
		}

		internal static void RequestClaim(Ship ship, Player player)
		{
			ZNetView obj = NetView(ship);
			if (obj != null)
			{
				obj.InvokeRPC("LockedCargo_Claim", new object[2]
				{
					player.GetPlayerID(),
					player.GetPlayerName()
				});
			}
		}

		internal static void RecordOwnerNameIfNeeded(Ship ship, Player player)
		{
			if (!Object.op_Implicit((Object)(object)ship) || !Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			long playerID = player.GetPlayerID();
			if (playerID != 0L && playerID == GetOwner(ship) && string.IsNullOrEmpty(GetOwnerName(ship)))
			{
				ZNetView obj = NetView(ship);
				if (obj != null)
				{
					obj.InvokeRPC("LockedCargo_SetOwnerName", new object[2]
					{
						playerID,
						player.GetPlayerName()
					});
				}
			}
		}

		internal static void InitialiseNewShip(Ship ship, Player placer)
		{
			ZNetView val = NetView(ship);
			if (Object.op_Implicit((Object)(object)val) && val.IsOwner() && Object.op_Implicit((Object)(object)placer))
			{
				ZDO zDO = val.GetZDO();
				zDO.Set("lockedcargo_initialised", true);
				zDO.Set("lockedcargo_locked", true);
				zDO.Set("lockedcargo_ownername", placer.GetPlayerName());
			}
		}

		internal static void Register(Ship ship)
		{
			ZNetView val = (Object.op_Implicit((Object)(object)ship) ? ((Component)ship).GetComponent<ZNetView>() : null);
			if (Object.op_Implicit((Object)(object)val) && val.GetZDO() != null)
			{
				val.Register<long, string>("LockedCargo_ToggleLock", (Action<long, long, string>)delegate(long sender, long playerID, string name)
				{
					OnToggleLock(ship, sender, playerID, name);
				});
				val.Register<long, string>("LockedCargo_TogglePermitted", (Action<long, long, string>)delegate(long sender, long playerID, string name)
				{
					OnTogglePermitted(ship, sender, playerID, name);
				});
				val.Register<long, string>("LockedCargo_Claim", (Action<long, long, string>)delegate(long sender, long playerID, string name)
				{
					OnClaim(ship, sender, playerID, name);
				});
				val.Register<long, string>("LockedCargo_SetOwnerName", (Action<long, long, string>)delegate(long sender, long playerID, string name)
				{
					OnSetOwnerName(ship, playerID, name);
				});
				val.Register<Vector3>("LockedCargo_Flash", (Action<long, Vector3>)delegate(long sender, Vector3 position)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					OnFlash(position);
				});
			}
		}

		private static bool OwnerSide(Ship ship, out ZDO zdo)
		{
			zdo = null;
			ZNetView val = NetView(ship);
			if (!Object.op_Implicit((Object)(object)val) || !val.IsOwner())
			{
				return false;
			}
			zdo = val.GetZDO();
			return zdo != null;
		}

		private static void OnToggleLock(Ship ship, long sender, long playerID, string name)
		{
			if (!OwnerSide(ship, out var zdo))
			{
				return;
			}
			long owner = GetOwner(ship);
			if (owner == 0L)
			{
				return;
			}
			bool flag = playerID == owner;
			if (!flag && !AdminBypassFor(playerID, sender))
			{
				LockedCargoPlugin.Log.LogInfo((object)("Refused lock toggle on " + ((Object)ship).name + " from player " + playerID));
				return;
			}
			if (flag && string.IsNullOrEmpty(GetOwnerName(ship)) && !string.IsNullOrEmpty(name))
			{
				zdo.Set("lockedcargo_ownername", name);
			}
			zdo.Set("lockedcargo_initialised", true);
			zdo.Set("lockedcargo_locked", !zdo.GetBool("lockedcargo_locked", false));
		}

		private static void OnTogglePermitted(Ship ship, long sender, long playerID, string name)
		{
			if (!OwnerSide(ship, out var zdo) || zdo.GetBool("lockedcargo_locked", false) || playerID == 0L)
			{
				return;
			}
			long owner = GetOwner(ship);
			if (owner != 0L && playerID != owner)
			{
				List<KeyValuePair<long, string>> permitted = GetPermitted(ship);
				if (permitted.RemoveAll((KeyValuePair<long, string> entry) => entry.Key == playerID) == 0)
				{
					permitted.Add(new KeyValuePair<long, string>(playerID, name));
				}
				SetPermitted(zdo, permitted);
			}
		}

		private static void OnClaim(Ship ship, long sender, long playerID, string name)
		{
			if (OwnerSide(ship, out var zdo) && playerID != 0L && GetOwner(ship) == 0L)
			{
				zdo.Set("lockedcargo_owner", playerID);
				zdo.Set("lockedcargo_ownername", name ?? "");
				zdo.Set("lockedcargo_initialised", true);
				zdo.Set("lockedcargo_locked", true);
			}
		}

		private static void OnSetOwnerName(Ship ship, long playerID, string name)
		{
			if (OwnerSide(ship, out var zdo) && !string.IsNullOrEmpty(name) && playerID != 0L && playerID == GetOwner(ship) && string.IsNullOrEmpty(zdo.GetString("lockedcargo_ownername", "")))
			{
				zdo.Set("lockedcargo_ownername", name);
			}
		}

		private static void SetPermitted(ZDO zdo, List<KeyValuePair<long, string>> list)
		{
			int num = zdo.GetInt("lockedcargo_permitted", 0);
			zdo.Set("lockedcargo_permitted", list.Count);
			for (int i = 0; i < list.Count; i++)
			{
				zdo.Set("lockedcargo_pu_id" + i, list[i].Key);
				zdo.Set("lockedcargo_pu_name" + i, list[i].Value ?? "");
			}
			for (int j = list.Count; j < num; j++)
			{
				zdo.Set("lockedcargo_pu_id" + j, 0L);
				zdo.Set("lockedcargo_pu_name" + j, "");
			}
		}

		internal static void Deny(Ship ship, Vector3 position, string message)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && !string.IsNullOrEmpty(message))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
			ZNetView val = NetView(ship);
			if (Object.op_Implicit((Object)(object)val))
			{
				int instanceID = ((Object)ship).GetInstanceID();
				if (!s_lastFlash.TryGetValue(instanceID, out var value) || !(Time.time - value < 1f))
				{
					s_lastFlash[instanceID] = Time.time;
					val.InvokeRPC(ZNetView.Everybody, "LockedCargo_Flash", new object[1] { position });
				}
			}
		}

		private static void OnFlash(Vector3 position)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			EffectList obj = FlashEffect();
			if (obj != null)
			{
				obj.Create(position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
		}

		private static EffectList FlashEffect()
		{
			if (s_flashEffect == null && Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("guard_stone");
				PrivateArea val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<PrivateArea>() : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					s_flashEffect = val.m_flashEffect;
				}
			}
			return s_flashEffect;
		}
	}
	internal static class Texts
	{
		internal const string GameNoAccess = "$piece_noaccess";

		internal const string GamePrivateZone = "$msg_privatezone";

		internal const string GameOwner = "$piece_guardstone_owner";

		internal const string GameAddMe = "$piece_guardstone_add";

		internal const string GameRemoveMe = "$piece_guardstone_remove";

		internal const string GamePermittedList = "$piece_guardstone_additional";

		internal const string StatusLocked = "$lockedcargo_status_locked";

		internal const string StatusUnlocked = "$lockedcargo_status_unlocked";

		internal const string UnknownOwner = "$lockedcargo_unknownowner";

		internal const string NoOwner = "$lockedcargo_noowner";

		internal const string ActionLock = "$lockedcargo_lock";

		internal const string ActionUnlock = "$lockedcargo_unlock";

		internal const string ActionClaim = "$lockedcargo_claim";

		internal const string MsgLocked = "$lockedcargo_msg_locked";

		internal const string MsgUnlocked = "$lockedcargo_msg_unlocked";

		internal const string MsgClaimed = "$lockedcargo_msg_claimed";

		internal const string MsgOnlyOwner = "$lockedcargo_msg_onlyowner";

		internal const string MsgAdded = "$lockedcargo_msg_added";

		internal const string MsgRemoved = "$lockedcargo_msg_removed";

		internal static readonly Dictionary<string, string> English = new Dictionary<string, string>
		{
			{ "lockedcargo_status_locked", "Ship: locked" },
			{ "lockedcargo_status_unlocked", "Ship: unlocked" },
			{ "lockedcargo_unknownowner", "Unknown owner" },
			{ "lockedcargo_noowner", "No owner" },
			{ "lockedcargo_lock", "Lock ship" },
			{ "lockedcargo_unlock", "Unlock ship" },
			{ "lockedcargo_claim", "Claim and lock ship" },
			{ "lockedcargo_msg_locked", "Ship locked" },
			{ "lockedcargo_msg_unlocked", "Ship unlocked" },
			{ "lockedcargo_msg_claimed", "You claimed this ship. It is now locked." },
			{ "lockedcargo_msg_onlyowner", "Only the owner can unlock this ship" },
			{ "lockedcargo_msg_added", "You can now use this ship when it is locked" },
			{ "lockedcargo_msg_removed", "You can no longer use this ship when it is locked" }
		};

		internal static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, English);
		}

		internal static string AltUseHint()
		{
			if (!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive())
			{
				return "$KEY_AltPlace + $KEY_Use";
			}
			return "$KEY_AltKeys + $KEY_Use";
		}

		internal static string OwnerDisplayName(Ship ship)
		{
			long owner = ShipLock.GetOwner(ship);
			if (owner == 0L)
			{
				return "$lockedcargo_noowner";
			}
			string ownerName = ShipLock.GetOwnerName(ship);
			if (string.IsNullOrEmpty(ownerName))
			{
				return "$lockedcargo_unknownowner";
			}
			return CensorShittyWords.FilterUGC(ownerName, (UGCType)2, owner);
		}

		internal static string AltAction(Ship ship)
		{
			long num = ShipLock.LocalPlayerID();
			long owner = ShipLock.GetOwner(ship);
			bool flag = ShipLock.IsLocked(ship);
			if (owner == 0L)
			{
				return "$lockedcargo_claim";
			}
			if (num == owner || ShipLock.LocalAdminBypass())
			{
				if (!flag)
				{
					return "$lockedcargo_lock";
				}
				return "$lockedcargo_unlock";
			}
			if (flag)
			{
				return null;
			}
			if (!ShipLock.IsPermitted(ship, num))
			{
				return "$piece_guardstone_add";
			}
			return "$piece_guardstone_remove";
		}

		internal static string StatusLines(Ship ship, bool withAction)
		{
			StringBuilder stringBuilder = new StringBuilder(128);
			stringBuilder.Append('\n').Append(ShipLock.IsLocked(ship) ? "$lockedcargo_status_locked" : "$lockedcargo_status_unlocked");
			stringBuilder.Append('\n').Append("$piece_guardstone_owner").Append(": ")
				.Append(OwnerDisplayName(ship));
			if (withAction)
			{
				string text = AltAction(ship);
				if (text != null)
				{
					stringBuilder.Append("\n[<color=yellow><b>").Append(AltUseHint()).Append("</b></color>] ")
						.Append(text);
				}
			}
			List<KeyValuePair<long, string>> permitted = ShipLock.GetPermitted(ship);
			if (permitted.Count > 0)
			{
				long owner = ShipLock.GetOwner(ship);
				stringBuilder.Append('\n').Append("$piece_guardstone_additional").Append(": ");
				for (int i = 0; i < permitted.Count; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(", ");
					}
					stringBuilder.Append(CensorShittyWords.FilterUGC(permitted[i].Value, (UGCType)2, owner));
				}
			}
			return stringBuilder.ToString();
		}
	}
}
namespace LockedCargo.Patches
{
	[HarmonyPatch(typeof(Container), "Interact")]
	[HarmonyPriority(900)]
	internal static class Container_Interact_ShipLock
	{
		private static bool Prefix(Container __instance, Humanoid character, bool hold, bool alt, ref bool __result)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (hold)
			{
				return true;
			}
			Player val = (Player)(object)((character is Player) ? character : null);
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			Ship val2 = ShipLock.FromContainer(__instance);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)ShipLock.NetView(val2)))
			{
				return true;
			}
			ShipLock.RecordOwnerNameIfNeeded(val2, val);
			if (alt)
			{
				ShipAlt.Handle(val2, val, ((Component)__instance).transform.position);
				__result = true;
				return false;
			}
			if (ShipLock.LocalDenied(val2))
			{
				ShipLock.Deny(val2, ((Component)__instance).transform.position, "$piece_noaccess");
				__result = true;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Container), "CheckAccess")]
	[HarmonyPriority(0)]
	internal static class Container_CheckAccess_ShipLock
	{
		private static void Postfix(Container __instance, long playerID, ref bool __result)
		{
			if (__result)
			{
				Ship val = ShipLock.FromContainer(__instance);
				if (Object.op_Implicit((Object)(object)val) && ShipLock.IsLocked(val) && !ShipLock.HasAccess(val, playerID, ShipLock.AdminBypassFor(playerID, 0L)))
				{
					__result = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Container), "GetHoverText")]
	[HarmonyPriority(200)]
	internal static class Container_GetHoverText_ShipLock
	{
		private static void Postfix(Container __instance, ref string __result)
		{
			Ship val = ShipLock.FromContainer(__instance);
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)ShipLock.NetView(val)) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				if (ShipLock.LocalDenied(val))
				{
					__result = Localization.instance.Localize(__instance.m_name + "\n$piece_noaccess");
				}
				__result += Localization.instance.Localize(Texts.StatusLines(val, withAction: true));
			}
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "GetHoverText")]
	[HarmonyPriority(200)]
	internal static class ShipControlls_GetHoverText_ShipLock
	{
		private static void Postfix(ShipControlls __instance, ref string __result)
		{
			Ship ship = __instance.m_ship;
			if (Object.op_Implicit((Object)(object)ship) && Object.op_Implicit((Object)(object)ShipLock.NetView(ship)) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				__result += Localization.instance.Localize(Texts.StatusLines(ship, withAction: true));
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Update")]
	internal static class InventoryGui_Update_CloseLockedCargo
	{
		private static void Postfix(InventoryGui __instance, Container ___m_currentContainer)
		{
			if (Object.op_Implicit((Object)(object)___m_currentContainer) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				Ship val = ShipLock.FromContainer(___m_currentContainer);
				if (Object.op_Implicit((Object)(object)val) && ShipLock.LocalDenied(val))
				{
					__instance.Hide();
				}
			}
		}
	}
	[HarmonyPatch(typeof(Ship), "Awake")]
	internal static class Ship_Awake_Register
	{
		private static void Postfix(Ship __instance)
		{
			ShipLock.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(Piece), "SetCreator")]
	internal static class Piece_SetCreator_InitialiseShip
	{
		private static void Postfix(Piece __instance, long uid)
		{
			if (uid == 0L || __instance.GetCreator() != uid)
			{
				return;
			}
			Ship component = ((Component)__instance).GetComponent<Ship>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Player localPlayer = Player.m_localPlayer;
				if (Object.op_Implicit((Object)(object)localPlayer) && localPlayer.GetPlayerID() == uid)
				{
					ShipLock.InitialiseNewShip(component, localPlayer);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Interact", new Type[]
	{
		typeof(GameObject),
		typeof(bool),
		typeof(bool)
	})]
	[HarmonyPriority(900)]
	internal static class Player_Interact_ShipLock
	{
		private static bool Prefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)go))
			{
				return true;
			}
			if (alt && !hold && TryHandleShipToggle(__instance, go))
			{
				return false;
			}
			if (!DeniedShipInteractable(go, out var ship))
			{
				return true;
			}
			if (!hold)
			{
				ShipLock.Deny(ship, go.transform.position, "$piece_noaccess");
			}
			return false;
		}

		private static bool TryHandleShipToggle(Player player, GameObject go)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (((Character)player).InAttack() || ((Character)player).InDodge())
			{
				return false;
			}
			Interactable componentInParent = go.GetComponentInParent<Interactable>();
			Ship val = null;
			Component val2 = null;
			Container val3 = (Container)(object)((componentInParent is Container) ? componentInParent : null);
			if (val3 != null)
			{
				val = ShipLock.FromContainer(val3);
				val2 = (Component)(object)val3;
			}
			else
			{
				ShipControlls val4 = (ShipControlls)(object)((componentInParent is ShipControlls) ? componentInParent : null);
				if (val4 != null)
				{
					val = val4.m_ship;
					val2 = (Component)(object)val4;
				}
			}
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)ShipLock.NetView(val)))
			{
				return false;
			}
			ShipLock.RecordOwnerNameIfNeeded(val, player);
			ShipAlt.Handle(val, player, val2.transform.position);
			return true;
		}

		internal static bool DeniedShipInteractable(GameObject go, out Ship ship)
		{
			ship = (Object.op_Implicit((Object)(object)go) ? go.GetComponentInParent<Ship>() : null);
			if (!Object.op_Implicit((Object)(object)ship) || !ShipLock.LocalDenied(ship))
			{
				return false;
			}
			Interactable componentInParent = go.GetComponentInParent<Interactable>();
			if (componentInParent != null && !(componentInParent is Chair) && !(componentInParent is Ladder) && !(componentInParent is ShipControlls))
			{
				return !(componentInParent is Container);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UseItem")]
	[HarmonyPriority(900)]
	internal static class Humanoid_UseItem_ShipLock
	{
		private static readonly FieldRef<Player, GameObject> Hovering = AccessTools.FieldRefAccess<Player, GameObject>("m_hovering");

		private static void Prefix(Humanoid __instance, bool fromInventoryGui, out GameObject __state)
		{
			__state = null;
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!fromInventoryGui && Object.op_Implicit((Object)(object)val) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
			{
				GameObject val2 = Hovering.Invoke(val);
				if (Player_Interact_ShipLock.DeniedShipInteractable(val2, out var _))
				{
					__state = val2;
					Hovering.Invoke(val) = null;
				}
			}
		}

		private static void Finalizer(Humanoid __instance, GameObject __state)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (Object.op_Implicit((Object)(object)__state) && Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)Hovering.Invoke(val)))
			{
				Hovering.Invoke(val) = __state;
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "TryUseItemOnInteractable")]
	[HarmonyPriority(900)]
	internal static class Humanoid_TryUseItemOnInteractable_ShipLock
	{
		private static bool Prefix(Humanoid __instance, GameObject hoverObject, bool fromInventoryGui)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (fromInventoryGui || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (!Player_Interact_ShipLock.DeniedShipInteractable(hoverObject, out var ship))
			{
				return true;
			}
			ShipLock.Deny(ship, hoverObject.transform.position, "$piece_noaccess");
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "RemovePiece")]
	[HarmonyPriority(900)]
	internal static class Player_RemovePiece_ShipLock
	{
		private static bool Prefix(Player __instance, ref bool __result, int ___m_removeRayMask)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)GameCamera.instance))
			{
				return true;
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(transform.position, transform.forward, ref val, 50f, ___m_removeRayMask) || Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)__instance).m_eye.position) >= __instance.m_maxPlaceDistance)
			{
				return true;
			}
			Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
			Ship val2 = ShipLock.FromPiece(componentInParent);
			if (!ShipLock.LocalDenied(val2))
			{
				if (Object.op_Implicit((Object)(object)val2) && ShipLock.HasShipPrecedence(val2, ShipLock.LocalPlayerID(), ShipLock.LocalAdminBypass()))
				{
					WardPrecedenceScope.Begin(((Component)componentInParent).transform.position);
				}
				return true;
			}
			ShipLock.Deny(val2, ((RaycastHit)(ref val)).point, "$msg_privatezone");
			__result = false;
			return false;
		}

		private static void Finalizer()
		{
			WardPrecedenceScope.End();
		}
	}
	[HarmonyPatch(typeof(Player), "Repair")]
	[HarmonyPriority(900)]
	internal static class Player_Repair_ShipLock
	{
		private static bool Prefix(Player __instance)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).InPlaceMode())
			{
				return true;
			}
			Piece hoveringPiece = __instance.GetHoveringPiece();
			Ship val = ShipLock.FromPiece(hoveringPiece);
			if (!ShipLock.LocalDenied(val))
			{
				if (Object.op_Implicit((Object)(object)val) && ShipLock.HasShipPrecedence(val, ShipLock.LocalPlayerID(), ShipLock.LocalAdminBypass()))
				{
					WardPrecedenceScope.Begin(((Component)hoveringPiece).transform.position);
				}
				return true;
			}
			ShipLock.Deny(val, ((Component)hoveringPiece).transform.position, "$msg_privatezone");
			return false;
		}

		private static void Finalizer()
		{
			WardPrecedenceScope.End();
		}
	}
	[HarmonyPatch(typeof(WearNTear), "RPC_Remove")]
	[HarmonyPriority(900)]
	internal static class WearNTear_RPC_Remove_ShipLock
	{
		private static bool Prefix(WearNTear __instance, long sender, ZNetView ___m_nview)
		{
			if (!Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsValid() || !___m_nview.IsOwner())
			{
				return true;
			}
			Ship val = ShipLock.FromPiece(((Component)__instance).GetComponent<Piece>());
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = ((Component)__instance).GetComponentInParent<Ship>();
			}
			if (!Object.op_Implicit((Object)(object)val) || !ShipLock.IsLocked(val))
			{
				return true;
			}
			long num = ShipLock.ResolvePlayerID(sender);
			if (num == 0L)
			{
				LockedCargoPlugin.Log.LogWarning((object)("Remove request for locked " + ((Object)val).name + " from unknown sender " + sender + "; allowed"));
				return true;
			}
			if (ShipLock.HasAccess(val, num, ShipLock.AdminBypassFor(num, sender)))
			{
				return true;
			}
			LockedCargoPlugin.Log.LogInfo((object)("Refused removal of locked " + ((Object)val).name + " by player " + num));
			return false;
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "Interact")]
	[HarmonyPriority(900)]
	internal static class ShipControlls_Interact_ShipLock
	{
		private static bool Prefix(ShipControlls __instance, Humanoid character, bool repeat, bool alt, ref bool __result)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (repeat)
			{
				return true;
			}
			Player val = (Player)(object)((character is Player) ? character : null);
			Ship ship = __instance.m_ship;
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)ship) || !Object.op_Implicit((Object)(object)ShipLock.NetView(ship)))
			{
				return true;
			}
			ShipLock.RecordOwnerNameIfNeeded(ship, val);
			if (alt)
			{
				ShipAlt.Handle(ship, val, ((Component)__instance).transform.position);
				__result = false;
				return false;
			}
			if (ShipLock.LocalDenied(ship))
			{
				ShipLock.Deny(ship, ((Component)__instance).transform.position, "$piece_noaccess");
				__result = false;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "ApplyControlls")]
	[HarmonyPriority(900)]
	internal static class ShipControlls_ApplyControlls_ShipLock
	{
		private static bool Prefix(ShipControlls __instance)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Ship ship = __instance.m_ship;
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)ship) || !ShipLock.LocalDenied(ship))
			{
				return true;
			}
			localPlayer.StopDoodadControl();
			ShipLock.Deny(ship, ((Component)__instance).transform.position, "$piece_noaccess");
			return false;
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "RPC_RequestControl")]
	[HarmonyPriority(900)]
	internal static class ShipControlls_RPC_RequestControl_ShipLock
	{
		private static bool Prefix(ShipControlls __instance, long sender, long playerID, ZNetView ___m_nview)
		{
			Ship ship = __instance.m_ship;
			if (!Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsValid() || !___m_nview.IsOwner() || !Object.op_Implicit((Object)(object)ship) || !ShipLock.IsLocked(ship))
			{
				return true;
			}
			if (ShipLock.HasAccess(ship, playerID, ShipLock.AdminBypassFor(playerID, sender)))
			{
				return true;
			}
			LockedCargoPlugin.Log.LogInfo((object)("Refused helm of locked " + ((Object)ship).name + " to player " + playerID));
			___m_nview.InvokeRPC(sender, "RequestRespons", new object[1] { false });
			return false;
		}
	}
}
namespace LockedCargo.Compat
{
	internal static class IndirectAccessCompat
	{
		internal const string HopperTargetType = "ValheimHopper.Logic.ContainerTarget";

		internal const string GorilaTrackerType = "GorilaChestMod.ContainerTracker";

		internal const string VillagerAIType = "VikingsVillage.VillagerAI";

		private static readonly FieldRef<Container, bool> InUse = AccessTools.FieldRefAccess<Container, bool>("m_inUse");

		private static readonly List<Container> s_markedInUse = new List<Container>();

		private static int s_villageDepth;

		internal static void Apply(Harmony harmony)
		{
			PatchHopper(harmony);
			PatchGorila(harmony);
			PatchVillage(harmony);
		}

		private static void PatchVillage(Harmony harmony)
		{
			Type type = AccessTools.TypeByName("VikingsVillage.VillagerAI");
			if (!(type == null))
			{
				Patch(harmony, type, "StockChest", "Village_Scope_Prefix", null, "Village_Scope_Finalizer");
				Patch(harmony, type, "Deposit", "Village_Scope_Prefix", null, "Village_Scope_Finalizer", new Type[2]
				{
					typeof(string),
					typeof(int)
				});
				Patch(harmony, type, "KilnChest", "Village_KilnChest_Prefix", "Village_ChestFinder_Postfix");
			}
		}

		private static bool Village_KilnChest_Prefix(Smelter s, ref Container __result)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)s))
			{
				return true;
			}
			Container val = null;
			float num = 36f;
			Collider[] array = Physics.OverlapSphere(((Component)s).transform.position, 6f);
			for (int i = 0; i < array.Length; i++)
			{
				Container componentInParent = ((Component)array[i]).GetComponentInParent<Container>();
				if (Object.op_Implicit((Object)(object)componentInParent) && componentInParent.GetInventory() != null && !LockedShipCargo(componentInParent))
				{
					Vector3 val2 = ((Component)componentInParent).transform.position - ((Component)s).transform.position;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						val = componentInParent;
					}
				}
			}
			__result = val;
			return false;
		}

		private static void Village_Scope_Prefix()
		{
			if (s_villageDepth++ > 0)
			{
				return;
			}
			foreach (IMonoUpdater instance in Ship.Instances)
			{
				Ship val = (Ship)(object)((instance is Ship) ? instance : null);
				if (!Object.op_Implicit((Object)(object)val) || !ShipLock.IsLocked(val))
				{
					continue;
				}
				Container[] componentsInChildren = ((Component)val).GetComponentsInChildren<Container>();
				foreach (Container val2 in componentsInChildren)
				{
					if (Object.op_Implicit((Object)(object)val2) && !InUse.Invoke(val2))
					{
						InUse.Invoke(val2) = true;
						s_markedInUse.Add(val2);
					}
				}
			}
		}

		private static void Village_Scope_Finalizer()
		{
			if (--s_villageDepth > 0)
			{
				return;
			}
			s_villageDepth = 0;
			foreach (Container item in s_markedInUse)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					InUse.Invoke(item) = false;
				}
			}
			s_markedInUse.Clear();
		}

		private static void Village_ChestFinder_Postfix(ref Container __result)
		{
			if (Object.op_Implicit((Object)(object)__result) && LockedShipCargo(__result))
			{
				__result = null;
			}
		}

		private static void PatchHopper(Harmony harmony)
		{
			Type type = AccessTools.TypeByName("ValheimHopper.Logic.ContainerTarget");
			if (!(type == null))
			{
				Patch(harmony, type, "GetItems", null, "Hopper_GetItems_Postfix");
				Patch(harmony, type, "CanAddItem", null, "Hopper_CanAddItem_Postfix");
				Patch(harmony, type, "AddItem", "Hopper_Skip_Prefix");
				Patch(harmony, type, "RemoveItem", "Hopper_Skip_Prefix");
			}
		}

		private static void PatchGorila(Harmony harmony)
		{
			Type type = AccessTools.TypeByName("GorilaChestMod.ContainerTracker");
			if (!(type == null))
			{
				Patch(harmony, type, "IsUsable", null, "Gorila_IsUsable_Postfix");
			}
		}

		private static void Patch(Harmony harmony, Type type, string method, string prefix = null, string postfix = null, string finalizer = null, Type[] args = null)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a7: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo methodInfo = AccessTools.Method(type, method, args, (Type[])null);
			if (methodInfo == null)
			{
				LockedCargoPlugin.Log.LogWarning((object)("Compat: " + type.FullName + "." + method + " not found; not patched"));
			}
			else
			{
				HarmonyMethod val = ((prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(IndirectAccessCompat), prefix, (Type[])null)
				{
					priority = 800
				});
				HarmonyMethod val2 = ((postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(IndirectAccessCompat), postfix, (Type[])null)
				{
					priority = 0
				});
				HarmonyMethod val3 = ((finalizer == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(IndirectAccessCompat), finalizer, (Type[])null));
				harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, val3, (HarmonyMethod)null);
				LockedCargoPlugin.Log.LogInfo((object)("Compat: patched " + type.FullName + "." + method));
			}
		}

		private static bool LockedShipCargo(object component)
		{
			Component val = (Component)((component is Component) ? component : null);
			Ship val2 = ShipLock.FromContainer(Object.op_Implicit((Object)(object)val) ? val.GetComponent<Container>() : null);
			if (Object.op_Implicit((Object)(object)val2))
			{
				return ShipLock.IsLocked(val2);
			}
			return false;
		}

		private static void Hopper_GetItems_Postfix(object __instance, ref IEnumerable<ItemData> __result)
		{
			if (LockedShipCargo(__instance))
			{
				__result = Enumerable.Empty<ItemData>();
			}
		}

		private static void Hopper_CanAddItem_Postfix(object __instance, ref bool __result)
		{
			if (__result && LockedShipCargo(__instance))
			{
				__result = false;
			}
		}

		private static bool Hopper_Skip_Prefix(object __instance)
		{
			return !LockedShipCargo(__instance);
		}

		private static void Gorila_IsUsable_Postfix(Container container, long playerId, ref bool __result)
		{
			if (__result)
			{
				Ship val = ShipLock.FromContainer(container);
				if (Object.op_Implicit((Object)(object)val) && ShipLock.IsLocked(val) && !ShipLock.HasAccess(val, playerId, ShipLock.AdminBypassFor(playerId, 0L)))
				{
					__result = false;
				}
			}
		}
	}
	internal static class WardPrecedenceCompat
	{
		internal const string ProtectiveWardsType = "ProtectiveWards.ProtectiveWards";

		internal const string ExemptionMethod = "IsObjectOwnedByPlayerWithWardAccess";

		internal const string BackgroundProtectionType = "ProtectiveWards.BackgroundProtection";

		internal const string BuildingRestrictedMethod = "IsBuildingRestricted";

		internal static void Apply(Harmony harmony)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("ProtectiveWards.ProtectiveWards");
			if (type == null)
			{
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "IsObjectOwnedByPlayerWithWardAccess", new Type[2]
			{
				typeof(Component),
				typeof(Player)
			}, (Type[])null);
			if (methodInfo == null)
			{
				LockedCargoPlugin.Log.LogWarning((object)"Compat: ProtectiveWards.ProtectiveWards.IsObjectOwnedByPlayerWithWardAccess not found; not patched");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(WardPrecedenceCompat), "Exemption_Postfix", (Type[])null)
			{
				priority = 0
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			LockedCargoPlugin.Log.LogInfo((object)"Compat: patched ProtectiveWards.ProtectiveWards.IsObjectOwnedByPlayerWithWardAccess");
			Type type2 = AccessTools.TypeByName("ProtectiveWards.BackgroundProtection");
			MethodInfo methodInfo2 = ((type2 != null) ? AccessTools.Method(type2, "IsBuildingRestricted", new Type[2]
			{
				typeof(Player),
				typeof(Vector3)
			}, (Type[])null) : null);
			if (methodInfo2 == null)
			{
				LockedCargoPlugin.Log.LogWarning((object)"Compat: ProtectiveWards.BackgroundProtection.IsBuildingRestricted not found; not patched");
				return;
			}
			harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(WardPrecedenceCompat), "BuildingRestricted_Postfix", (Type[])null)
			{
				priority = 0
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			LockedCargoPlugin.Log.LogInfo((object)"Compat: patched ProtectiveWards.BackgroundProtection.IsBuildingRestricted");
		}

		private static void BuildingRestricted_Postfix(Vector3 point, ref bool __result)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (__result && WardPrecedenceScope.MatchesHammerPoint(point))
			{
				__result = false;
			}
		}

		private static void Exemption_Postfix(Component component, Player interactingPlayer, ref bool __result)
		{
			if (__result || !Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)interactingPlayer))
			{
				return;
			}
			Ship val = component.GetComponentInParent<Ship>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				ShipControlls componentInParent = component.GetComponentInParent<ShipControlls>();
				val = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.m_ship : null);
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				long playerID = interactingPlayer.GetPlayerID();
				if (ShipLock.HasShipPrecedence(val, playerID, ShipLock.AdminBypassFor(playerID, 0L)))
				{
					__result = true;
				}
			}
		}
	}
	internal static class WardPrecedenceScope
	{
		private static bool s_active;

		private static Vector3 s_point;

		internal static void Begin(Vector3 point)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			s_active = true;
			s_point = point;
		}

		internal static void End()
		{
			s_active = false;
		}

		internal static bool MatchesHammerPoint(Vector3 point)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (s_active)
			{
				Vector3 val = point - s_point;
				return ((Vector3)(ref val)).sqrMagnitude <= 0.0001f;
			}
			return false;
		}

		internal static bool Matches(Vector3 point, float radius)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (radius != 0f)
			{
				return false;
			}
			if (s_active)
			{
				Vector3 val = point - s_point;
				if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f)
				{
					return true;
				}
			}
			return ShipPartScope.Matches(point);
		}
	}
	internal static class ShipPartScope
	{
		private const float MaxPartDistance = 25f;

		private static Ship s_ship;

		private static Ship s_deniedShip;

		private static int s_depth;

		internal static void Begin(GameObject target)
		{
			s_depth++;
			if (!Object.op_Implicit((Object)(object)s_ship) && !Object.op_Implicit((Object)(object)s_deniedShip) && Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				Ship val = target.GetComponentInParent<Ship>();
				if (!Object.op_Implicit((Object)(object)val))
				{
					ShipControlls componentInParent = target.GetComponentInParent<ShipControlls>();
					val = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.m_ship : null);
				}
				Ship ship;
				if (Object.op_Implicit((Object)(object)val) && ShipLock.HasShipPrecedence(val, ShipLock.LocalPlayerID(), ShipLock.LocalAdminBypass()))
				{
					s_ship = val;
				}
				else if (Player_Interact_ShipLock.DeniedShipInteractable(target, out ship))
				{
					s_deniedShip = ship;
				}
			}
		}

		internal static void End()
		{
			if (--s_depth <= 0)
			{
				s_depth = 0;
				s_ship = null;
				s_deniedShip = null;
			}
		}

		internal static bool Matches(Vector3 point)
		{
			//IL_000c: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)s_ship))
			{
				Vector3 val = point - ((Component)s_ship).transform.position;
				return ((Vector3)(ref val)).sqrMagnitude <= 625f;
			}
			return false;
		}

		internal static bool DeniedMatches(Vector3 point)
		{
			//IL_000c: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)s_deniedShip))
			{
				Vector3 val = point - ((Component)s_deniedShip).transform.position;
				return ((Vector3)(ref val)).sqrMagnitude <= 625f;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
	internal static class Hud_UpdateCrosshair_ShipPartScope
	{
		private static void Prefix(Player player)
		{
			ShipPartScope.Begin(Object.op_Implicit((Object)(object)player) ? ((Humanoid)player).GetHoverObject() : null);
		}

		private static void Finalizer()
		{
			ShipPartScope.End();
		}
	}
	[HarmonyPatch(typeof(Player), "Interact", new Type[]
	{
		typeof(GameObject),
		typeof(bool),
		typeof(bool)
	})]
	internal static class Player_Interact_ShipPartScope
	{
		[HarmonyPriority(1000)]
		private static void Prefix(Player __instance, GameObject go)
		{
			ShipPartScope.Begin(((Object)(object)__instance == (Object)(object)Player.m_localPlayer) ? go : null);
		}

		private static void Finalizer()
		{
			ShipPartScope.End();
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UseItem")]
	internal static class Humanoid_UseItem_ShipPartScope
	{
		[HarmonyPriority(1000)]
		private static void Prefix(Humanoid __instance)
		{
			ShipPartScope.Begin(((Object)(object)__instance == (Object)(object)Player.m_localPlayer) ? __instance.GetHoverObject() : null);
		}

		private static void Finalizer()
		{
			ShipPartScope.End();
		}
	}
	[HarmonyPatch(typeof(Humanoid), "TryUseItemOnInteractable")]
	internal static class Humanoid_TryUseItemOnInteractable_ShipPartScope
	{
		[HarmonyPriority(1000)]
		private static void Prefix(Humanoid __instance, GameObject hoverObject)
		{
			ShipPartScope.Begin(((Object)(object)__instance == (Object)(object)Player.m_localPlayer) ? hoverObject : null);
		}

		private static void Finalizer()
		{
			ShipPartScope.End();
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "CheckAccess")]
	internal static class PrivateArea_CheckAccess_ShipPrecedence
	{
		[HarmonyPriority(900)]
		private static void Prefix(Vector3 point, float radius, ref bool flash)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (WardPrecedenceScope.Matches(point, radius))
			{
				flash = false;
			}
		}

		[HarmonyPriority(0)]
		private static void Postfix(Vector3 point, float radius, ref bool __result)
		{
			//IL_0004: 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)
			if (!__result && WardPrecedenceScope.Matches(point, radius))
			{
				__result = true;
			}
			else if (__result && radius == 0f && ShipPartScope.DeniedMatches(point))
			{
				__result = false;
			}
		}
	}
}