Decompiled source of ValheimRAFT v2.5.3

plugins\DynamicLocations.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using DynamicLocations.API;
using DynamicLocations.Commands;
using DynamicLocations.Config;
using DynamicLocations.Constants;
using DynamicLocations.Controllers;
using DynamicLocations.Patches;
using DynamicLocations.Structs;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using ZdoWatcher;
using Zolantris.Shared.Debug;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DynamicLocations")]
[assembly: AssemblyDescription("Valheim Mod made to attach to an item/prefab such as a bed and place a player or object near the item wherever it is in the current game. Meant for ValheimVehicles but could be used for any movement mod. Requires Jotunn and ZdoWatcher")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Virtualize LLC")]
[assembly: AssemblyProduct("DynamicLocations")]
[assembly: AssemblyCopyright("Copyright © 2023-2024, GNU-v3 licensed")]
[assembly: Guid("6015B165-2627-40A7-8CA1-3E6B6CD7CB49")]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DynamicLocations
{
	internal class ZdoWatcherDelegate
	{
		public static readonly int DynamicLocationSpawn = StringExtensionMethods.GetStableHashCode("DynamicLocation_Spawn");

		public static readonly int DynamicLocationLogout = StringExtensionMethods.GetStableHashCode("DynamicLocation_Logout");

		public static Dictionary<int, ZDOID> DynamicSpawns;

		public void RegisterToZdoManager()
		{
			ZdoWatchController.OnDeserialize = (Action<ZDO>)Delegate.Combine(ZdoWatchController.OnDeserialize, new Action<ZDO>(OnZdoRegister));
			ZdoWatchController.OnLoad = (Action<ZDO>)Delegate.Combine(ZdoWatchController.OnLoad, new Action<ZDO>(OnZdoRegister));
		}

		private static void OnZdoRegister(ZDO zdo)
		{
		}

		public static void OnZdoUnRegister(ZDO zdo)
		{
		}
	}
	[BepInPlugin("zolantris.DynamicLocations", "DynamicLocations", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class DynamicLocationsPlugin : BaseUnityPlugin
	{
		public const string Author = "zolantris";

		public const string Version = "1.2.0";

		public const string ModName = "DynamicLocations";

		public const string BepInGuid = "zolantris.DynamicLocations";

		private static Harmony _harmony;

		public const string ModDescription = "Valheim Mod made to attach to an item/prefab such as a bed and place a player or object near the item wherever it is in the current game. Meant for ValheimVehicles but could be used for any movement mod. Requires Jotunn and ZdoWatcher";

		public const string CopyRight = "Copyright © 2023-2024, GNU-v3 licensed";

		public static string HarmonyGuid => "zolantris.DynamicLocations";

		public void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			DynamicLocationsConfig.BindConfig(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony(HarmonyGuid);
			_harmony.PatchAll(typeof(DynamicLocationsPatches));
			RegisterCommands();
		}

		public void RegisterCommands()
		{
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new DynamicLocationsCommands());
		}
	}
}
namespace DynamicLocations.Structs
{
	public struct DynamicLocation
	{
		public Tuple<int, int> zoneId;

		public Tuple<float, float, float> position;

		public LocationVariation locationType;
	}
	public struct IntegrationConfig
	{
		public string ZdoTargetTargetPrefabName { get; private set; }

		public string Guid { get; set; }

		public string Version { get; set; }

		public string Name { get; set; }

		public BaseUnityPlugin Plugin { get; set; }

		public bool UseDefaultCallbacks { get; set; }

		public int MovementTimeout { get; set; }

		public bool ShouldFreezePlayer { get; set; }

		public int LoginPrefabHashCode { get; set; }

		public int Priority { get; set; }

		public List<string> RunBeforePlugins { get; }

		public List<string> RunAfterPlugins { get; }

		[UsedImplicitly]
		public IntegrationConfig()
		{
			UseDefaultCallbacks = false;
			MovementTimeout = 0;
			ShouldFreezePlayer = false;
			LoginPrefabHashCode = 0;
			Priority = 999;
			RunBeforePlugins = new List<string>();
			RunAfterPlugins = new List<string>();
			throw new Exception("This constructor is not supported, please provide plugin and zdoTargetPrefabName");
		}

		public IntegrationConfig(BaseUnityPlugin plugin, string zdoTargetPrefabName)
		{
			UseDefaultCallbacks = false;
			MovementTimeout = 0;
			ShouldFreezePlayer = false;
			LoginPrefabHashCode = 0;
			Priority = 999;
			RunBeforePlugins = new List<string>();
			RunAfterPlugins = new List<string>();
			Plugin = plugin;
			ZdoTargetTargetPrefabName = zdoTargetPrefabName;
			LoginPrefabHashCode = zdoTargetPrefabName.GetHashCode();
			Name = plugin.Info.Metadata.Name;
			Version = plugin.Info.Metadata.Version.ToString();
			Guid = plugin.Info.Metadata.GUID;
			Logger.LogDebug((object)$"PluginVersion: {plugin.Info.Metadata.Version} stringVersion {Version}, Name: {Name}");
		}
	}
}
namespace DynamicLocations.Prefabs
{
	public class DynamicPointPrefab
	{
		public static readonly DynamicPointPrefab Instance = new DynamicPointPrefab();

		public void Register(PrefabManager prefabManager, PieceManager pieceManager)
		{
			prefabManager.CreateEmptyPrefab("DynamicLocations_Prefabs_SpawnPoint", true).layer = LayerMask.NameToLayer("piece");
		}
	}
	public static class PrefabNames
	{
		private const string ModNamePrefix = "DynamicLocations_Prefabs";

		public const string SpawnPoint = "DynamicLocations_Prefabs_SpawnPoint";
	}
}
namespace DynamicLocations.Patches
{
	public class DynamicLocationsPatches
	{
		[HarmonyPatch(typeof(Bed), "Interact")]
		[HarmonyPostfix]
		private static void OnSpawnPointUpdated(Bed __instance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Game.instance.GetPlayerProfile().GetCustomSpawnPoint();
			if (((Character)Player.m_localPlayer).InInterior())
			{
				if (DynamicLocationsConfig.IsDebug)
				{
					Logger.LogDebug((object)"Cannot dynamic spawn inside dungeon or building. InIniterior returned true, must skip.");
				}
				return;
			}
			PlayerSpawnController instance = PlayerSpawnController.Instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				instance?.SyncBedSpawnPoint(__instance.m_nview.GetZDO(), __instance);
			}
		}

		[HarmonyPatch(typeof(Player), "OnDeath")]
		[HarmonyPostfix]
		private static void OnDeathDestroyLogoutPoint(Player __instance)
		{
			if (((Character)__instance).m_nview.IsOwner())
			{
				LocationController.RemoveZdoTarget(LocationVariation.Logout, __instance);
			}
		}

		[HarmonyPatch(typeof(Player), "ShowTeleportAnimation")]
		[HarmonyPostfix]
		private static void ShowTeleportAnimation(bool __result)
		{
			PlayerSpawnController? instance = PlayerSpawnController.Instance;
			if (instance != null && instance.IsTeleportingToDynamicLocation)
			{
				__result = false;
			}
		}

		[HarmonyPatch(typeof(Game), "Awake")]
		[HarmonyPostfix]
		private static void AddSpawnController(Game __instance)
		{
			Logger.LogDebug((object)"Game Awake called and added PlayerSpawnController and LocationController");
			((Component)__instance).gameObject.AddComponent<LocationController>();
			((Component)__instance).gameObject.AddComponent<PlayerSpawnController>();
		}

		[HarmonyPatch(typeof(Game), "OnDestroy")]
		[HarmonyPostfix]
		private static void ResetSpawnController(Game __instance)
		{
			Logger.LogDebug((object)"Game destroy called ResetSpawnController");
			LocationController.ResetCachedValues();
		}

		[HarmonyPatch(typeof(Game), "SpawnPlayer")]
		[HarmonyPostfix]
		private static void OnSpawned(Game __instance, Player __result)
		{
			if (!ZNetView.m_forceDisableInit)
			{
				if (__instance.m_respawnAfterDeath && DynamicLocationsConfig.EnableDynamicSpawnPoint.Value && !((Character)__result).InIntro())
				{
					PlayerSpawnController.Instance?.MovePlayerToSpawnPoint();
				}
				else if (DynamicLocationsConfig.EnableDynamicLogoutPoint.Value && !((Character)__result).InInterior() && !((Character)__result).InIntro())
				{
					PlayerSpawnController.Instance?.MovePlayerToLogoutPoint();
				}
			}
		}
	}
}
namespace DynamicLocations.Interfaces
{
	internal interface IModLoginAPI
	{
		BaseUnityPlugin Plugin { get; set; }

		bool UseDefaultCallbacks { get; }

		int MovementTimeout { get; }

		bool ShouldFreezePlayer { get; }

		int LoginPrefabHashCode { get; }

		int Priority { get; }

		List<string> RunBeforePlugins { get; }

		List<string> RunAfterPlugins { get; }

		IEnumerator OnLoginMoveToZDO(ZDO zdo, Vector3? offset, PlayerSpawnController playerSpawnController);

		bool OnLoginMatchZdoPrefab(ZDO zdo);
	}
	public interface IVehiclePiecesController
	{
		bool IsActivationComplete { get; }
	}
}
namespace DynamicLocations.Controllers
{
	public interface ICachedLocation
	{
		Vector3? Offset { get; set; }

		ZDO Zdo { get; set; }
	}
	public class CacheLocationItem : ICachedLocation
	{
		public Vector3? Offset { get; set; }

		public ZDO Zdo { get; set; }
	}
	public class LocationController : MonoBehaviour
	{
		private const string DynamicPrefix = "Dynamic";

		private const string SpawnZdoPrefix = "SpawnZdo";

		private const string SpawnZdoOffsetPrefix = "SpawnZdoOffset";

		private const string LogoutParentZdoOffsetPrefix = "LogoutParentZdoOffset";

		private const string LogoutParentZdoPrefix = "LogoutParentZdo";

		private static Dictionary<LocationVariation, ICachedLocation> _cachedLocations = new Dictionary<LocationVariation, ICachedLocation>();

		public static LocationController Instance;

		internal static long WorldIdOverride = 0L;

		private static long CurrentWorldId
		{
			get
			{
				if (WorldIdOverride == 0L)
				{
					ZNet instance = ZNet.instance;
					if (instance == null)
					{
						return 0L;
					}
					return instance.GetWorldUID();
				}
				return WorldIdOverride;
			}
		}

		public void Awake()
		{
			Instance = this;
		}

		public void OnDestroy()
		{
			_cachedLocations.Clear();
		}

		public static ICachedLocation? GetCachedDynamicLocation(LocationVariation locationVariationType)
		{
			_cachedLocations.TryGetValue(locationVariationType, out ICachedLocation value);
			return value;
		}

		public static bool SetCachedDynamicLocation(LocationVariation locationVariationType, CacheLocationItem cachedLocationItem)
		{
			if (GetCachedDynamicLocation(locationVariationType) != null)
			{
				_cachedLocations[locationVariationType] = cachedLocationItem;
			}
			else
			{
				_cachedLocations.Add(locationVariationType, cachedLocationItem);
			}
			return true;
		}

		public static string GetPluginPrefix()
		{
			return "DynamicLocations";
		}

		public static string GetFullPrefix()
		{
			return GetPluginPrefix() + "_Dynamic";
		}

		public static string GetLogoutZdoOffsetKey()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return string.Format("{0}_{1}_{2}", GetFullPrefix(), "LogoutParentZdoOffset", CurrentWorldId);
			}
			return "";
		}

		public static string GetLogoutZdoKey()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return string.Format("{0}_{1}_{2}", GetFullPrefix(), "LogoutParentZdo", CurrentWorldId);
			}
			return "";
		}

		public static string GetSpawnZdoOffsetKey()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return string.Format("{0}_{1}_{2}", GetFullPrefix(), "SpawnZdoOffset", CurrentWorldId);
			}
			return "";
		}

		public static string GetSpawnZdoKey()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return string.Format("{0}_{1}_{2}", GetFullPrefix(), "SpawnZdo", CurrentWorldId);
			}
			return "";
		}

		private static string ZDOIDToString(ZDOID zdoid)
		{
			long userID = ((ZDOID)(ref zdoid)).UserID;
			uint iD = ((ZDOID)(ref zdoid)).ID;
			return $"{userID},{iD}";
		}

		private static ZDOID? StringToZDOID(string zdoidString)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			string[] array = zdoidString.Split(new char[1] { ',' });
			if (array.Length != 2)
			{
				return null;
			}
			long.TryParse(array[0], out var result);
			uint.TryParse(array[1], out var result2);
			if (result == 0L || result2 == 0)
			{
				Logger.LogDebug((object)"failed to parse to ZDOID");
				return null;
			}
			return new ZDOID(result, result2);
		}

		private static string Vector3ToString(Vector3 val)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"{val.x},{val.y},{val.z}";
		}

		private static Vector3? StringToVector3(string val)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			string[] array = val.Split(new char[1] { ',' });
			if (array.Length != 3)
			{
				return null;
			}
			float.TryParse(array[0], out var result);
			float.TryParse(array[1], out var result2);
			float.TryParse(array[2], out var result3);
			return new Vector3(result, result2, result3);
		}

		internal static void DEBUG_RemoveAllDynamicLocationKeys()
		{
			KeyValuePair<string, string>[] array = Player.m_localPlayer.m_customData.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				KeyValuePair<string, string> keyValuePair = array[i];
				if (keyValuePair.Key.Contains(GetFullPrefix()))
				{
					Logger.LogDebug((object)("Removing: Key: " + keyValuePair.Key + " Value: " + keyValuePair.Value));
					Player.m_localPlayer.m_customData.Remove(keyValuePair.Key);
				}
			}
		}

		internal static void DEBUGCOMMAND_RemoveLogout()
		{
			string logoutZdoKey = GetLogoutZdoKey();
			Logger.LogInfo((object)(Player.m_localPlayer.m_customData.Remove(logoutZdoKey) ? ("Removing logout key: " + logoutZdoKey) : "No logout key found"));
		}

		internal static void DEBUGCOMMAND_ListAllKeys()
		{
			KeyValuePair<string, string>[] array = Player.m_localPlayer.m_customData.ToArray();
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			List<string> list3 = new List<string>();
			List<string> list4 = new List<string>();
			string[] value = Player.m_localPlayer.m_customData.ToArray().Where(delegate(KeyValuePair<string, string> keyValuePair)
			{
				KeyValuePair<string, string> keyValuePair4 = keyValuePair;
				return keyValuePair4.Key.Contains($"{CurrentWorldId}");
			}).Select(delegate(KeyValuePair<string, string> keyValuePair)
			{
				KeyValuePair<string, string> keyValuePair3 = keyValuePair;
				return keyValuePair3.Value;
			})
				.ToArray();
			KeyValuePair<string, string>[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				KeyValuePair<string, string> keyValuePair2 = array2[i];
				if (keyValuePair2.Key.Contains(GetFullPrefix()))
				{
					if (keyValuePair2.Key.Contains("SpawnZdoOffset"))
					{
						list4.Add(keyValuePair2.Value);
					}
					else if (keyValuePair2.Key.Contains("SpawnZdo"))
					{
						list3.Add(keyValuePair2.Value);
					}
					else if (keyValuePair2.Key.Contains("LogoutParentZdoOffset"))
					{
						list2.Add(keyValuePair2.Value);
					}
					else if (keyValuePair2.Key.Contains("LogoutParentZdo"))
					{
						list.Add(keyValuePair2.Value);
					}
				}
			}
			Logger.LogInfo((object)("currentWorldItems: " + string.Join(", ", value)));
			Logger.LogInfo((object)("spawnKeys: " + string.Join(", ", list3)));
			Logger.LogInfo((object)("spawnOffsetKeys: " + string.Join(", ", list4)));
			Logger.LogInfo((object)("logoutKeys: " + string.Join(", ", list)));
			Logger.LogInfo((object)("logoutOffsetKeys: " + string.Join(", ", list2)));
		}

		public static bool RemoveZdoTarget(LocationVariation locationVariationType, Player? player)
		{
			RemoveTargetKey(locationVariationType, player);
			return true;
		}

		public static int? GetZdoFromStore(LocationVariation locationVariationType, Player? player)
		{
			string zdoStorageKey = GetZdoStorageKey(locationVariationType);
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			if (!player.m_customData.TryGetValue(zdoStorageKey, out var value))
			{
				return null;
			}
			if (!int.TryParse(value, out var result))
			{
				Logger.LogError((object)("The targetKey <" + zdoStorageKey + "> zdoKey: <" + value + "> could not be parsed as an int"));
				return null;
			}
			Logger.LogDebug((object)$"Retreiving targetKey <{zdoStorageKey}> zdoKey: <{value}> for name: {player.GetPlayerName()} id: {player.GetPlayerID()}");
			return result;
		}

		public static bool TryGetWorldUidFromKey(string storageKey, out long worldUid)
		{
			long.TryParse(storageKey.Split(new char[1] { '_' }).Last(), out var result);
			worldUid = result;
			return result == CurrentWorldId;
		}

		public static void RemoveTargetKey(LocationVariation locationVariationType, Player? player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)ZNet.instance == (Object)null))
			{
				string zdoStorageKey = GetZdoStorageKey(locationVariationType);
				string offsetStorageKey = GetOffsetStorageKey(locationVariationType);
				if (!TryGetWorldUidFromKey(zdoStorageKey, out var worldUid))
				{
					Logger.LogWarning((object)$"Skipping key deletion due to current world {CurrentWorldId} not matching key worldUid {worldUid}");
					return;
				}
				player.m_customData.Remove(zdoStorageKey);
				player.m_customData.Remove(offsetStorageKey);
				Game.instance.m_playerProfile.SavePlayerData(player);
			}
		}

		public static IEnumerator GetZdoFromStoreAsync(LocationVariation locationVariationType, Player? player, Action<ZDO?> onComplete)
		{
			int? zdoFromStore = GetZdoFromStore(locationVariationType, player);
			if (!zdoFromStore.HasValue)
			{
				onComplete(null);
				yield break;
			}
			ZDO zdoOutput = null;
			yield return ZdoWatchController.Instance.GetZdoFromServerAsync(zdoFromStore.Value, (Action<ZDO>)delegate(ZDO? output)
			{
				zdoOutput = output;
			});
			if (zdoOutput == null)
			{
				Logger.LogDebug((object)"Removing targetKey as it's ZDO no longer exists");
				RemoveTargetKey(locationVariationType, player);
			}
			else if (zdoOutput.GetInt("DynamicLocations_Point", 0) != 0)
			{
				onComplete(zdoOutput);
			}
		}

		public static void ResetCachedValues()
		{
			_cachedLocations.Clear();
		}

		public static Vector3 GetOffset(LocationVariation locationVariationType, Player? player)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return GetOffset(GetOffsetStorageKey(locationVariationType), player);
		}

		public static Vector3 GetOffset(string key, Player? player)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return Vector3.zero;
			}
			if (!player.m_customData.TryGetValue(key, out var value))
			{
				return Vector3.zero;
			}
			return (Vector3)(((??)StringToVector3(value)) ?? Vector3.zero);
		}

		public static ZDO? SetZdo(LocationVariation locationVaration, Player? player, ZDO? zdo)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return null;
			}
			if (zdo == null)
			{
				return null;
			}
			string zdoStorageKey = GetZdoStorageKey(locationVaration);
			int num = default(int);
			if (!ZdoWatchController.GetPersistentID(zdo, ref num))
			{
				Logger.LogWarning((object)$"No persistent id found for dynamicObj {zdo}");
				return null;
			}
			zdo.Set("DynamicLocations_Point", 1);
			if (player.m_customData.TryGetValue(zdoStorageKey, out var _))
			{
				player.m_customData[zdoStorageKey] = num.ToString();
			}
			else
			{
				player.m_customData.Add(zdoStorageKey, num.ToString());
			}
			if (!player.m_customData.ContainsKey(zdoStorageKey))
			{
				Logger.LogError((object)"Zdo string failed to set on player.customData");
			}
			Logger.LogDebug((object)$"Setting key: {zdoStorageKey}, uid: {zdo.m_uid} for name: {player.GetPlayerName()} id: {player.GetPlayerID()}");
			Game.instance.m_playerProfile.SavePlayerData(player);
			return zdo;
		}

		public static Vector3? SetOffset(LocationVariation locationVariationType, Player player, Vector3 offset)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return SetOffset(GetOffsetStorageKey(locationVariationType), player, offset);
		}

		public static Vector3? SetOffset(string key, Player player, Vector3 offset)
		{
			//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_004d: 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)
			if (!Object.op_Implicit((Object)(object)player))
			{
				return null;
			}
			if (Vector3.zero == offset)
			{
				if (player.m_customData.TryGetValue(key, out var _))
				{
					player.m_customData.Remove(key);
				}
				return null;
			}
			player.m_customData[key] = Vector3ToString(offset);
			return offset;
		}

		public static string GetOffsetStorageKey(LocationVariation locationVariationType)
		{
			return locationVariationType switch
			{
				LocationVariation.Spawn => GetSpawnZdoOffsetKey(), 
				LocationVariation.Logout => GetLogoutZdoOffsetKey(), 
				_ => throw new ArgumentOutOfRangeException("locationVariationType", locationVariationType, null), 
			};
		}

		public static string GetZdoStorageKey(LocationVariation locationVariationType)
		{
			return locationVariationType switch
			{
				LocationVariation.Spawn => GetSpawnZdoKey(), 
				LocationVariation.Logout => GetLogoutZdoKey(), 
				_ => throw new ArgumentOutOfRangeException("locationVariationType", locationVariationType, null), 
			};
		}

		public static bool SetLocationTypeData(LocationVariation locationVariation, Player player, ZDO zdo, Vector3 offset)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Vector3? offset2 = SetOffset(GetOffsetStorageKey(locationVariation), player, offset);
			ZDO val = SetZdo(locationVariation, player, zdo);
			if (val == null)
			{
				return false;
			}
			SetCachedDynamicLocation(locationVariation, new CacheLocationItem
			{
				Zdo = val,
				Offset = offset2
			});
			return true;
		}

		public static void SaveWorldData()
		{
			World.GetWorldSavePath((FileSource)0);
			_ = Game.instance.m_devWorldName + "_mod_dynamic_locations.json";
		}
	}
	public class LoginAPIController
	{
		internal static readonly Dictionary<string, DynamicLoginIntegration> LoginIntegrations = new Dictionary<string, DynamicLoginIntegration>();

		internal static readonly Dictionary<string, DynamicLoginIntegration> DisabledLoginIntegrations = new Dictionary<string, DynamicLoginIntegration>();

		internal static List<DynamicLoginIntegration> loginIntegrationsByPriority = new List<DynamicLoginIntegration>();

		private PlayerSpawnController? _playerSpawnController => PlayerSpawnController.Instance;

		private static string? GetModIntegrationId(DynamicLoginIntegration integration)
		{
			if (integration.Guid != "")
			{
				return integration.Guid;
			}
			Logger.LogWarning((object)"Invalid guid detected, make sure the BepInPlugin guid is a valid number");
			return null;
		}

		public static List<DynamicLoginIntegration> OrderItems(List<DynamicLoginIntegration> items)
		{
			Dictionary<string, DynamicLoginIntegration> itemLookup = items.ToDictionary((DynamicLoginIntegration i) => i.Guid);
			List<DynamicLoginIntegration> result = new List<DynamicLoginIntegration>();
			HashSet<string> placed = new HashSet<string>();
			foreach (DynamicLoginIntegration item in items.OrderBy((DynamicLoginIntegration i) => i.Guid))
			{
				AddItemWithDependencies(item, itemLookup, result, placed);
			}
			return result;
		}

		private static void AddItemWithDependencies(DynamicLoginIntegration item, Dictionary<string, DynamicLoginIntegration> itemLookup, List<DynamicLoginIntegration> result, HashSet<string> placed)
		{
			if (placed.Contains(item.Guid))
			{
				return;
			}
			foreach (string runAfterPlugin in item.RunAfterPlugins)
			{
				if (itemLookup.TryGetValue(runAfterPlugin, out DynamicLoginIntegration value))
				{
					AddItemWithDependencies(value, itemLookup, result, placed);
				}
			}
			result.Add(item);
			placed.Add(item.Guid);
			foreach (string runBeforePlugin in item.RunBeforePlugins)
			{
				if (itemLookup.TryGetValue(runBeforePlugin, out DynamicLoginIntegration value2))
				{
					AddItemWithDependencies(value2, itemLookup, result, placed);
				}
			}
		}

		internal static void UpdateIntegrations()
		{
			foreach (string disabledLoginApiIntegration in DynamicLocationsConfig.DisabledLoginApiIntegrations)
			{
				if (LoginIntegrations.ContainsKey(disabledLoginApiIntegration))
				{
					LoginIntegrations.Remove(disabledLoginApiIntegration);
				}
			}
			foreach (KeyValuePair<string, DynamicLoginIntegration> disabledLoginIntegration in DisabledLoginIntegrations)
			{
				bool flag = false;
				foreach (string disabledLoginApiIntegration2 in DynamicLocationsConfig.DisabledLoginApiIntegrations)
				{
					if (DisabledLoginIntegrations.ContainsKey(disabledLoginApiIntegration2))
					{
						flag = true;
					}
				}
				if (!flag)
				{
					LoginIntegrations.Add(disabledLoginIntegration.Key, disabledLoginIntegration.Value);
				}
			}
			loginIntegrationsByPriority = OrderItems(LoginIntegrations.Values.ToList());
			foreach (DynamicLoginIntegration item in loginIntegrationsByPriority)
			{
				Logger.LogInfo((object)$"item ----> name:{item.Name}, guid: {item.Guid}, priority: {item.Priority}");
			}
		}

		public static bool AddLoginApiIntegration(DynamicLoginIntegration loginIntegration)
		{
			string modIntegrationId = GetModIntegrationId(loginIntegration);
			if (modIntegrationId == null)
			{
				return false;
			}
			if (!LoginIntegrations.ContainsKey(modIntegrationId))
			{
				LoginIntegrations.Add(modIntegrationId, loginIntegration);
				UpdateIntegrations();
				return true;
			}
			if (loginIntegration.LoginPrefabHashCode == 0)
			{
				Logger.LogWarning((object)$"LoginIntegration provided invalid prefab identifier, the hashcode was {loginIntegration.LoginPrefabHashCode}.");
			}
			if (DynamicLocationsConfig.IsDebug)
			{
				if (!ZNetScene.instance.m_namedPrefabs.TryGetValue(loginIntegration.LoginPrefabHashCode, out var value))
				{
					Logger.LogError((object)$"Prefab not found for stableHashCode {loginIntegration.LoginPrefabHashCode}");
				}
				else
				{
					Logger.LogDebug((object)$"Found prefab for stableHashCode {loginIntegration.LoginPrefabHashCode} name {((Object)value).name}");
				}
			}
			Logger.LogError((object)"Could not integrate component due to collision in registered plugin GUID and plugin_version, this ModAPI plugin will not be loaded. Make sure your plugin only creates 1 instance of ModLoginApi and that your plugin GUID or plugin.Name_plugin_Version are unique.");
			return false;
		}

		private static void LogResults(DynamicLoginIntegration? selectedIntegration)
		{
			if (DynamicLocationsConfig.IsDebug)
			{
				Logger.LogDebug((object)((selectedIntegration != null) ? ("Successfully handled ModApi " + selectedIntegration.Name + " matched") : "No matches found for registered integrations"));
			}
		}

		public static IEnumerator RunAllIntegrations_OnLoginMoveToZdo(ZDO zdo, Vector3? offset, PlayerSpawnController playerSpawnController)
		{
			if ((Object)(object)playerSpawnController == (Object)null)
			{
				yield break;
			}
			DynamicLoginIntegration selectedIntegration = null;
			foreach (DynamicLoginIntegration item in loginIntegrationsByPriority)
			{
				if (item.OnLoginMatchZdoPrefab(zdo))
				{
					selectedIntegration = item;
					yield return item.API_OnLoginMoveToZDO(zdo, offset, playerSpawnController);
					break;
				}
			}
			if (selectedIntegration != null)
			{
				yield return (object)new WaitUntil((Func<bool>)(() => selectedIntegration.IsComplete));
			}
			LogResults(selectedIntegration);
		}
	}
	public class PlayerSpawnController : MonoBehaviour
	{
		public delegate TResult Func<in T, out TResult>(T arg);

		internal bool CanUpdateLogoutPoint = true;

		internal bool CanRemoveLogoutAfterSync = true;

		internal bool IsTeleportingToDynamicLocation;

		private bool IsRunningFindDynamicZdo;

		public static Dictionary<long, PlayerSpawnController> Instances = new Dictionary<long, PlayerSpawnController>();

		public static PlayerSpawnController? Instance;

		public static Coroutine? MoveToLogoutRoutine;

		public static Coroutine? MoveToSpawnRoutine;

		internal static List<DebugSafeTimer> Timers = new List<DebugSafeTimer>();

		private bool MovePlayerToZdoComplete;

		private static Player? player => Player.m_localPlayer;

		private void Awake()
		{
			Setup();
		}

		private void Update()
		{
			DebugSafeTimer.UpdateTimersFromList(Timers);
		}

		public void DEBUG_MoveTo(LocationVariation locationVariationType)
		{
			CanUpdateLogoutPoint = true;
			CanRemoveLogoutAfterSync = false;
			switch (locationVariationType)
			{
			case LocationVariation.Spawn:
				Instance?.MovePlayerToSpawnPoint();
				break;
			case LocationVariation.Logout:
				Instance?.MovePlayerToLogoutPoint();
				break;
			default:
				throw new ArgumentOutOfRangeException("locationVariationType", locationVariationType, null);
			}
		}

		internal void Reset()
		{
			IsRunningFindDynamicZdo = false;
			IsTeleportingToDynamicLocation = false;
			CanUpdateLogoutPoint = true;
			CanRemoveLogoutAfterSync = true;
			MovePlayerToZdoComplete = true;
			ResetRoutine(ref MoveToLogoutRoutine);
			ResetRoutine(ref MoveToSpawnRoutine);
		}

		internal void OnMovePlayerToZdoComplete(bool success = false, string errorMessage = "OnMovePlayerToZdo exited but failed")
		{
			Reset();
			Timers.Clear();
			IsTeleportingToDynamicLocation = false;
			MovePlayerToZdoComplete = true;
			if (!success)
			{
				Logger.LogError((object)errorMessage);
			}
		}

		internal static void ResetRoutine(ref Coroutine? routine)
		{
			if (routine != null)
			{
				PlayerSpawnController? instance = Instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StopCoroutine(routine);
				}
				routine = null;
			}
		}

		private void OnDestroy()
		{
			Reset();
			Logger.LogDebug((object)"Called onDestroy");
		}

		private void OnDisable()
		{
			Reset();
			((MonoBehaviour)this).StopAllCoroutines();
		}

		private void Setup()
		{
			Instance = this;
			_ = (Object)(object)player == (Object)null;
		}

		public bool PersistDynamicPoint(ZDO zdo, LocationVariation locationVariationType, out int id)
		{
			id = 0;
			if ((Object)(object)ZdoWatchController.Instance == (Object)null)
			{
				return false;
			}
			id = ZdoWatchController.Instance.GetOrCreatePersistentID(zdo);
			if (id == 0)
			{
				if (locationVariationType == LocationVariation.Spawn)
				{
					Logger.LogError((object)"No persistent ID returned for bed, this should not be possible. Please report this error");
					RemoveDynamicPoint(zdo, locationVariationType);
				}
				return false;
			}
			AddDynamicPoint(zdo, locationVariationType);
			return true;
		}

		public void AddDynamicPoint(ZDO zdo, LocationVariation locationVariationType)
		{
			zdo.Set("DynamicLocations_Point", 1);
		}

		public void RemoveDynamicPoint(ZDO? zdo, LocationVariation locationVariationType)
		{
			LocationController.RemoveZdoTarget(locationVariationType, player);
			if (zdo != null)
			{
				zdo.RemoveInt("DynamicLocations_Point");
			}
		}

		public bool SyncBedSpawnPoint(ZDO zdo, Bed bed)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (!bed.IsMine())
			{
				return false;
			}
			PersistDynamicPoint(zdo, LocationVariation.Spawn, out var _);
			return LocationController.SetLocationTypeData(LocationVariation.Spawn, player, zdo, ((Component)bed).transform.position - ((Component)player).transform.position);
		}

		public bool SyncLogoutPoint(ZDO? zdo, bool shouldRemove = false)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			if (zdo == null && !shouldRemove)
			{
				Logger.LogError((object)"ZDO not found for netview, this likely means something is wrong with the are it is being called in");
				return false;
			}
			if (shouldRemove)
			{
				RemoveDynamicPoint(zdo, LocationVariation.Logout);
				Game.instance.m_playerProfile.SavePlayerData(player);
				return true;
			}
			int id;
			bool flag = PersistDynamicPoint(zdo, LocationVariation.Logout, out id);
			if (!shouldRemove && !flag)
			{
				Logger.LogDebug((object)"vehicleZdoId is invalid");
				return false;
			}
			if (LocationController.GetZdoFromStore(LocationVariation.Logout, player) == id)
			{
				Logger.LogDebug((object)"Matching ZDOID found already stored, skipping sync/save");
				return false;
			}
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (((Component)player).transform.localPosition != ((Component)player).transform.position)
			{
				LocationController.SetOffset(LocationVariation.Logout, player, ((Component)player).transform.localPosition);
			}
			LocationController.SetZdo(LocationVariation.Logout, player, zdo);
			Game.instance.m_playerProfile.SavePlayerData(player);
			return true;
		}

		[UsedImplicitly]
		public bool DynamicTeleport(Vector3 position, Quaternion rotation)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			player.m_teleportCooldown = 15f;
			player.m_teleporting = false;
			return ((Character)player).TeleportTo(position, rotation, !DynamicLocationsConfig.DebugDisableDistancePortal.Value);
		}

		public void MovePlayerToLogoutPoint()
		{
			MoveToLogoutRoutine = ((MonoBehaviour)this).StartCoroutine(UpdateLocation(LocationVariation.Logout));
		}

		public IEnumerator FindDynamicZdo(LocationVariation locationVariationType, Action<ZDO?> onComplete, bool shouldAdjustReferencePoint = false)
		{
			IsRunningFindDynamicZdo = true;
			ZDO zdoOutput = null;
			yield return LocationController.GetZdoFromStoreAsync(locationVariationType, player, delegate(ZDO? output)
			{
				zdoOutput = output;
			});
			onComplete(zdoOutput);
			if (shouldAdjustReferencePoint && (Object)(object)ZNet.instance != (Object)null && zdoOutput != null)
			{
				ZNet.instance.SetReferencePosition(zdoOutput.GetPosition());
			}
			IsRunningFindDynamicZdo = false;
		}

		private IEnumerator UpdateLocation(LocationVariation locationVariationType)
		{
			DebugSafeTimer timer = DebugSafeTimer.StartNew(Timers);
			IsTeleportingToDynamicLocation = false;
			Vector3 offset = LocationController.GetOffset(locationVariationType, player);
			ZDO zdoOutput = null;
			yield return FindDynamicZdo(locationVariationType, delegate(ZDO? output)
			{
				zdoOutput = output;
			});
			if (zdoOutput == null)
			{
				yield break;
			}
			switch (locationVariationType)
			{
			case LocationVariation.Spawn:
				yield return MovePlayerToZdo(zdoOutput, offset);
				break;
			case LocationVariation.Logout:
				yield return LoginAPIController.RunAllIntegrations_OnLoginMoveToZdo(zdoOutput, offset, this);
				break;
			default:
				throw new ArgumentOutOfRangeException("locationVariationType", locationVariationType, null);
			}
			IsTeleportingToDynamicLocation = false;
			LocationVariation locationVariation = locationVariationType;
			if (locationVariation != 0)
			{
				if (locationVariation != LocationVariation.Logout || !((Object)(object)player != (Object)null))
				{
					throw new ArgumentOutOfRangeException("locationVariationType", locationVariationType, null);
				}
				if (CanRemoveLogoutAfterSync && DynamicLocationsConfig.DEBUG_ShouldNotRemoveTargetKey.Value)
				{
					LocationController.RemoveZdoTarget(LocationVariation.Logout, player);
				}
			}
			timer.Clear();
			yield return true;
		}

		public Coroutine MovePlayerToSpawnPoint()
		{
			ResetRoutine(ref MoveToSpawnRoutine);
			ResetRoutine(ref MoveToLogoutRoutine);
			MoveToSpawnRoutine = ((MonoBehaviour)this).StartCoroutine(UpdateLocation(LocationVariation.Spawn));
			return MoveToSpawnRoutine;
		}

		private void SyncPlayerPosition(Vector3 newPosition)
		{
			//IL_0042: 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)
			//IL_0058: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogDebug((object)"Running PlayerPosition Sync");
			if (ZNetView.m_forceDisableInit || (Object)(object)player == (Object)null)
			{
				return;
			}
			ZDO zDO = ((Character)player).m_nview.GetZDO();
			if (zDO == null)
			{
				Logger.LogDebug((object)"Player zdo invalid exiting");
				return;
			}
			Logger.LogDebug((object)$"Syncing Player Position and sector, {newPosition}");
			if (!ZoneSystem.instance.IsZoneLoaded(ZoneSystem.GetZone(newPosition)))
			{
				Logger.LogDebug((object)$"zone not loaded, exiting SyncPlayerPosition for position: {newPosition}");
				return;
			}
			ZNet.instance.SetReferencePosition(newPosition);
			zDO.SetPosition(newPosition);
			zDO.SetSector(ZoneSystem.GetZone(newPosition));
			((Component)player).transform.position = newPosition;
		}

		public static bool HasExpiredTimer(Stopwatch timer, int timeInMs = 1000)
		{
			int num = ((timeInMs > 1000) ? timeInMs : DynamicLocationsConfig.LocationControlsTimeoutInMs.Value);
			return timer.ElapsedMilliseconds > num;
		}

		public static bool HasExpiredTimer(DebugSafeTimer timer, int timeInMs = 1000)
		{
			int num = ((timeInMs > 1000) ? timeInMs : DynamicLocationsConfig.LocationControlsTimeoutInMs.Value);
			return timer.ElapsedMilliseconds > (float)num;
		}

		[UsedImplicitly]
		public bool CanFreezePlayer(bool val)
		{
			return !DynamicLocationsConfig.DebugDisableFreezePlayerTeleportMechanics.Value && val;
		}

		public IEnumerator MovePlayerToZdo(ZDO? zdo, Vector3? offset, bool freezePlayerOnTeleport = false, bool shouldKeepPlayerFrozen = false)
		{
			ZDO zdo2 = zdo;
			if (!Object.op_Implicit((Object)(object)player) || zdo2 == null)
			{
				OnMovePlayerToZdoComplete();
				yield break;
			}
			DebugSafeTimer timer = DebugSafeTimer.StartNew();
			bool hasKinematicPlayerFreeze = CanFreezePlayer(freezePlayerOnTeleport);
			bool hasKeepPlayerFrozen = CanFreezePlayer(shouldKeepPlayerFrozen);
			if (DynamicLocationsConfig.IsDebug)
			{
				Logger.LogDebug((object)"Running MovePlayerToZdo");
			}
			Vector3 val = Vector3.up * (float)DynamicLocationsConfig.RespawnHeightOffset.Value;
			Vector3 position = zdo2.GetPosition() + val;
			IsTeleportingToDynamicLocation = DynamicTeleport(position, zdo2.GetRotation());
			Vector2i zone = ZoneSystem.GetZone(zdo2.GetPosition());
			ZoneSystem.instance.PokeLocalZone(zone);
			bool zoneIsNotLoaded = false;
			while (!zoneIsNotLoaded)
			{
				zone = ZoneSystem.GetZone(zdo2.GetPosition());
				zoneIsNotLoaded = ZoneSystem.instance.IsZoneLoaded(zone);
				yield return (object)new WaitForFixedUpdate();
			}
			if (!IsTeleportingToDynamicLocation)
			{
				OnMovePlayerToZdoComplete();
				Logger.LogError((object)"Teleport command failed for player, exiting dynamic spawn MovePlayerToZdo.");
				yield break;
			}
			if ((Object)(object)player != (Object)null && CanFreezePlayer(freezePlayerOnTeleport) && ((Character)player).IsDebugFlying())
			{
				player.ToggleDebugFly();
			}
			ZNetView zdoNetViewInstance = null;
			zone = ZoneSystem.GetZone(zdo2.GetPosition());
			ZoneSystem.instance.PokeLocalZone(zone);
			yield return (object)new WaitUntil((Func<bool>)(() => !((Character)Player.m_localPlayer).IsTeleporting() || HasExpiredTimer(timer, DynamicLocationsConfig.LocationControlsTimeoutInMs.Value)));
			zdoNetViewInstance = ZNetScene.instance.FindInstance(zdo2);
			yield return (object)new WaitUntil((Func<bool>)delegate
			{
				zdoNetViewInstance = ZNetScene.instance.FindInstance(zdo2);
				return (Object)(object)zdoNetViewInstance != (Object)null || HasExpiredTimer(timer, DynamicLocationsConfig.LocationControlsTimeoutInMs.Value);
			});
			if (HasExpiredTimer(timer, DynamicLocationsConfig.LocationControlsTimeoutInMs.Value))
			{
				Logger.LogError((object)"Error attempting to find NetView instance of the ZDO");
				yield break;
			}
			if ((Object)(object)player != (Object)null && hasKinematicPlayerFreeze && !hasKeepPlayerFrozen && ((Character)player).IsDebugFlying())
			{
				player.ToggleDebugFly();
			}
			if (DynamicLocationsConfig.DebugForceUpdatePositionAfterTeleport.Value && DynamicLocationsConfig.DebugForceUpdatePositionDelay.Value > 0f)
			{
				yield return (object)new WaitForSeconds(DynamicLocationsConfig.DebugForceUpdatePositionDelay.Value);
			}
			if ((Object)(object)player != (Object)null && DynamicLocationsConfig.DebugForceUpdatePositionAfterTeleport.Value)
			{
				ZNetView obj = zdoNetViewInstance;
				Vector3? obj2;
				if (obj == null)
				{
					obj2 = null;
				}
				else
				{
					Vector3 position2 = ((Component)obj).transform.position;
					Vector3? val2 = offset;
					obj2 = (val2.HasValue ? new Vector3?(position2 + val2.GetValueOrDefault()) : null);
				}
				position = (Vector3)(((??)obj2) ?? zdo2.GetPosition()) + Vector3.up * (float)DynamicLocationsConfig.RespawnHeightOffset.Value;
				((Component)player).transform.position = position;
			}
			timer.Clear();
			yield return null;
		}
	}
}
namespace DynamicLocations.Constants
{
	public enum LocationVariation
	{
		Spawn,
		Logout
	}
	public static class LocationVariationUtils
	{
		public const string LogoutString = "logout";

		public const string SpawnString = "spawn";

		public static LocationVariation? ToLocationVaration(string? locationVarationString)
		{
			string text = locationVarationString?.ToLower();
			if (!(text == "logout"))
			{
				if (text == "spawn")
				{
					return LocationVariation.Spawn;
				}
				return null;
			}
			return LocationVariation.Logout;
		}
	}
	public static class ZdoVarKeys
	{
		public const string DynamicLocationsPoint = "DynamicLocations_Point";
	}
}
namespace DynamicLocations.Config
{
	public static class DynamicLocationsConfig
	{
		private const string MainSection = "Main";

		private const string DebugSection = "Debug";

		public static ConfigFile? Config { get; private set; }

		public static ConfigEntry<string> DisabledLoginApiIntegrationsString { get; private set; }

		public static ConfigEntry<int> LocationControlsTimeoutInMs { get; private set; }

		public static List<string> DisabledLoginApiIntegrations => DisabledLoginApiIntegrationsString?.Value.Split(new char[1] { ',' }).ToList() ?? new List<string>();

		public static ConfigEntry<bool> HasCustomSpawnDelay { get; private set; }

		public static ConfigEntry<bool> DEBUG_ShouldNotRemoveTargetKey { get; private set; }

		public static ConfigEntry<float> CustomSpawnDelay { get; private set; }

		public static ConfigEntry<int> RespawnHeightOffset { get; set; }

		public static ConfigEntry<bool> EnableDynamicSpawnPoint { get; private set; }

		public static ConfigEntry<bool> EnableDynamicLogoutPoint { get; private set; }

		public static ConfigEntry<bool> DebugDisableFreezePlayerTeleportMechanics { get; private set; }

		private static ConfigEntry<bool> Debug { get; set; }

		public static bool IsDebug => Debug.Value;

		public static ConfigEntry<bool> DebugDisableDistancePortal { get; private set; }

		public static ConfigEntry<float> DebugForceUpdatePositionDelay { get; private set; }

		public static ConfigEntry<bool> DebugForceUpdatePositionAfterTeleport { get; private set; }

		public static void BindConfig(ConfigFile config)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_007c: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Expected O, but got Unknown
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Expected O, but got Unknown
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Expected O, but got Unknown
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Expected O, but got Unknown
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Expected O, but got Unknown
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Expected O, but got Unknown
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Expected O, but got Unknown
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Expected O, but got Unknown
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Expected O, but got Unknown
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Expected O, but got Unknown
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Expected O, but got Unknown
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Expected O, but got Unknown
			Config = config;
			DEBUG_ShouldNotRemoveTargetKey = Config.Bind<bool>("Main", "DEBUG_ShouldNotRemoveTargetKey", true, new ConfigDescription("Debug only command: will prevent removing of data on the player. This is meant to debug issues with the player spawn points. Should not be enabled in production builds.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = true
			} }));
			LocationControlsTimeoutInMs = Config.Bind<int>("Main", "LocationControls Timeout In Ms", 20000, new ConfigDescription("Allows for setting the delay in which the spawn will exit logic to prevent degraded performance.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1000, 40000), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = false
			} }));
			HasCustomSpawnDelay = Config.Bind<bool>("Main", "HasCustomSpawnDelay", false, new ConfigDescription("Enables custom spawn delay. This is meant to speed-up the game.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = false
			} }));
			CustomSpawnDelay = Config.Bind<float>("Main", "CustomSpawnDelay", 1f, new ConfigDescription("Will significantly speed-up respawn and login process. This mod will NOT support respawn delays above default(10) seconds, this is too punishing for players. Try to make other consequences instead of preventing people from playing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = false
			} }));
			DisabledLoginApiIntegrationsString = Config.Bind<string>("Main", "DisabledLoginApiIntegrations", "", new ConfigDescription("A list of disabled plugins by GUID or name. Each item must be separated by a comma. This list will force disable any plugins matching either the guid or name. e.g. if you don't want ValheimRAFT to be enabling dynamic locations login integrations add \"zolantris.ValheimRAFT\" or \"ValheimRAFT.2.3.0\".", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = false,
				IsAdvanced = false
			} }));
			DebugDisableFreezePlayerTeleportMechanics = Config.Bind<bool>("Debug", "DEBUG_DisableFreezePlayerMechanics", false, new ConfigDescription("This will disable freezing of players from integrations. Do not disable this unless you know what you are doing. Freezing is used to prevent physics happening during teleport.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = false,
				IsAdvanced = false
			} }));
			DebugDisableDistancePortal = Config.Bind<bool>("Debug", "DebugDistancePortal", false, new ConfigDescription("distance portal enabled, disabling this could break portals", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = true
			} }));
			DebugForceUpdatePositionDelay = Config.Bind<float>("Debug", "DebugForceUpdatePositionDelay", 0f, new ConfigDescription("distance portal enabled, disabling this could break portals", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = true
			} }));
			DebugForceUpdatePositionAfterTeleport = Config.Bind<bool>("Debug", "DebugForceUpdatePositionAfterTeleport", false, new ConfigDescription("distance portal enabled, disabling this could break portals", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = true
			} }));
			EnableDynamicSpawnPoint = Config.Bind<bool>("Main", "enableDynamicSpawnPoints", true, new ConfigDescription("Enable dynamic spawn points. This will allow the user to re-spawn in a new area of the map if a vehicle has moved.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = true
			} }));
			EnableDynamicLogoutPoint = Config.Bind<bool>("Main", "enableDynamicLogoutPoints", true, new ConfigDescription("Enable dynamic logout points. This will allow the user to login to a new area of the map if a vehicle has moved", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = true
			} }));
			RespawnHeightOffset = Config.Bind<int>("Main", "respawnHeightOffset", 0, new ConfigDescription("Sets the respawn height for beds. Useful if the player is spawning within the bed instead of above it", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-5, 10), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = false,
				IsAdvanced = true
			} }));
			Debug = Config.Bind<bool>("Main", "debug", false, new ConfigDescription("Enable additional logging and debug drawing around spawn and logout points. Useful for debugging this mod", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = true
			} }));
			DisabledLoginApiIntegrationsString.SettingChanged += delegate
			{
				LoginAPIController.UpdateIntegrations();
			};
			_ = Debug.Value;
		}
	}
}
namespace DynamicLocations.Commands
{
	public class KeyValueSerializer
	{
		public static string Serialize(object obj, int indentLevel = 0)
		{
			if (obj == null)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			string indent = new string(' ', indentLevel * 4);
			Type type = obj.GetType();
			PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				object value = propertyInfo.GetValue(obj);
				SerializeValue(stringBuilder, propertyInfo.Name, value, indent, indentLevel);
			}
			FieldInfo[] array2 = fields;
			foreach (FieldInfo fieldInfo in array2)
			{
				object value2 = fieldInfo.GetValue(obj);
				SerializeValue(stringBuilder, fieldInfo.Name, value2, indent, indentLevel);
			}
			return stringBuilder.ToString();
		}

		private static void SerializeValue(StringBuilder sb, string name, object value, string indent, int indentLevel)
		{
			if (value == null)
			{
				sb.AppendLine(indent + name + ": null");
				return;
			}
			if (value is string || value.GetType().IsPrimitive)
			{
				sb.AppendLine($"{indent}{name}: {value}");
				return;
			}
			if (value is IEnumerable enumerable)
			{
				sb.AppendLine(indent + name + ":");
				{
					foreach (object item in enumerable)
					{
						SerializeValue(sb, "- Item", item, indent + "  ", indentLevel + 1);
					}
					return;
				}
			}
			sb.AppendLine(indent + name + ":");
			sb.Append(Serialize(value, indentLevel + 1));
		}
	}
	public class ListAllKeysCommand : ConsoleCommand
	{
		public override string Name => "list-all-keys";

		public override string Help { get; } = "list all keys";


		public override void Run(string[] args)
		{
			if (args.Length != 0)
			{
				LocationController.DEBUGCOMMAND_ListAllKeys();
			}
		}
	}
	public class ModIntegrationsCommand : ConsoleCommand
	{
		private const string Indent = "\n-  ";

		public override string Name => "mod-integrations";

		public override string Help { get; } = "Lists all mods using this plugin, e.g. ValheimRaft/Vehicles. \n-  Name + version will be output only.\n-  To see everything add -v will output the whole object per integration.";


		private static void ModIntegrationsCommands(bool isVerbose)
		{
			Logger.LogMessage((object)"Listing all integrations by order");
			int num = 1;
			foreach (DynamicLoginIntegration item in LoginAPIController.loginIntegrationsByPriority)
			{
				if (isVerbose)
				{
					Logger.LogMessage((object)KeyValueSerializer.Serialize(item));
				}
				else
				{
					Logger.LogMessage((object)$"[LoginIntegration]: [index: {num}] -> ModName: {item.Name} ModVersion {item.Version}, priority {item.Priority}, guid: {item.Guid}");
				}
				num++;
			}
		}

		private static bool IsVerboseFlag(string arg)
		{
			switch (arg)
			{
			case "-v":
			case "-verbose":
			case "--verbose":
				return true;
			default:
				return false;
			}
		}

		public override void Run(string[] args)
		{
			if (args.Length != 0)
			{
				ModIntegrationsCommands(IsVerboseFlag(args.First()));
			}
		}

		public override List<string> CommandOptionList()
		{
			return new List<string>(1) { "-v" };
		}
	}
	public class MoveToCommand : ConsoleCommand
	{
		public override bool IsCheat => true;

		public override string Name => "move-to";

		public override string Help { get; } = "Moves to logout point. Requires Admin privileges";


		public override void Run(string[] args)
		{
			if (args.Length == 0)
			{
				Logger.LogMessage((object)("Requires an argument of " + string.Join(",", ((ConsoleCommand)this).CommandOptionList().ToArray())));
				return;
			}
			string text = args.First();
			LocationVariation? locationVariation = LocationVariationUtils.ToLocationVaration(text);
			if (!locationVariation.HasValue)
			{
				Logger.LogMessage((object)("Invalid input " + text));
			}
			else
			{
				PlayerSpawnController.Instance?.DEBUG_MoveTo(locationVariation.Value);
			}
		}

		public override List<string> CommandOptionList()
		{
			return new List<string>(2) { "logout", "spawn" };
		}
	}
	public class DynamicLocationsCommands : ConsoleCommand
	{
		private enum CommandsEnum
		{
			Help,
			MoveToLocation,
			ClearAll,
			ClearSpawn,
			ClearLogout,
			ListAllKeys,
			ListIntegrations
		}

		private const string playerClearAllCommand = "playerClearAll";

		private const string playerClearSpawnCommand = "playerClearSpawn";

		private const string playerClearLogoutCommand = "playerClearLogout";

		private const string serverClearAllCommand = "serverClearAll";

		private const string helpCommand = "help";

		private static readonly ListAllKeysCommand ListAllKeysCommandInstance = new ListAllKeysCommand();

		private static readonly ModIntegrationsCommand ModIntegrationsCommandInstance = new ModIntegrationsCommand();

		private static readonly MoveToCommand MoveToCommandInstance = new MoveToCommand();

		private static string helpCommandItems = string.Join("\n", "DynamicLocationsCLI Mod CLI: ", FormatCommand("playerClearLogout") + " removes logout for the current world, will not change other worlds", FormatCommand("playerClearAll") + " clears all dynamicLogin and dynamicSpawn points for a player for the corresponding world", FormatCommand((ConsoleCommand)(object)MoveToCommandInstance), FormatCommand((ConsoleCommand)(object)ListAllKeysCommandInstance), FormatCommand((ConsoleCommand)(object)ModIntegrationsCommandInstance));

		public override string Help => OnHelp();

		public override string Name => "dynamic-locations";

		private static string FormatCommand(string? command)
		{
			if (command != null)
			{
				return "<" + command + ">:";
			}
			return "";
		}

		private static string FormatCommand(string command, List<string>? args, string description)
		{
			return "<" + command + ">: " + string.Join("", args?.Select((string arg) => " " + FormatCommand(arg)) ?? Array.Empty<string>()) + " " + description;
		}

		private static string FormatCommand(ConsoleCommand consoleCommand)
		{
			return FormatCommand(consoleCommand.Name, consoleCommand.CommandOptionList(), consoleCommand.Help);
		}

		private static string OnHelp()
		{
			return helpCommandItems;
		}

		private static CommandsEnum? GetCommandArg(string commandString)
		{
			if (((ConsoleCommand)ModIntegrationsCommandInstance).Name == commandString)
			{
				return CommandsEnum.ListIntegrations;
			}
			if (((ConsoleCommand)ListAllKeysCommandInstance).Name == commandString)
			{
				return CommandsEnum.ListAllKeys;
			}
			if (((ConsoleCommand)MoveToCommandInstance).Name == commandString)
			{
				return CommandsEnum.MoveToLocation;
			}
			return commandString switch
			{
				"playerClearAll" => CommandsEnum.ClearAll, 
				"playerClearLogout" => CommandsEnum.ClearLogout, 
				"help" => CommandsEnum.Help, 
				_ => null, 
			};
		}

		public override void Run(string[] args)
		{
			if (args.Length != 0)
			{
				ParseFirstArg(args);
			}
		}

		private static void ParseFirstArg(string[]? args)
		{
			string text = args?.First() ?? "";
			if (text == "")
			{
				Logger.LogMessage((object)"Must provide a argument for a command. Please run help for more information.");
			}
			CommandsEnum? commandArg = GetCommandArg(text);
			if (!commandArg.HasValue)
			{
				Logger.LogMessage((object)("Command " + text + " not recognized. Please run help for more information."));
				return;
			}
			string[] array = args?.Skip(1)?.ToArray() ?? Array.Empty<string>();
			if (commandArg.HasValue)
			{
				switch (commandArg.GetValueOrDefault())
				{
				case CommandsEnum.ClearAll:
					PlayerClearAll(array);
					break;
				case CommandsEnum.ClearSpawn:
				case CommandsEnum.ClearLogout:
				case CommandsEnum.ListAllKeys:
					((ConsoleCommand)ListAllKeysCommandInstance).Run(array);
					break;
				case CommandsEnum.ListIntegrations:
					((ConsoleCommand)ModIntegrationsCommandInstance).Run(array);
					break;
				case CommandsEnum.Help:
					OnHelp();
					break;
				case CommandsEnum.MoveToLocation:
					((ConsoleCommand)MoveToCommandInstance).Run(array);
					break;
				default:
					throw new ArgumentOutOfRangeException();
				}
			}
		}

		private bool IsAdmin()
		{
			if (!SynchronizationManager.Instance.PlayerIsAdmin)
			{
				Logger.LogMessage((object)"Player is not admin, must be admin to run this command");
				return false;
			}
			return true;
		}

		public static void PlayerClearAll(string[] args)
		{
			if (args.Length == 0)
			{
				LocationController.DEBUG_RemoveAllDynamicLocationKeys();
			}
		}

		public void PlayerListAllDynamicLocationKeys()
		{
			LocationController.DEBUGCOMMAND_ListAllKeys();
		}

		public static void PlayerClearLogout()
		{
			LocationController.DEBUGCOMMAND_RemoveLogout();
		}

		public override List<string> CommandOptionList()
		{
			return new List<string>(5)
			{
				((ConsoleCommand)ListAllKeysCommandInstance).Name,
				((ConsoleCommand)MoveToCommandInstance).Name,
				((ConsoleCommand)ModIntegrationsCommandInstance).Name,
				"playerClearLogout",
				"playerClearAll"
			};
		}
	}
}
namespace DynamicLocations.API
{
	public class DynamicLoginIntegration
	{
		private const int DefaultMovementTimeoutMs = 5000;

		private readonly DebugSafeTimer _timerInstance = new DebugSafeTimer();

		private bool _isRunningOnLoginMoveToZdo;

		private bool _hasCompleted;

		private Coroutine? _onLoginMoveToZdoCoroutine;

		public int LoginPrefabHashCode => Config.LoginPrefabHashCode;

		internal string Guid => Config.Guid;

		internal string Name => Config.Name;

		internal string Version => Config.Version;

		public bool ShouldFreezePlayer => Config.ShouldFreezePlayer;

		public List<string> RunBeforePlugins => Config.RunBeforePlugins;

		public List<string> RunAfterPlugins => Config.RunAfterPlugins;

		public int Priority
		{
			get
			{
				if (Config.Priority <= 0)
				{
					return 999;
				}
				return Config.Priority;
			}
		}

		public int MovementTimeoutMs => GetMovementTimeout();

		public bool IsComplete
		{
			get
			{
				if (_hasCompleted && !_isRunningOnLoginMoveToZdo)
				{
					return _onLoginMoveToZdoCoroutine == null;
				}
				return false;
			}
		}

		public IntegrationConfig Config { get; set; }

		protected DynamicLoginIntegration(IntegrationConfig config)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Config = config;
		}

		private int GetMovementTimeout()
		{
			int movementTimeout = Config.MovementTimeout;
			if (movementTimeout < 2000 || movementTimeout > 20000)
			{
				return 5000;
			}
			return Config.MovementTimeout;
		}

		public static IntegrationConfig CreateConfig(BaseUnityPlugin plugin, string zdoTargetPrefabName)
		{
			return new IntegrationConfig(plugin, zdoTargetPrefabName);
		}

		private void OnStart()
		{
			_timerInstance.Restart();
			PlayerSpawnController.ResetRoutine(ref _onLoginMoveToZdoCoroutine);
			_hasCompleted = false;
			_isRunningOnLoginMoveToZdo = true;
		}

		private void OnComplete()
		{
			_timerInstance.Reset();
			PlayerSpawnController.ResetRoutine(ref _onLoginMoveToZdoCoroutine);
			_isRunningOnLoginMoveToZdo = false;
			_hasCompleted = true;
		}

		protected internal IEnumerator API_OnLoginMoveToZDO(ZDO zdo, Vector3? offset, PlayerSpawnController playerSpawnController)
		{
			OnStart();
			_onLoginMoveToZdoCoroutine = ((MonoBehaviour)playerSpawnController).StartCoroutine(OnLoginMoveToZDO(zdo, offset, playerSpawnController));
			yield return _onLoginMoveToZdoCoroutine;
			yield return (object)new WaitUntil((Func<bool>)(() => _onLoginMoveToZdoCoroutine == null || _timerInstance.ElapsedMilliseconds >= (float)GetMovementTimeout()));
			OnComplete();
			yield return true;
		}

		protected virtual IEnumerator OnLoginMoveToZDO(ZDO zdo, Vector3? offset, PlayerSpawnController playerSpawnController)
		{
			if (DynamicLocationsConfig.IsDebug)
			{
				Logger.LogDebug((object)"Not overridden custom handler, running MovePlayerToZdo default call.");
			}
			if (OnLoginMatchZdoPrefab(zdo))
			{
				yield return playerSpawnController.MovePlayerToZdo(zdo, (Vector3)(((??)offset) ?? Vector3.zero));
				yield return (object)new WaitUntil((Func<bool>)(() => PlayerSpawnController.MoveToLogoutRoutine == null));
			}
		}

		[UsedImplicitly]
		public virtual bool OnLoginMatchZdoPrefab(ZDO zdo)
		{
			if (LoginPrefabHashCode == 0)
			{
				Logger.LogError((object)("Login Prefab Hash was zero, this likely means the mod " + Config.Name + " " + Config.Version + " has not properly been integrated for DynamicLoginIntegration"));
				return false;
			}
			return zdo.GetPrefab() == LoginPrefabHashCode;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

plugins\Shared.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Shared.Interfaces
{
	public interface PluginInfo
	{
		string Name { get; }

		string Version { get; }

		string Guid { get; }
	}
}
namespace Zolantris.Shared
{
	[AttributeUsage(AttributeTargets.Method)]
	public class MeasureTimeAttribute : Attribute
	{
	}
	public static class TimerUtility
	{
		public static void ExecuteWithTiming(Action action, [CallerMemberName] string methodName = "")
		{
		}

		public static void MeasureTimeWithAttribute(object instance, string methodName)
		{
			object instance2 = instance;
			MethodInfo method = instance2.GetType().GetMethod(methodName);
			if ((object)method != null && method.GetCustomAttribute<MeasureTimeAttribute>() != null)
			{
				ExecuteWithTiming(delegate
				{
					method.Invoke(instance2, null);
				}, methodName);
			}
			else
			{
				method?.Invoke(instance2, null);
			}
		}
	}
	public class BatchedLogger : MonoBehaviour
	{
		private static BatchedLogger? _instance;

		private static readonly Queue<string> _logQueue = new Queue<string>();

		private float _timer;

		public static bool IsLoggingEnabled { get; set; } = true;


		[UsedImplicitly]
		public static float BatchIntervalFrequencyInSeconds { get; set; } = 3f;


		public static BatchedLogger Instance
		{
			get
			{
				//IL_000c: 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_0021: Expected O, but got Unknown
				if (_instance == null)
				{
					GameObject val = new GameObject("Logger");
					_instance = val.AddComponent<BatchedLogger>();
					Object.DontDestroyOnLoad((Object)val);
				}
				return _instance;
			}
		}

		public void Log(string message)
		{
			_logQueue.Enqueue(message);
		}

		private void FlushLogs()
		{
			while (_logQueue.Count > 0)
			{
				Logger.LogInfo((object)_logQueue.Dequeue());
			}
		}
	}
}
namespace Zolantris.Shared.Debug
{
	public class DebugGui
	{
	}
	public class DebugSafeTimer
	{
		private bool _isRunning;

		private float _elapsedTime;

		private List<DebugSafeTimer>? _listRef;

		public float ElapsedMilliseconds => _elapsedTime * 1000f;

		public static DebugSafeTimer StartNew()
		{
			DebugSafeTimer debugSafeTimer = new DebugSafeTimer();
			debugSafeTimer.Start();
			return debugSafeTimer;
		}

		public static DebugSafeTimer StartNew(List<DebugSafeTimer> list)
		{
			DebugSafeTimer debugSafeTimer = new DebugSafeTimer();
			debugSafeTimer.Start();
			list.Add(debugSafeTimer);
			debugSafeTimer._listRef = list;
			return debugSafeTimer;
		}

		public static void UpdateTimersFromList(List<DebugSafeTimer> list)
		{
			if (list.Count == 0)
			{
				return;
			}
			DebugSafeTimer[] array = list.ToArray();
			foreach (DebugSafeTimer debugSafeTimer in array)
			{
				if (debugSafeTimer != null)
				{
					debugSafeTimer.Update();
				}
				else if (debugSafeTimer == null)
				{
					list.Remove(debugSafeTimer);
				}
			}
		}

		[UsedImplicitly]
		public void Start()
		{
			if (_listRef != null && !_listRef.Contains(this))
			{
				_listRef.Add(this);
			}
			_isRunning = true;
		}

		[UsedImplicitly]
		public void Stop()
		{
			_isRunning = false;
		}

		[UsedImplicitly]
		public void Reset()
		{
			if (_listRef != null && _listRef.Contains(this))
			{
				_listRef.Remove(this);
			}
			_elapsedTime = 0f;
			Stop();
		}

		[UsedImplicitly]
		public void Restart()
		{
			_elapsedTime = 0f;
			Start();
		}

		[UsedImplicitly]
		public void Clear()
		{
			Reset();
			if (_listRef == null)
			{
				Logger.LogWarning((object)"Called delete but listRef did not exist");
			}
			else
			{
				_listRef?.Remove(this);
			}
		}

		private void OnUpdateAutoExpire()
		{
			if (ElapsedMilliseconds > 20000f)
			{
				Clear();
			}
		}

		[UsedImplicitly]
		private void Update()
		{
			if (_isRunning)
			{
				_elapsedTime += Time.deltaTime;
			}
			OnUpdateAutoExpire();
		}
	}
}
namespace Zolantris.Shared.ModIntegrations
{
	public interface IModIntegrationApi
	{
		void RunIntegration();
	}
	public static class ConditionalImporter
	{
		public static bool ImportConditionally(string modGuid, string targetClass)
		{
			Type type = Type.GetType("Namespace.ParentClassName");
			if (type != null)
			{
				Logger.LogDebug((object)("Conditional " + modGuid + " found. " + targetClass + " will now run"));
				(Activator.CreateInstance(type) as IModIntegrationApi)?.RunIntegration();
				return true;
			}
			Logger.LogDebug((object)("Conditional " + modGuid + " not found. Exiting"));
			return false;
		}
	}
}
namespace Zolantris.Shared.BepInExAutoDoc
{
	public class BepInExConfigAutoDoc
	{
		public bool runOnRelease;

		public bool runOnDebug = true;

		private static readonly Regex ConfigMatchRegExp = new Regex("\\[(.*?)\\]");

		private static string? GetOutputFolderPath(PluginInfo plugin, string autoDocName)
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
			string directoryName2 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			Logger.LogDebug((object)("BepInExConfigAutoDoc: GetOutputFolderPath() " + directoryName));
			Logger.LogDebug((object)("BepInExConfigAutoDoc: GetOutputFolderPath() executingAssemblyLocation " + directoryName2));
			if (directoryName2 == null)
			{
				return null;
			}
			return Path.Combine(directoryName2, autoDocName + "_AutoDoc.md");
		}

		private static string StripString(string x)
		{
			return ConfigMatchRegExp.Match(x).Groups[1].Value;
		}

		private static void AutoWriteBepInExConfigDoc(PluginInfo plugin, ConfigFile Config, string documentName)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string text = "";
			foreach (ConfigDefinition key in Config.Keys)
			{
				if (key.Section != text)
				{
					text = key.Section;
					stringBuilder.Append(Environment.NewLine + "## " + key.Section + Environment.NewLine);
				}
				stringBuilder.Append(("\n### " + key.Key + " [" + StripString(Config[key].Description.Description) + "]").Replace("[]", "") + Environment.NewLine + "- Description: " + Config[key].Description.Description.Replace("[Synced with Server]", "").Replace("[Not Synced with Server]", "") + $"{Environment.NewLine}- Default Value: {Config[key].DefaultValue}{Environment.NewLine}");
			}
			string outputFolderPath = GetOutputFolderPath(plugin, documentName);
			if (outputFolderPath != null)
			{
				File.WriteAllText(outputFolderPath, stringBuilder.ToString());
			}
		}

		public void Generate(BaseUnityPlugin plugin, ConfigFile configFile, string documentName)
		{
			PluginInfo pluginInfoFromType = BepInExUtils.GetPluginInfoFromType(((object)plugin).GetType());
			Generate(pluginInfoFromType, configFile, documentName);
		}

		public void Generate(FileInfo pluginPath, ConfigFile configFile, string documentName)
		{
			PluginInfo pluginInfoFromPath = BepInExUtils.GetPluginInfoFromPath(pluginPath);
			Generate(pluginInfoFromPath, configFile, documentName);
		}

		public void Generate(PluginInfo pluginInfo, ConfigFile configFile, string documentName)
		{
			AutoWriteBepInExConfigDoc(pluginInfo, configFile, documentName);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

plugins\ValheimRAFT.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using Advize_PlantEasily;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using ComfyGizmo;
using DynamicLocations.API;
using DynamicLocations.Constants;
using DynamicLocations.Controllers;
using DynamicLocations.Structs;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.GUI;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using PlanBuild.Blueprints;
using PlanBuild.Blueprints.Components;
using PlanBuild.Plans;
using Registry;
using TMPro;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
using UnityEngine.U2D;
using UnityEngine.UI;
using ValheimRAFT;
using ValheimRAFT.Config;
using ValheimRAFT.Patches;
using ValheimRAFT.UI;
using ValheimRAFT.Util;
using ValheimVehicles.Attributes;
using ValheimVehicles.Config;
using ValheimVehicles.ConsoleCommands;
using ValheimVehicles.Controllers;
using ValheimVehicles.Helpers;
using ValheimVehicles.ModSupport;
using ValheimVehicles.Patches;
using ValheimVehicles.Prefabs;
using ValheimVehicles.Prefabs.Registry;
using ValheimVehicles.Propulsion.Rudder;
using ValheimVehicles.Propulsion.Sail;
using ValheimVehicles.SharedScripts;
using ValheimVehicles.Vehicles;
using ValheimVehicles.Vehicles.Components;
using ValheimVehicles.Vehicles.Controllers;
using ValheimVehicles.Vehicles.Enums;
using ValheimVehicles.Vehicles.Interfaces;
using ValheimVehicles.Vehicles.Structs;
using ZdoWatcher;
using Zolantris.Shared;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValheimRAFT")]
[assembly: AssemblyDescription("Valheim Mod for building on the sea, requires Jotunn to be installed.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Virtualize LLC")]
[assembly: AssemblyProduct("ValheimRAFT")]
[assembly: AssemblyCopyright("Copyright © 2023-2024, GNU-v3 licensed")]
[assembly: Guid("6015B165-2627-40A7-8CA1-3E6B6CD7CB49")]
[assembly: AssemblyFileVersion("2.5.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.5.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Components
{
	public class CustomToggleSwitch : ToggleSwitch
	{
		private void Awake()
		{
		}
	}
	public class LeverComponent
	{
	}
}
namespace Registry
{
	public class ShipKeelPrefab : IRegisterPrefab
	{
		public static readonly ShipKeelPrefab Instance = new ShipKeelPrefab();

		public void Register(PrefabManager prefabManager, PieceManager pieceManager)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_009d: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			GameObject val = prefabManager.CreateClonedPrefab("ValheimVehicles_ShipKeel", LoadValheimVehicleAssets.ShipKeelAsset);
			PrefabRegistryHelpers.HoistSnapPointsToPrefab(val, val.transform);
			PrefabRegistryHelpers.AddNetViewWithPersistence(val);
			PrefabRegistryHelpers.SetWearNTear(val);
			PrefabRegistryHelpers.AddPieceForPrefab("ValheimVehicles_ShipKeel", val);
			PrefabRegistryHelpers.PieceData valueSafe = GeneralExtensions.GetValueSafe<string, PrefabRegistryHelpers.PieceData>(PrefabRegistryHelpers.PieceDataDictionary, "ValheimVehicles_ShipKeel");
			PieceConfig val2 = new PieceConfig();
			val2.PieceTable = "Hammer";
			val2.Description = valueSafe.Description;
			val2.Icon = LoadValheimVehicleAssets.VehicleSprites.GetSprite("keel");
			val2.Category = "Raft";
			val2.Enabled = true;
			val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig
				{
					Amount = 10,
					Item = "Wood",
					Recover = true
				}
			};
			pieceManager.AddPiece(new CustomPiece(val, false, val2));
		}
	}
	public class VehiclePiecesPrefab : IRegisterPrefab
	{
		public static readonly VehiclePiecesPrefab Instance = new VehiclePiecesPrefab();

		public static GameObject VehiclePiecesContainer = null;

		public void RegisterPiecesContainer(PrefabManager prefabManager)
		{
			VehiclePiecesContainer = prefabManager.CreateClonedPrefab("ValheimVehicles_piecesContainer", LoadValheimVehicleAssets.VehiclePiecesAsset);
		}

		public void Register(PrefabManager prefabManager, PieceManager pieceManager)
		{
			RegisterPiecesContainer(prefabManager);
		}
	}
}
namespace ValheimVehicles.SharedScripts
{
	public enum AnchorState
	{
		Idle,
		Lowering,
		Anchored,
		Reeling,
		Recovered
	}
	public class AnchorMechanismController : ParentCollisionListener
	{
		public const int baseTextSize = 4;

		public static bool HasAnchorTextHud = true;

		public static float HideAnchorTimer = 3f;

		public static List<AnchorMechanismController> Instances = new List<AnchorMechanismController>();

		public int anchorTextSize = 4;

		public float anchorTextCharacterSize = 0.25f;

		public Transform rotationAnchorRopeAttachpoint;

		public Transform anchorRopeAttachmentPoint;

		public Transform anchorRopeAttachStartPoint;

		public Transform anchorReelTransform;

		public Transform anchorReelCogsTransform;

		public float anchorDropDistance = 10f;

		public float reelSpeed = 5f;

		public float reelCogAngleMult = 100f;

		public Transform anchorTransform;

		public AnchorState currentState = AnchorState.Recovered;

		public LineRenderer ropeLine;

		public Rigidbody prefabRigidbody;

		public bool CanUseHotkeys = true;

		public TextMeshPro anchorStateTextMesh;

		private readonly Color messageColor = new Color(249f, 224f, 0f, 255f);

		private Rigidbody anchorRb;

		private Vector3 anchorStartLocalPosition;

		private Transform anchorTextMeshProTransform;

		private float messageFadeValue = 255f;

		private float timePassedSinceStateUpdate;

		internal void Awake()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefabRigidbody == (Object)null)
			{
				prefabRigidbody = ((Component)((Component)this).transform).GetComponent<Rigidbody>();
				if (Object.op_Implicit((Object)(object)prefabRigidbody))
				{
					prefabRigidbody.Sleep();
				}
			}
			if ((Object)(object)anchorTransform == (Object)null)
			{
				anchorTransform = ((Component)this).transform.Find("anchor");
			}
			if ((Object)(object)anchorRopeAttachmentPoint == (Object)null)
			{
				anchorRopeAttachmentPoint = anchorTransform.Find("attachpoint_anchor");
			}
			if ((Object)(object)rotationAnchorRopeAttachpoint == (Object)null)
			{
				rotationAnchorRopeAttachpoint = ((Component)this).transform.Find("attachpoint_rotational");
			}
			if ((Object)(object)anchorRopeAttachStartPoint == (Object)null)
			{
				anchorRopeAttachStartPoint = ((Component)this).transform.Find("attachpoint_anchor_start");
			}
			anchorTextMeshProTransform = ((Component)this).transform.Find("hover_anchor_state_message");
			anchorStateTextMesh = ((Component)anchorTextMeshProTransform).gameObject.AddComponent<TextMeshPro>();
			((Graphic)anchorStateTextMesh).color = messageColor;
			((TMP_Text)anchorStateTextMesh).fontStyle = (FontStyles)33;
			((TMP_Text)anchorStateTextMesh).alignment = (TextAlignmentOptions)514;
			((TMP_Text)anchorStateTextMesh).outlineWidth = 0.136f;
			((TMP_Text)anchorStateTextMesh).fontSize = 4f;
			((Component)anchorTransform.Find("scalar/colliders")).gameObject.AddComponent<ChildCollisionDetector>();
			anchorReelTransform = ((Component)this).transform.Find("anchor_reel");
			anchorReelCogsTransform = ((Component)this).transform.Find("anchor_reel/cogs");
			anchorRb = ((Component)anchorTransform).GetComponent<Rigidbody>();
			anchorStartLocalPosition = ((Component)anchorRb).transform.localPosition;
		}

		private void Start()
		{
			if ((Object)(object)ropeLine == (Object)null)
			{
				ropeLine = ((Component)this).GetComponent<LineRenderer>();
			}
			UpdateRopeVisual();
			UpdateAnchorState(AnchorState.Recovered);
		}

		private void Update()
		{
			if (CanUseHotkeys)
			{
				HandleKeyInputs();
			}
		}

		public virtual void FixedUpdate()
		{
			//IL_004e: 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)
			if (!((Object)(object)anchorRb == (Object)null))
			{
				switch (currentState)
				{
				case AnchorState.Lowering:
					DropAnchor();
					break;
				case AnchorState.Reeling:
					ReelAnchor();
					break;
				case AnchorState.Idle:
				case AnchorState.Recovered:
					((Component)anchorRb).transform.localPosition = anchorStartLocalPosition;
					((Component)anchorRb).transform.localRotation = Quaternion.identity;
					break;
				}
				UpdateRopeVisual();
				UpdateText();
			}
		}

		internal void OnEnable()
		{
			Instances.Add(this);
		}

		internal void OnDisable()
		{
			Instances.Remove(this);
		}

		public void SetScaledTextSize()
		{
			anchorTextSize = Mathf.RoundToInt((float)Mathf.Clamp(DisplayScaledValues.GetScaledSize(), 4, 16));
			((TMP_Text)anchorStateTextMesh).fontSize = anchorTextSize;
		}

		public override void OnChildCollisionEnter(Collision collision)
		{
			if (currentState == AnchorState.Lowering && collision.gameObject.layer == LayerMask.NameToLayer("terrain"))
			{
				UpdateAnchorState(AnchorState.Anchored);
			}
		}

		public virtual string GetCurrentStateText()
		{
			return currentState.ToString();
		}

		private void hideAnchorText()
		{
			if (((Component)anchorTextMeshProTransform).gameObject.activeInHierarchy)
			{
				((Component)anchorTextMeshProTransform).gameObject.SetActive(false);
			}
		}

		private void showAnchorText()
		{
			if (!((Component)anchorTextMeshProTransform).gameObject.activeSelf)
			{
				((Component)anchorTextMeshProTransform).gameObject.SetActive(true);
			}
		}

		public bool ShouldHideAfterLastStateUpdate()
		{
			if (Mathf.Approximately(HideAnchorTimer, 0f))
			{
				return false;
			}
			return timePassedSinceStateUpdate > HideAnchorTimer;
		}

		private void UpdateText()
		{
			//IL_00d8: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			if (!HasAnchorTextHud || ShouldHideAfterLastStateUpdate())
			{
				hideAnchorText();
				return;
			}
			showAnchorText();
			if (HideAnchorTimer != 0f)
			{
				timePassedSinceStateUpdate += Time.fixedDeltaTime;
			}
			if ((Object)(object)anchorTextMeshProTransform != (Object)null && (Object)(object)Camera.main != (Object)null)
			{
				float num = HideAnchorTimer * 0.1f;
				if (timePassedSinceStateUpdate > num)
				{
					float num2 = Mathf.InverseLerp(num, HideAnchorTimer, timePassedSinceStateUpdate);
					messageFadeValue = Mathf.Lerp(1f, 0f, num2);
					((Graphic)anchorStateTextMesh).color = new Color(messageColor.r, messageColor.g, messageColor.b, messageFadeValue);
				}
				else
				{
					((Graphic)anchorStateTextMesh).color = messageColor;
				}
				anchorTextMeshProTransform.LookAt(((Component)Camera.main).transform);
				((TMP_Text)anchorStateTextMesh).text = GetCurrentStateText();
				anchorTextMeshProTransform.rotation = Quaternion.LookRotation(anchorTextMeshProTransform.forward * -1f);
			}
		}

		public virtual void OnAnchorStateChange(AnchorState newState)
		{
		}

		internal void UpdateAnchorState(AnchorState newState)
		{
			if (newState != currentState)
			{
				timePassedSinceStateUpdate = 0f;
				currentState = newState;
				AnchorState anchorState = currentState;
				if ((uint)anchorState <= 4u)
				{
					anchorRb.isKinematic = true;
				}
				OnAnchorStateChange(currentState);
			}
		}

		private void HandleKeyInputs()
		{
			if ((Object)(object)anchorRb == (Object)null)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)100))
			{
				if (currentState != AnchorState.Lowering)
				{
					StartDropping();
				}
				else
				{
					StopDropping();
				}
			}
			if (Input.GetKeyDown((KeyCode)114))
			{
				if (currentState != AnchorState.Reeling)
				{
					StartReeling();
				}
				else
				{
					StopReeling();
				}
			}
		}

		public void StartDropping()
		{
			if (!((Object)(object)anchorRb == (Object)null) && currentState != AnchorState.Lowering)
			{
				UpdateAnchorState(AnchorState.Lowering);
			}
		}

		public void StopDropping()
		{
			if (!((Object)(object)anchorRb == (Object)null) && currentState == AnchorState.Lowering)
			{
				UpdateAnchorState(AnchorState.Anchored);
			}
		}

		public void StartReeling()
		{
			if (!((Object)(object)anchorRb == (Object)null) && currentState != AnchorState.Reeling)
			{
				UpdateAnchorState(AnchorState.Reeling);
			}
		}

		public void StopReeling()
		{
			if (!((Object)(object)anchorRb == (Object)null) && currentState == AnchorState.Reeling)
			{
				UpdateAnchorState(AnchorState.Recovered);
			}
		}

		private void DropAnchor()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (anchorRopeAttachmentPoint.position.y > rotationAnchorRopeAttachpoint.position.y - anchorDropDistance)
			{
				float num = reelSpeed * 1.5f * Time.fixedDeltaTime;
				anchorRb.MovePosition(anchorRb.position + Vector3.down * num);
				Quaternion val = Quaternion.Euler((0f - reelCogAngleMult) * num, 0f, 0f);
				Transform obj = anchorReelCogsTransform;
				obj.localRotation *= val;
			}
			else
			{
				StopDropping();
			}
		}

		private void ReelAnchor()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_006b: 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)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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 (anchorRopeAttachmentPoint.position.y < anchorRopeAttachStartPoint.position.y)
			{
				float num = reelSpeed * Time.fixedDeltaTime;
				anchorRb.MovePosition(anchorRb.position + Vector3.up * num);
				Quaternion val = Quaternion.Euler((0f - reelCogAngleMult) * num, 0f, 0f);
				Transform obj = anchorReelCogsTransform;
				obj.localRotation *= val;
				if (anchorRopeAttachmentPoint.position.y > anchorRopeAttachStartPoint.position.y)
				{
					StopReeling();
				}
			}
			else
			{
				StopReeling();
			}
		}

		private void UpdateRopeVisual()
		{
			//IL_004d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0069: 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)
			//IL_0075: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ropeLine == (Object)null))
			{
				ropeLine.useWorldSpace = false;
				ropeLine.startWidth = 0.2f;
				ropeLine.endWidth = 0.2f;
				Transform transform = ((Component)ropeLine).transform;
				Vector3 item = transform.InverseTransformPoint(rotationAnchorRopeAttachpoint.position);
				Vector3 val = transform.InverseTransformPoint(anchorRopeAttachStartPoint.position);
				Vector3 val2 = transform.InverseTransformPoint(anchorRopeAttachmentPoint.position);
				int num = Mathf.Clamp(Mathf.RoundToInt(Vector3.Distance(val, val2) / 2f) + 1, 3, 40);
				List<Vector3> list = new List<Vector3>();
				list.Add(item);
				list.Add(val);
				for (int i = 1; i < num; i++)
				{
					float num2 = (float)i / (float)(num - 1);
					Vector3 item2 = Vector3.Lerp(val, val2, num2);
					list.Add(item2);
				}
				list.Add(val2);
				ropeLine.positionCount = list.Count;
				ropeLine.SetPositions(list.ToArray());
			}
		}

		public static bool IsAnchorStateValid(AnchorState anchorState)
		{
			if ((uint)anchorState <= 4u)
			{
				return true;
			}
			return false;
		}

		public static AnchorState GetSafeAnchorState(int anchorStateInt)
		{
			if ((uint)anchorStateInt <= 4u)
			{
				return (AnchorState)anchorStateInt;
			}
			return AnchorState.Recovered;
		}
	}
	public class ChildCollisionDetector : MonoBehaviour
	{
		private ParentCollisionListener parentCollisionListener;

		public bool hasCollisionStayListener;

		private void Start()
		{
			parentCollisionListener = ((Component)this).GetComponentInParent<ParentCollisionListener>();
		}

		private void OnCollisionEnter(Collision collision)
		{
			if ((Object)(object)parentCollisionListener != (Object)null)
			{
				parentCollisionListener.OnChildCollisionEnter(collision);
			}
		}

		private void OnCollisionStay(Collision collision)
		{
			if (hasCollisionStayListener && (Object)(object)parentCollisionListener != (Object)null)
			{
				parentCollisionListener.OnChildCollisionStay(collision);
			}
		}

		private void OnCollisionExit(Collision collision)
		{
			if ((Object)(object)parentCollisionListener != (Object)null)
			{
				parentCollisionListener.OnChildCollisionExit(collision);
			}
		}
	}
	public class ConvexHullAPI : MonoBehaviour
	{
		public enum PreviewModes
		{
			None,
			Debug,
			Bubble
		}

		private static readonly ConvexHullCalculator convexHullCalculator = new ConvexHullCalculator();

		public static bool CanRenderBubble = true;

		public static bool HasInitialized = false;

		[CanBeNull]
		public static Material DebugMaterial;

		[CanBeNull]
		public static Material BubbleMaterial;

		public static Color DebugMaterialColor = new Color(0.1f, 0.23f, 0.5f, 0.2f);

		public static Color BubbleMaterialColor = new Color(0f, 0.4f, 0.4f, 0.8f);

		public static Action<string> LoggerAPI = Debug.Log;

		public static bool UseWorld = true;

		public static string MeshNamePrefix = "ConvexHull";

		public static bool ShouldOptimizeGeneratedMeshes = false;

		public static List<ConvexHullAPI> Instances = new List<ConvexHullAPI>();

		public static readonly int MaxHeightShaderId = Shader.PropertyToID("_MaxHeight");

		public static readonly string MeshNamePreviewPrefix = MeshNamePrefix + "_Preview";

		public static string MeshNameTriggerPrefix = MeshNamePrefix + "_Preview";

		public PreviewModes PreviewMode = PreviewModes.Bubble;

		[FormerlySerializedAs("sphereEncapsulationBuffer")]
		public float wrapperBuffer = 0.5f;

		public Vector3 transformPreviewOffset = Vector3.zero;

		[FormerlySerializedAs("ConvexHullMaterialOverride")]
		[CanBeNull]
		public Material m_fallbackMaterial;

		public bool CanLog;

		public Vector3 previewScale = Vector3.one;

		public Transform PreviewParent;

		private List<Vector3> _cachedPoints = new List<Vector3>();

		[NonSerialized]
		public List<MeshCollider> convexHullMeshColliders = new List<MeshCollider>();

		[NonSerialized]
		public List<GameObject> convexHullMeshes = new List<GameObject>();

		[NonSerialized]
		public List<GameObject> convexHullPreviewMeshes = new List<GameObject>();

		[NonSerialized]
		public List<MeshRenderer> convexHullPreviewMeshRendererItems = new List<MeshRenderer>();

		[NonSerialized]
		public List<GameObject> convexHullTriggerMeshes = new List<GameObject>();

		private void Awake()
		{
			if ((Object)(object)m_fallbackMaterial != (Object)null && (Object)(object)BubbleMaterial == (Object)null)
			{
				BubbleMaterial = m_fallbackMaterial;
			}
			if ((Object)(object)m_fallbackMaterial != (Object)null && (Object)(object)DebugMaterial == (Object)null)
			{
				DebugMaterial = m_fallbackMaterial;
			}
			PreviewParent = ((Component)this).transform;
		}

		private void OnEnable()
		{
			if (!Instances.Contains(this))
			{
				Instances.Add(this);
			}
		}

		private void OnDisable()
		{
			if (Instances.Contains(this))
			{
				Instances.Remove(this);
				DeleteMeshesFromChildColliders(convexHullMeshes);
				DeleteMeshesFromChildColliders(convexHullPreviewMeshes);
				convexHullPreviewMeshRendererItems.Clear();
				convexHullMeshes.Clear();
			}
		}

		public void InitializeConvexMeshGeneratorApi(PreviewModes mode, Material debugMaterial, Material bubbleMaterial, Color debugMaterialColor, Color bubbleMaterialColor, string meshNamePrefix, Action<string> loggerApi)
		{
			//IL_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			MeshNamePrefix = meshNamePrefix;
			LoggerAPI = loggerApi;
			PreviewMode = mode;
			DebugMaterial = debugMaterial;
			DebugMaterialColor = debugMaterialColor;
			BubbleMaterial = bubbleMaterial;
			BubbleMaterialColor = bubbleMaterialColor;
		}

		public virtual bool IsAllowedAsHullOverride(string val)
		{
			return false;
		}

		public void UpdatePropertiesForConvexHulls(Vector3 transformPreviewOffset, PreviewModes mode, Color debugColor, Color bubbleColor)
		{
			//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_000f: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			PreviewMode = mode;
			DebugMaterialColor = debugColor;
			BubbleMaterialColor = bubbleColor;
			foreach (ConvexHullAPI instance in Instances)
			{
				instance.transformPreviewOffset = transformPreviewOffset;
				instance.CreatePreviewConvexHullMeshes();
			}
		}

		public static List<Vector3> GetCapsuleColliderVertices(CapsuleCollider capsuleCollider)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: 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)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			Vector3 center = capsuleCollider.center;
			float radius = capsuleCollider.radius;
			float height = capsuleCollider.height;
			Vector3 val;
			Vector3 val2;
			Vector3 val3;
			switch (capsuleCollider.direction)
			{
			case 0:
				val = Vector3.right;
				val2 = Vector3.up;
				val3 = Vector3.forward;
				break;
			case 1:
				val = Vector3.up;
				val2 = Vector3.forward;
				val3 = Vector3.right;
				break;
			case 2:
				val = Vector3.forward;
				val2 = Vector3.up;
				val3 = Vector3.right;
				break;
			default:
				throw new ArgumentException("Invalid capsule direction");
			}
			float num = (height - 2f * radius) * 0.5f;
			int num2 = 12;
			int num3 = 6;
			Vector3 val4 = default(Vector3);
			for (int i = 0; i <= num3; i++)
			{
				float num4 = (float)Math.PI * (float)i / (float)num3;
				float num5 = Mathf.Sin(num4);
				float num6 = Mathf.Cos(num4);
				for (int j = 0; j <= num2; j++)
				{
					float num7 = (float)Math.PI * 2f * (float)j / (float)num2;
					float num8 = Mathf.Sin(num7);
					float num9 = Mathf.Cos(num7);
					((Vector3)(ref val4))..ctor(num5 * num9, num6, num5 * num8);
					Vector3 item = center + val * (num + radius) + val4 * radius;
					Vector3 item2 = center - val * (num + radius) + val4 * radius;
					list.Add(item);
					list.Add(item2);
				}
			}
			for (int k = 0; k <= num2; k++)
			{
				float num10 = (float)Math.PI * 2f * (float)k / (float)num2;
				float num11 = Mathf.Sin(num10);
				float num12 = Mathf.Cos(num10);
				Vector3 val5 = center + (val2 * num11 + val3 * num12) * radius;
				Vector3 item3 = val5 + val * num;
				Vector3 item4 = val5 - val * num;
				list.Add(item3);
				list.Add(item4);
			}
			for (int l = 0; l < list.Count; l++)
			{
				list[l] = ((Component)capsuleCollider).transform.TransformPoint(list[l]);
			}
			return list;
		}

		public static List<Vector3> GetMeshColliderVertices(MeshCollider meshCollider)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			Transform transform = ((Component)meshCollider).transform;
			List<Vector3> list = new List<Vector3>();
			Mesh val = (Mesh)(meshCollider.sharedMesh.isReadable ? ((object)meshCollider.sharedMesh) : ((object)CreateReadableMesh(meshCollider.sharedMesh)));
			if ((Object)(object)val != (Object)null)
			{
				Vector3[] vertices = val.vertices;
				foreach (Vector3 val2 in vertices)
				{
					Vector3 item = transform.TransformPoint(val2);
					list.Add(item);
				}
			}
			return list;
		}

		public static List<Vector3> GetColliderPointsLocal(Collider collider)
		{
			//IL_000c: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			Vector3 localScale = ((Component)collider).transform.localScale;
			MeshCollider val = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
			if (val != null && (Object)(object)val.sharedMesh != (Object)null)
			{
				Vector3[] vertices = val.sharedMesh.vertices;
				foreach (Vector3 val2 in vertices)
				{
					list.Add(Vector3.Scale(val2, localScale));
				}
			}
			else
			{
				BoxCollider val3 = (BoxCollider)(object)((collider is BoxCollider) ? collider : null);
				if (val3 != null)
				{
					Vector3 val4 = Vector3.Scale(val3.center, localScale);
					Vector3 val5 = Vector3.Scale(val3.size * 0.5f, localScale);
					Vector3[] collection = (Vector3[])(object)new Vector3[8]
					{
						val4 + new Vector3(0f - val5.x, 0f - val5.y, 0f - val5.z),
						val4 + new Vector3(0f - val5.x, 0f - val5.y, val5.z),
						val4 + new Vector3(0f - val5.x, val5.y, 0f - val5.z),
						val4 + new Vector3(0f - val5.x, val5.y, val5.z),
						val4 + new Vector3(val5.x, 0f - val5.y, 0f - val5.z),
						val4 + new Vector3(val5.x, 0f - val5.y, val5.z),
						val4 + new Vector3(val5.x, val5.y, 0f - val5.z),
						val4 + new Vector3(val5.x, val5.y, val5.z)
					};
					list.AddRange(collection);
				}
				else
				{
					SphereCollider val6 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null);
					if (val6 != null)
					{
						Vector3 val7 = Vector3.Scale(val6.center, localScale);
						float num = val6.radius * Mathf.Max(new float[3] { localScale.x, localScale.y, localScale.z });
						for (int j = 0; j <= 10; j++)
						{
							float num2 = (float)Math.PI * (float)j / 10f;
							float num3 = Mathf.Sin(num2);
							float num4 = Mathf.Cos(num2);
							for (int k = 0; k <= 20; k++)
							{
								float num5 = (float)Math.PI * 2f * (float)k / 20f;
								float num6 = num * num3 * Mathf.Cos(num5);
								float num7 = num * num4;
								float num8 = num * num3 * Mathf.Sin(num5);
								list.Add(val7 + new Vector3(num6, num7, num8));
							}
						}
					}
					else
					{
						CapsuleCollider val8 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null);
						if (val8 != null)
						{
							list.AddRange(GetCapsuleColliderVertices(val8));
						}
						else
						{
							Debug.LogWarning((object)$"Unsupported collider type: {((object)collider).GetType()}");
						}
					}
				}
			}
			return list;
		}

		private static List<Vector3> GetSphereColliderPoints(SphereCollider sphereCollider)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			Transform transform = ((Component)sphereCollider).transform;
			Vector3 val = transform.position + transform.rotation * sphereCollider.center;
			Vector3 lossyScale = transform.lossyScale;
			float num = sphereCollider.radius * Mathf.Max(new float[3] { lossyScale.x, lossyScale.y, lossyScale.z });
			int num2 = 12;
			for (int i = 0; i < num2; i++)
			{
				float num3 = (float)i * (float)Math.PI * 2f / (float)num2;
				for (int j = 0; j <= num2 / 2; j++)
				{
					float num4 = (float)j * (float)Math.PI / (float)(num2 / 2);
					Vector3 val2 = new Vector3(Mathf.Sin(num4) * Mathf.Cos(num3), Mathf.Sin(num4) * Mathf.Sin(num3), Mathf.Cos(num4)) * num;
					Vector3 item = val + val2;
					list.Add(item);
				}
			}
			return list;
		}

		private static List<Vector3> GetBoxColliderVertices(BoxCollider boxCollider)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_004f: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_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)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)boxCollider).transform;
			List<Vector3> list = new List<Vector3>();
			Vector3 val = transform.TransformPoint(boxCollider.center);
			Vector3 size = boxCollider.size;
			Vector3 one = Vector3.one;
			Transform val2 = transform;
			while ((Object)(object)val2 != (Object)null)
			{
				((Vector3)(ref one)).Scale(val2.localScale);
				val2 = val2.parent;
			}
			Vector3 val3 = Vector3.Scale(size, one);
			for (int i = -1; i <= 1; i += 2)
			{
				for (int j = -1; j <= 1; j += 2)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						Vector3 val4 = new Vector3((float)i * val3.x, (float)j * val3.y, (float)k * val3.z) * 0.5f;
						Vector3 item = val + transform.rotation * val4;
						list.Add(item);
					}
				}
			}
			return list;
		}

		private static List<Vector3> GetColliderPointsGlobal(Collider collider)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			if (!LayerHelpers.IsContainedWithinMask(((Component)collider).gameObject.layer, LayerHelpers.PhysicalLayers) || !((Component)collider).gameObject.activeInHierarchy)
			{
				return new List<Vector3>();
			}
			BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null);
			if (val == null)
			{
				SphereCollider val2 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null);
				if (val2 == null)
				{
					CapsuleCollider val3 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null);
					if (val3 == null)
					{
						MeshCollider val4 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
						if (val4 != null)
						{
							list.AddRange(GetMeshColliderVertices(val4));
						}
					}
					else
					{
						list.AddRange(GetCapsuleColliderVertices(val3));
					}
				}
				else
				{
					list.AddRange(GetSphereColliderPoints(val2));
				}
			}
			else
			{
				list.AddRange(GetBoxColliderVertices(val));
			}
			return list;
		}

		public static List<Vector3> ConvertToRelativeSpace(Collider collider, List<Vector3> localPoints)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			foreach (Vector3 localPoint in localPoints)
			{
				list.Add(localPoint + ((Component)collider).transform.localPosition);
			}
			return list;
		}

		public static List<Vector3> ConvertToWorldSpace(Collider collider, List<Vector3> localPoints)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			List<Vector3> list = new List<Vector3>();
			foreach (Vector3 localPoint in localPoints)
			{
				list.Add(((Component)collider).transform.TransformPoint(localPoint));
			}
			return list;
		}

		public static List<Vector3> GetColliderPointsLocal(List<Collider> colliders)
		{
			return colliders.SelectMany(GetColliderPointsLocal).Distinct().ToList();
		}

		public static List<Vector3> GetAllColliderPointsAsWorldPoints(List<Collider> colliders)
		{
			return colliders.SelectMany(GetColliderPointsGlobal).Distinct().ToList();
		}

		public static List<Vector3> GetColliderPointsRelative(List<Collider> colliders)
		{
			return colliders.SelectMany((Collider collider) => ConvertToRelativeSpace(collider, GetColliderPointsLocal(collider))).Distinct().ToList();
		}

		private static bool IsAllowedAsHullDefault(string input)
		{
			if (input.Contains("floor") || input.Contains("wall") || input.Contains("hull"))
			{
				return true;
			}
			return false;
		}

		public bool IsAllowedAsHull(GameObject go)
		{
			string text = ((Object)go).name.ToLower();
			if (!IsAllowedAsHullOverride(text))
			{
				return IsAllowedAsHullDefault(text);
			}
			return true;
		}

		public void GenerateUnderwaterBoxWrapper()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			foreach (MeshCollider item in convexHullMeshColliders.ToList())
			{
				if ((Object)(object)item == (Object)null)
				{
					convexHullMeshColliders.Remove(item);
					continue;
				}
				EncapsulateMeshCollider(item, wrapperBuffer, out var boxCenter, out var boxSize);
				CreateEncapsulationBox(boxCenter, boxSize);
			}
		}

		private void EncapsulateMeshCollider(MeshCollider collider, float buffer, out Vector3 boxCenter, out Vector3 boxSize)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_001b: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			//IL_0071: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_008a: 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_0099: 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_00a1: 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)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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)
			Mesh sharedMesh = collider.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null)
			{
				Debug.LogError((object)"MeshCollider does not have a valid mesh.");
				boxCenter = Vector3.zero;
				boxSize = Vector3.zero;
				return;
			}
			Vector3[] vertices = sharedMesh.vertices;
			Transform transform = ((Component)collider).transform;
			Vector3 val = Vector3.positiveInfinity;
			Vector3 val2 = Vector3.negativeInfinity;
			Vector3[] array = vertices;
			foreach (Vector3 val3 in array)
			{
				Vector3 val4 = transform.TransformPoint(val3);
				val = Vector3.Min(val, val4);
				val2 = Vector3.Max(val2, val4);
			}
			boxCenter = (val + val2) / 2f;
			boxSize = val2 - val;
			boxSize += new Vector3(buffer, buffer, buffer);
		}

		private void CreateEncapsulationBox(Vector3 center, Vector3 size)
		{
			//IL_0028: 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)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val).name = "VehicleShip_HullUnderwaterBox";
			val.gameObject.layer = LayerHelpers.IgnoreRaycastLayer;
			val.transform.position = center;
			val.transform.localScale = size;
			val.transform.SetParent(PreviewParent);
			Renderer component = val.GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				component.material = GetMaterial();
				component.shadowCastingMode = (ShadowCastingMode)0;
				component.receiveShadows = false;
				component.lightProbeUsage = (LightProbeUsage)0;
				component.reflectionProbeUsage = (ReflectionProbeUsage)0;
			}
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
			convexHullPreviewMeshes.Add(val);
		}

		public static List<Collider> FilterColliders(List<Collider> colliders)
		{
			if (colliders != null && colliders.Count > 0)
			{
				colliders = colliders.Where((Collider x) => LayerHelpers.IsContainedWithinMask(((Component)x).gameObject.layer, LayerHelpers.PhysicalLayers) && ((Component)x).gameObject.activeInHierarchy).ToList();
			}
			return colliders;
		}

		private List<List<Collider>> GroupCollidersByProximity(List<GameObject> gameObjects, float proximityThreshold)
		{
			List<Collider> list = new List<Collider>();
			foreach (GameObject gameObject in gameObjects)
			{
				if ((Object)(object)gameObject == (Object)null || !IsAllowedAsHull(gameObject))
				{
					continue;
				}
				Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(false);
				if (componentsInChildren != null)
				{
					List<Collider> list2 = FilterColliders(componentsInChildren.ToList());
					if (list2 != null && list2.Count > 0)
					{
						list.AddRange(componentsInChildren);
					}
				}
			}
			List<List<Collider>> list3 = new List<List<Collider>>();
			foreach (Collider item in list)
			{
				bool flag = false;
				foreach (List<Collider> item2 in list3)
				{
					if (IsColliderNearCluster(item, item2, proximityThreshold))
					{
						item2.Add(item);
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					list3.Add(new List<Collider> { item });
				}
			}
			MergeNearbyClusters(list3, proximityThreshold);
			return list3;
		}

		private static bool IsColliderNearCluster(Collider collider, List<Collider> cluster, float proximityThreshold)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			//IL_0040: 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_0047: 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)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			foreach (Collider item in cluster)
			{
				Bounds bounds = collider.bounds;
				if (((Bounds)(ref bounds)).Intersects(item.bounds))
				{
					return true;
				}
				bounds = collider.bounds;
				Vector3 val = item.ClosestPoint(((Bounds)(ref bounds)).center);
				bounds = collider.bounds;
				if (Vector3.Distance(((Bounds)(ref bounds)).center, val) <= proximityThreshold)
				{
					return true;
				}
			}
			return false;
		}

		private static void MergeNearbyClusters(List<List<Collider>> clusters, float proximityThreshold)
		{
			bool flag;
			do
			{
				flag = false;
				for (int i = 0; i < clusters.Count; i++)
				{
					for (int j = i + 1; j < clusters.Count; j++)
					{
						if (AreClustersNearEachOther(clusters[i], clusters[j], proximityThreshold))
						{
							clusters[i].AddRange(clusters[j]);
							clusters.RemoveAt(j);
							flag = true;
							break;
						}
					}
					if (flag)
					{
						break;
					}
				}
			}
			while (flag);
		}

		private static bool AreClustersNearEachOther(List<Collider> cluster1, List<Collider> cluster2, float proximityThreshold)
		{
			//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_0030: 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_0048: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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)
			foreach (Collider item in cluster1)
			{
				foreach (Collider item2 in cluster2)
				{
					Bounds bounds = item.bounds;
					if (((Bounds)(ref bounds)).Intersects(item2.bounds))
					{
						return true;
					}
					bounds = item2.bounds;
					Vector3 val = item.ClosestPoint(((Bounds)(ref bounds)).center);
					bounds = item2.bounds;
					if (Vector3.Distance(((Bounds)(ref bounds)).center, val) <= proximityThreshold)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static void DeleteMeshesFromChildColliders(List<GameObject> generateObjectList)
		{
			if (generateObjectList.Count == 0)
			{
				return;
			}
			List<GameObject> list = generateObjectList.ToList();
			generateObjectList.Clear();
			foreach (GameObject item in list)
			{
				DebugUnityHelpers.AdaptiveDestroy((Object)(object)item);
			}
		}

		public static List<GameObject> GetAllChildGameObjects(GameObject parentGo, int depth = 0, int maxDepth = 0)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			List<GameObject> list = new List<GameObject>();
			foreach (Transform item in parentGo.transform)
			{
				Transform val = item;
				list.Add(((Component)val).gameObject);
				if (depth < maxDepth)
				{
					list.AddRange(GetAllChildGameObjects(((Component)val).gameObject, depth + 1, maxDepth));
				}
			}
			return list;
		}

		public void GenerateMeshesFromChildColliders(GameObject targetParentGameObject, float distanceThreshold, List<GameObject> childGameObjects, Transform? triggerParent = null)
		{
			if (convexHullMeshes.Count > 0)
			{
				DeleteMeshesFromChildColliders(convexHullMeshes);
				convexHullMeshColliders.Clear();
			}
			foreach (List<Collider> item in GroupCollidersByProximity(childGameObjects.ToList(), distanceThreshold))
			{
				List<Vector3> points = (UseWorld ? GetAllColliderPointsAsWorldPoints(item) : GetColliderPointsLocal(item));
				GenerateConvexHullMesh(points, targetParentGameObject.transform);
			}
			CreatePreviewConvexHullMeshes();
			if ((Object)(object)triggerParent != (Object)null)
			{
				CreateTriggerConvexHullMeshes(triggerParent);
			}
		}

		private static Mesh CreateReadableMesh(Mesh sourceMesh)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_001d: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				vertices = sourceMesh.vertices,
				triangles = sourceMesh.triangles,
				normals = sourceMesh.normals,
				uv = sourceMesh.uv
			};
			val.RecalculateBounds();
			return val;
		}

		public Material? GetMaterial()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (PreviewMode == PreviewModes.Bubble && (Object)(object)BubbleMaterial != (Object)null)
			{
				BubbleMaterial.color = BubbleMaterialColor;
				BubbleMaterial.SetFloat(MaxHeightShaderId, 29f);
				return BubbleMaterial;
			}
			if (PreviewMode == PreviewModes.Debug && (Object)(object)DebugMaterial != (Object)null)
			{
				DebugMaterial.color = DebugMaterialColor;
				return DebugMaterial;
			}
			return null;
		}

		public void AddConvexHullMeshRenderer(GameObject go, bool isPreview = false)
		{
			//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_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_0087: 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)
			if (PreviewMode == PreviewModes.None)
			{
				return;
			}
			Material material = GetMaterial();
			if ((Object)(object)material != (Object)null)
			{
				MeshRenderer val = go.GetComponent<MeshRenderer>();
				if (!Object.op_Implicit((Object)(object)val))
				{
					val = go.AddComponent<MeshRenderer>();
				}
				convexHullPreviewMeshRendererItems.Add(val);
				((Renderer)val).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val).receiveShadows = false;
				((Renderer)val).lightProbeUsage = (LightProbeUsage)0;
				((Renderer)val).reflectionProbeUsage = (ReflectionProbeUsage)0;
				((Renderer)val).sharedMaterial = material;
				if (PreviewMode == PreviewModes.Debug && ((Renderer)val).sharedMaterial.color != DebugMaterialColor)
				{
					((Renderer)val).sharedMaterial.color = DebugMaterialColor;
				}
				if (PreviewMode == PreviewModes.Bubble && ((Renderer)val).sharedMaterial.color != BubbleMaterialColor)
				{
					((Renderer)val).sharedMaterial.color = BubbleMaterialColor;
				}
			}
		}

		public void CreateTriggerConvexHullMeshes(Transform triggerParent)
		{
			//IL_0062: 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)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			DeleteMeshesFromChildColliders(convexHullTriggerMeshes);
			convexHullTriggerMeshes.Clear();
			Rigidbody val = ((Component)PreviewParent).GetComponent<Rigidbody>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)PreviewParent).GetComponentInParent<Rigidbody>();
			}
			if ((Object)(object)val != (Object)null && !val.isKinematic)
			{
				LoggerAPI("Error: This component is invalid due to preview parent containing a non-kinematic Rigidbody. Using a non-kinematic rigidbody will cause this preview to desync.");
				return;
			}
			if ((Object)(object)val != (Object)null)
			{
				val.includeLayers = LayerHelpers.PhysicalLayers;
				val.excludeLayers = LayerHelpers.RamColliderExcludeLayers;
			}
			if ((Object)(object)triggerParent == (Object)null)
			{
				LoggerAPI("Error: triggerParent is null.");
			}
			else
			{
				if (convexHullMeshes.Count <= 0)
				{
					return;
				}
				for (int i = 0; i < convexHullMeshes.Count; i++)
				{
					GameObject obj = convexHullMeshes[i];
					GameObject val2 = Object.Instantiate<GameObject>(obj, triggerParent);
					convexHullTriggerMeshes.Add(val2);
					val2.transform.localScale = Vector3.one;
					Vector3 val3 = obj.transform.TransformPoint(val2.transform.position);
					val2.transform.position = val3 - ((Component)triggerParent).transform.position;
					string name = $"{MeshNameTriggerPrefix}_{i}";
					((Object)val2.gameObject).name = name;
					MeshRenderer component = val2.GetComponent<MeshRenderer>();
					if ((Object)(object)component != (Object)null)
					{
						Object.Destroy((Object)(object)component);
					}
					MeshCollider component2 = val2.GetComponent<MeshCollider>();
					((Collider)component2).isTrigger = true;
					((Collider)component2).includeLayers = LayerHelpers.PhysicalLayers;
					((Collider)component2).excludeLayers = LayerHelpers.RamColliderExcludeLayers;
				}
			}
		}

		public Vector3 GetPreviewScale(MeshCollider meshCollider)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_001b: 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_0023: 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)
			//IL_004f: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = ((Collider)meshCollider).bounds;
			if (!(((Bounds)(ref bounds)).size.x > 30f))
			{
				bounds = ((Collider)meshCollider).bounds;
				if (!(((Bounds)(ref bounds)).size.z > 30f))
				{
					bounds = ((Collider)meshCollider).bounds;
					if (!(((Bounds)(ref bounds)).size.x > 10f))
					{
						bounds = ((Collider)meshCollider).bounds;
						if (!(((Bounds)(ref bounds)).size.z > 10f))
						{
							return Vector3.one * 1.1f;
						}
					}
					return Vector3.one * 1.05f;
				}
			}
			return new Vector3(1.03f, 1.1f, 1.03f);
		}

		public void CreatePreviewConvexHullMeshes()
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			DeleteMeshesFromChildColliders(convexHullPreviewMeshes);
			convexHullPreviewMeshRendererItems.Clear();
			if (PreviewMode == PreviewModes.None)
			{
				return;
			}
			if (PreviewMode == PreviewModes.Bubble)
			{
				GenerateUnderwaterBoxWrapper();
				return;
			}
			Rigidbody val = ((Component)PreviewParent).GetComponent<Rigidbody>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)PreviewParent).GetComponentInParent<Rigidbody>();
			}
			if ((Object)(object)val != (Object)null && !val.isKinematic)
			{
				LoggerAPI("Error: This component is invalid due to preview parent containing a non-kinematic Rigidbody. Using a non-kinematic rigidbody will cause this preview to desync.");
			}
			else if ((Object)(object)PreviewParent == (Object)null)
			{
				LoggerAPI("Error: PreviewParent is null.");
			}
			else
			{
				if (convexHullMeshes.Count <= 0)
				{
					return;
				}
				for (int i = 0; i < convexHullMeshes.Count; i++)
				{
					GameObject obj = convexHullMeshes[i];
					GameObject val2 = Object.Instantiate<GameObject>(obj, ((Component)PreviewParent).transform);
					convexHullPreviewMeshes.Add(val2);
					MeshCollider component = val2.GetComponent<MeshCollider>();
					val2.transform.localScale = ((PreviewMode == PreviewModes.Debug) ? previewScale : Vector3.one);
					Vector3 val3 = obj.transform.TransformPoint(val2.transform.position);
					val2.transform.position = val3 - ((Component)PreviewParent).transform.position + transformPreviewOffset;
					val2.AddComponent<MeshFilter>().mesh = component.sharedMesh;
					AddConvexHullMeshRenderer(val2.gameObject);
					string name = $"{MeshNamePreviewPrefix}_{i}";
					((Object)val2.gameObject).name = name;
					if ((Object)(object)component != (Object)null)
					{
						DebugUnityHelpers.AdaptiveDestroy((Object)(object)component);
					}
				}
			}
		}

		public void GenerateConvexHullMesh(List<Vector3> points, Transform parentObjTransform)
		{
			//IL_0091: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			Transform parentObjTransform2 = parentObjTransform;
			if (points.Count < 3)
			{
				Debug.LogError((object)"Not enough points to generate a convex hull.");
				return;
			}
			List<Vector3> list = points.Select((Vector3 x) => x - ((Component)parentObjTransform2).transform.position).ToList();
			if (convexHullMeshes.Count <= 0 || !DebugUnityHelpers.Vector3ArrayEqualWithTolerance(list.ToArray(), _cachedPoints.ToArray()))
			{
				_cachedPoints = list;
				List<Vector3> verts = new List<Vector3>();
				List<int> tris = new List<int>();
				List<Vector3> normals = new List<Vector3>();
				convexHullCalculator.GenerateHull(list, splitVerts: false, ref verts, ref tris, ref normals);
				Mesh val = new Mesh
				{
					vertices = verts.ToArray(),
					triangles = tris.ToArray(),
					normals = normals.ToArray(),
					name = $"{MeshNamePrefix}_{convexHullMeshes.Count}_mesh"
				};
				if (ShouldOptimizeGeneratedMeshes)
				{
					val.Optimize();
					val.RecalculateNormals();
					val.RecalculateBounds();
				}
				GameObject val2 = new GameObject($"{MeshNamePrefix}_{convexHullMeshes.Count}")
				{
					layer = 29
				};
				convexHullMeshes.Add(val2);
				MeshCollider val3 = val2.AddComponent<MeshCollider>();
				convexHullMeshColliders.Add(val3);
				val3.sharedMesh = val;
				val3.convex = true;
				((Collider)val3).excludeLayers = LayerHelpers.BlockingColliderExcludeLayers;
				((Collider)val3).includeLayers = LayerHelpers.PhysicalLayers;
				val2.transform.position = ((Component)parentObjTransform2).transform.position;
				val2.transform.SetParent(parentObjTransform2);
			}
		}
	}
	public class ConvexHullCalculator
	{
		private struct Face
		{
			public readonly int Vertex0;

			public readonly int Vertex1;

			public readonly int Vertex2;

			public int Opposite0;

			public int Opposite1;

			public int Opposite2;

			public readonly Vector3 Normal;

			public Face(int v0, int v1, int v2, int o0, int o1, int o2, Vector3 normal)
			{
				//IL_002e: 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)
				Vertex0 = v0;
				Vertex1 = v1;
				Vertex2 = v2;
				Opposite0 = o0;
				Opposite1 = o1;
				Opposite2 = o2;
				Normal = normal;
			}

			public bool Equals(Face other)
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				if (Vertex0 == other.Vertex0 && Vertex1 == other.Vertex1 && Vertex2 == other.Vertex2 && Opposite0 == other.Opposite0 && Opposite1 == other.Opposite1 && Opposite2 == other.Opposite2)
				{
					return Normal == other.Normal;
				}
				return false;
			}
		}

		private struct PointFace
		{
			public readonly int Point;

			public int Face;

			public float Distance;

			public PointFace(int p, int f, float d)
			{
				Point = p;
				Face = f;
				Distance = d;
			}
		}

		private struct HorizonEdge
		{
			public int Face;

			public int Edge0;

			public int Edge1;
		}

		private const int UNASSIGNED = -2;

		private const int INSIDE = -1;

		private const float EPSILON = 0.0001f;

		private int faceCount;

		private Dictionary<int, Face> faces;

		private List<HorizonEdge> horizon;

		private Dictionary<int, int> hullVerts;

		private HashSet<int> litFaces;

		private List<PointFace> openSet;

		private int openSetTail = -1;

		public void GenerateHull(List<Vector3> points, bool splitVerts, ref List<Vector3> verts, ref List<int> tris, ref List<Vector3> normals)
		{
			if (points.Count < 4)
			{
				throw new ArgumentException("Need at least 4 points to generate a convex hull");
			}
			Initialize(points, splitVerts);
			GenerateInitialHull(points);
			while (openSetTail >= 0)
			{
				GrowHull(points);
			}
			ExportMesh(points, splitVerts, ref verts, ref tris, ref normals);
		}

		private void Initialize(List<Vector3> points, bool splitVerts)
		{
			faceCount = 0;
			openSetTail = -1;
			if (faces == null)
			{
				faces = new Dictionary<int, Face>();
				litFaces = new HashSet<int>();
				horizon = new List<HorizonEdge>();
				openSet = new List<PointFace>(points.Count);
			}
			else
			{
				faces.Clear();
				litFaces.Clear();
				horizon.Clear();
				openSet.Clear();
				if (openSet.Capacity < points.Count)
				{
					openSet.Capacity = points.Count;
				}
			}
			if (!splitVerts)
			{
				if (hullVerts == null)
				{
					hullVerts = new Dictionary<int, int>();
				}
				else
				{
					hullVerts.Clear();
				}
			}
		}

		private void GenerateInitialHull(List<Vector3> points)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002c: 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_0033: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: 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)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00d6: 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)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			FindInitialHullIndices(points, out var b, out var b2, out var b3, out var b4);
			Vector3 val = points[b];
			Vector3 val2 = points[b2];
			Vector3 val3 = points[b3];
			bool num = Dot(points[b4] - val2, Cross(val2 - val, val3 - val)) > 0f;
			faceCount = 0;
			if (num)
			{
				faces[faceCount++] = new Face(b, b3, b2, 3, 1, 2, Normal(points[b], points[b3], points[b2]));
				faces[faceCount++] = new Face(b, b2, b4, 3, 2, 0, Normal(points[b], points[b2], points[b4]));
				faces[faceCount++] = new Face(b, b4, b3, 3, 0, 1, Normal(points[b], points[b4], points[b3]));
				faces[faceCount++] = new Face(b2, b3, b4, 2, 1, 0, Normal(points[b2], points[b3], points[b4]));
			}
			else
			{
				faces[faceCount++] = new Face(b, b2, b3, 3, 2, 1, Normal(points[b], points[b2], points[b3]));
				faces[faceCount++] = new Face(b, b4, b2, 3, 0, 2, Normal(points[b], points[b4], points[b2]));
				faces[faceCount++] = new Face(b, b3, b4, 3, 1, 0, Normal(points[b], points[b3], points[b4]));
				faces[faceCount++] = new Face(b2, b4, b3, 2, 0, 1, Normal(points[b2], points[b4], points[b3]));
			}
			for (int i = 0; i < points.Count; i++)
			{
				if (i != b && i != b2 && i != b3 && i != b4)
				{
					openSet.Add(new PointFace(i, -2, 0f));
				}
			}
			openSet.Add(new PointFace(b, -1, float.NaN));
			openSet.Add(new PointFace(b2, -1, float.NaN));
			openSet.Add(new PointFace(b3, -1, float.NaN));
			openSet.Add(new PointFace(b4, -1, float.NaN));
			openSetTail = openSet.Count - 5;
			for (int j = 0; j <= openSetTail; j++)
			{
				bool flag = false;
				PointFace value = openSet[j];
				for (int k = 0; k < 4; k++)
				{
					Face face = faces[k];
					float num2 = PointFaceDistance(points[value.Point], points[face.Vertex0], face);
					if (num2 > 0f)
					{
						value.Face = k;
						value.Distance = num2;
						openSet[j] = value;
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					value.Face = -1;
					value.Distance = float.NaN;
					openSet[j] = openSet[openSetTail];
					openSet[openSetTail] = value;
					openSetTail--;
					j--;
				}
			}
		}

		private void FindInitialHullIndices(List<Vector3> points, out int b0, out int b1, out int b2, out int b3)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			int count = points.Count;
			for (int i = 0; i < count - 3; i++)
			{
				for (int j = i + 1; j < count - 2; j++)
				{
					Vector3 a = points[i];
					Vector3 b4 = points[j];
					if (AreCoincident(a, b4))
					{
						continue;
					}
					for (int k = j + 1; k < count - 1; k++)
					{
						Vector3 c = points[k];
						if (AreCollinear(a, b4, c))
						{
							continue;
						}
						for (int l = k + 1; l < count; l++)
						{
							Vector3 d = points[l];
							if (!AreCoplanar(a, b4, c, d))
							{
								b0 = i;
								b1 = j;
								b2 = k;
								b3 = l;
								return;
							}
						}
					}
				}
			}
			throw new ArgumentException("Can't generate hull, points are coplanar");
		}

		private void GrowHull(List<Vector3> points)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			int index = 0;
			float distance = openSet[0].Distance;
			for (int i = 1; i <= openSetTail; i++)
			{
				if (openSet[i].Distance > distance)
				{
					index = i;
					distance = openSet[i].Distance;
				}
			}
			FindHorizon(points, points[openSet[index].Point], openSet[index].Face, faces[openSet[index].Face]);
			ConstructCone(points, openSet[index].Point);
			ReassignPoints(points);
		}

		private void FindHorizon(List<Vector3> points, Vector3 point, int fi, Face face)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			litFaces.Clear();
			horizon.Clear();
			litFaces.Add(fi);
			Face face2 = faces[face.Opposite0];
			if (PointFaceDistance(point, points[face2.Vertex0], face2) <= 0f)
			{
				horizon.Add(new HorizonEdge
				{
					Face = face.Opposite0,
					Edge0 = face.Vertex1,
					Edge1 = face.Vertex2
				});
			}
			else
			{
				SearchHorizon(points, point, fi, face.Opposite0, face2);
			}
			if (!litFaces.Contains(face.Opposite1))
			{
				Face face3 = faces[face.Opposite1];
				if (PointFaceDistance(point, points[face3.Vertex0], face3) <= 0f)
				{
					horizon.Add(new HorizonEdge
					{
						Face = face.Opposite1,
						Edge0 = face.Vertex2,
						Edge1 = face.Vertex0
					});
				}
				else
				{
					SearchHorizon(points, point, fi, face.Opposite1, face3);
				}
			}
			if (!litFaces.Contains(face.Opposite2))
			{
				Face face4 = faces[face.Opposite2];
				if (PointFaceDistance(point, points[face4.Vertex0], face4) <= 0f)
				{
					horizon.Add(new HorizonEdge
					{
						Face = face.Opposite2,
						Edge0 = face.Vertex0,
						Edge1 = face.Vertex1
					});
				}
				else
				{
					SearchHorizon(points, point, fi, face.Opposite2, face4);
				}
			}
		}

		private void SearchHorizon(List<Vector3> points, Vector3 point, int prevFaceIndex, int faceCount, Face face)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			litFaces.Add(faceCount);
			int num;
			int num2;
			int edge;
			int num3;
			int edge2;
			if (prevFaceIndex == face.Opposite0)
			{
				num = face.Opposite1;
				num2 = face.Opposite2;
				edge = face.Vertex2;
				num3 = face.Vertex0;
				edge2 = face.Vertex1;
			}
			else if (prevFaceIndex == face.Opposite1)
			{
				num = face.Opposite2;
				num2 = face.Opposite0;
				edge = face.Vertex0;
				num3 = face.Vertex1;
				edge2 = face.Vertex2;
			}
			else
			{
				num = face.Opposite0;
				num2 = face.Opposite1;
				edge = face.Vertex1;
				num3 = face.Vertex2;
				edge2 = face.Vertex0;
			}
			if (!litFaces.Contains(num))
			{
				Face face2 = faces[num];
				if (PointFaceDistance(point, points[face2.Vertex0], face2) <= 0f)
				{
					horizon.Add(new HorizonEdge
					{
						Face = num,
						Edge0 = edge,
						Edge1 = num3
					});
				}
				else
				{
					SearchHorizon(points, point, faceCount, num, face2);
				}
			}
			if (!litFaces.Contains(num2))
			{
				Face face3 = faces[num2];
				if (PointFaceDistance(point, points[face3.Vertex0], face3) <= 0f)
				{
					horizon.Add(new HorizonEdge
					{
						Face = num2,
						Edge0 = num3,
						Edge1 = edge2
					});
				}
				else
				{
					SearchHorizon(points, point, faceCount, num2, face3);
				}
			}
		}

		private void ConstructCone(List<Vector3> points, int farthestPoint)
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			foreach (int litFace in litFaces)
			{
				faces.Remove(litFace);
			}
			int num = faceCount;
			for (int i = 0; i < horizon.Count; i++)
			{
				int edge = horizon[i].Edge0;
				int edge2 = horizon[i].Edge1;
				int face = horizon[i].Face;
				int o = ((i == horizon.Count - 1) ? num : (num + i + 1));
				int o2 = ((i == 0) ? (num + horizon.Count - 1) : (num + i - 1));
				int num2 = faceCount++;
				faces[num2] = new Face(farthestPoint, edge, edge2, face, o, o2, Normal(points[farthestPoint], points[edge], points[edge2]));
				Face value = faces[horizon[i].Face];
				if (value.Vertex0 == edge)
				{
					value.Opposite1 = num2;
				}
				else if (value.Vertex1 == edge)
				{
					value.Opposite2 = num2;
				}
				else
				{
					value.Opposite0 = num2;
				}
				faces[horizon[i].Face] = value;
			}
		}

		private void ReassignPoints(List<Vector3> points)
		{
			//IL_0033: 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_0064: 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)
			for (int i = 0; i <= openSetTail; i++)
			{
				PointFace value = openSet[i];
				if (!litFaces.Contains(value.Face))
				{
					continue;
				}
				bool flag = false;
				Vector3 point = points[value.Point];
				foreach (KeyValuePair<int, Face> face in faces)
				{
					int key = face.Key;
					Face value2 = face.Value;
					float num = PointFaceDistance(point, points[value2.Vertex0], value2);
					if (num > 0.0001f)
					{
						flag = true;
						value.Face = key;
						value.Distance = num;
						openSet[i] = value;
						break;
					}
				}
				if (!flag)
				{
					value.Face = -1;
					value.Distance = float.NaN;
					openSet[i] = openSet[openSetTail];
					openSet[openSetTail] = value;
					i--;
					openSetTail--;
				}
			}
		}

		private void ExportMesh(List<Vector3> points, bool splitVerts, ref List<Vector3> verts, ref List<int> tris, ref List<Vector3> normals)
		{
			//IL_0077: 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)
			//IL_00ae: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			if (verts == null)
			{
				verts = new List<Vector3>();
			}
			else
			{
				verts.Clear();
			}
			if (tris == null)
			{
				tris = new List<int>();
			}
			else
			{
				tris.Clear();
			}
			if (normals == null)
			{
				normals = new List<Vector3>();
			}
			else
			{
				normals.Clear();
			}
			foreach (Face value4 in faces.Values)
			{
				int value;
				int value2;
				int value3;
				if (splitVerts)
				{
					value = verts.Count;
					verts.Add(points[value4.Vertex0]);
					value2 = verts.Count;
					verts.Add(points[value4.Vertex1]);
					value3 = verts.Count;
					verts.Add(points[value4.Vertex2]);
					normals.Add(value4.Normal);
					normals.Add(value4.Normal);
					normals.Add(value4.Normal);
				}
				else
				{
					if (!hullVerts.TryGetValue(value4.Vertex0, out value))
					{
						value = verts.Count;
						hullVerts[value4.Vertex0] = value;
						verts.Add(points[value4.Vertex0]);
					}
					if (!hullVerts.TryGetValue(value4.Vertex1, out value2))
					{
						value2 = verts.Count;
						hullVerts[value4.Vertex1] = value2;
						verts.Add(points[value4.Vertex1]);
					}
					if (!hullVerts.TryGetValue(value4.Vertex2, out value3))
					{
						value3 = verts.Count;
						hullVerts[value4.Vertex2] = value3;
						verts.Add(points[value4.Vertex2]);
					}
				}
				tris.Add(value);
				tris.Add(value2);
				tris.Add(value3);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private float PointFaceDistance(Vector3 point, Vector3 pointOnFace, Face face)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//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)
			return Dot(face.Normal, point - pointOnFace);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private Vector3 Normal(Vector3 v0, Vector3 v1, Vector3 v2)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Cross(v1 - v0, v2 - v0);
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f))
			{
				return Vector3.zero;
			}
			return ((Vector3)(ref val)).normalized;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static float Dot(Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (migh

plugins\ZdoWatcher.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using ZdoWatcher.Patches;
using ZdoWatcher.ZdoWatcher.Config;
using Zolantris.Shared.Debug;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ZdoWatcher")]
[assembly: AssemblyDescription("Valheim Mod made to share Zdo Changes and side effect through one shareable interface")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Virtualize LLC")]
[assembly: AssemblyProduct("ZdoWatcher")]
[assembly: AssemblyCopyright("Copyright © 2023-2024, GNU-v3 licensed")]
[assembly: Guid("6015B165-2627-40A7-8CA1-3E6B6CD7CB49")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ZdoWatcher
{
	public static class ZdoVarController
	{
		private static readonly Dictionary<string, string> ZdoVariables = new Dictionary<string, string>();

		public static readonly int PersistentUidHash = StringExtensionMethods.GetStableHashCode("PersistentID");

		public static string NameToVar(BaseUnityPlugin unityPlugin, string key)
		{
			return ((Object)unityPlugin).name + "_" + key;
		}

		public static void RegisterPublicVar(BaseUnityPlugin unityPlugin, string key, int value)
		{
			string key2 = NameToVar(unityPlugin, key);
			ZdoVariables.Add(key2, value.ToString());
		}

		public static void RegisterPublicVar(BaseUnityPlugin unityPlugin, string key, string value)
		{
			NameToVar(unityPlugin, key);
			ZdoVariables.Add(key, value);
		}

		public static void ListPublicVar(bool shouldLog = true)
		{
			if (!shouldLog)
			{
				return;
			}
			foreach (KeyValuePair<string, string> zdoVariable in ZdoVariables)
			{
				Logger.LogInfo((object)("Key: " + zdoVariable.Key + ", Value: " + zdoVariable.Value));
			}
		}
	}
	public class ZdoWatchController : MonoBehaviour
	{
		public static Action<ZDO>? OnDeserialize;

		public static Action<ZDO>? OnLoad;

		public static Action<ZDO>? OnReset;

		public static ZdoWatchController Instance;

		private readonly Dictionary<int, ZDO> _zdoGuidLookup = new Dictionary<int, ZDO>();

		private readonly List<DebugSafeTimer> _timers = new List<DebugSafeTimer>();

		private CustomRPC RPC_RequestPersistentIdInstance;

		public Dictionary<int, ZDO?> PendingPersistentIdQueries = new Dictionary<int, ZDO>();

		public void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			RPC_RequestPersistentIdInstance = NetworkManager.Instance.AddRPC("RPC_RequestSync", new CoroutineHandler(RequestPersistentIdRPCServerReceive), (CoroutineHandler)null);
		}

		public Dictionary<int, ZDO> GetAllZdoGuids()
		{
			return _zdoGuidLookup.ToDictionary<KeyValuePair<int, ZDO>, int, ZDO>((KeyValuePair<int, ZDO> kvp) => kvp.Key, (KeyValuePair<int, ZDO> kvp) => kvp.Value);
		}

		public void Update()
		{
			DebugSafeTimer.UpdateTimersFromList(_timers);
		}

		public void SyncToPeer(ZDOPeer? zdoPeer)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (!ZNet.instance.IsServer() || zdoPeer == null)
			{
				return;
			}
			foreach (ZDO value in _zdoGuidLookup.Values)
			{
				if (zdoPeer != null)
				{
					zdoPeer.ForceSendZDO(value.m_uid);
				}
			}
		}

		private IEnumerator RequestPersistentIdRPCServerReceive(long sender, ZPackage package)
		{
			int num = package.ReadInt();
			ZDOPeer peer = ZDOMan.instance.GetPeer(sender);
			Logger.LogMessage((object)$"Sending first id across to peer {num}");
			ZDO zdo = GetZdo(num);
			if (zdo != null && peer != null)
			{
				peer.ForceSendZDO(zdo.m_uid);
			}
			else
			{
				Logger.LogMessage((object)"RequestPersistentIdRPCServerReceive called but zdoid not found, attempting to sync all ids to peer");
				SyncToPeer(peer);
			}
			yield return null;
		}

		public ZPackage GetAllServerZdoIds()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			Logger.LogMessage((object)$"Writing {_zdoGuidLookup.Values.Count} zdos to a ZPackage");
			foreach (ZDO value in _zdoGuidLookup.Values)
			{
				val.Write(value.m_uid);
			}
			return val;
		}

		public bool RequestZdoFromServer(int persistentId)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if (ZNet.instance.IsServer())
			{
				return false;
			}
			ZPackage val = new ZPackage();
			val.Write(persistentId);
			long serverPeerID = ZRoutedRpc.instance.GetServerPeerID();
			RPC_RequestPersistentIdInstance.SendPackage(serverPeerID, val);
			return true;
		}

		public IEnumerator GetZdoFromServerAsync(int persistentId, Action<ZDO?> onComplete)
		{
			if (ZNet.instance.IsServer())
			{
				ZDO zdo = GetZdo(persistentId);
				Logger.LogWarning((object)$"Called GetZdoFromServer for {persistentId} on the server. This should not happen");
				onComplete(zdo);
				yield break;
			}
			ZDO zdo2 = GetZdo(persistentId);
			if (zdo2 != null)
			{
				onComplete(zdo2);
			}
			else if (PendingPersistentIdQueries.ContainsKey(persistentId))
			{
				Logger.LogWarning((object)$"RequestPersistentID called for ongoing operation on id: {persistentId}, requests cannot be called during a specific timelimit");
				onComplete(null);
			}
			else
			{
				RequestZdoFromServer(persistentId);
				yield return WaitForZdo(persistentId, onComplete);
				Logger.LogDebug((object)"GetZdoFromServerAsync finished");
			}
		}

		private IEnumerator WaitForZdo(int persistentId, Action<ZDO?> onComplete, int timeoutInMs = 2000)
		{
			DebugSafeTimer timer = DebugSafeTimer.StartNew(_timers);
			ZDO targetZdo = null;
			while (timer.ElapsedMilliseconds < (float)timeoutInMs && targetZdo == null)
			{
				if (_zdoGuidLookup.TryGetValue(persistentId, out ZDO value))
				{
					targetZdo = value;
					break;
				}
				yield return (object)new WaitForFixedUpdate();
			}
			if (timer.ElapsedMilliseconds >= (float)timeoutInMs)
			{
				Logger.LogWarning((object)"Timeout for WaitForZdo reached, exiting the WaitForZdo call with a failure.");
			}
			else
			{
				Logger.LogDebug((object)$"Completed timer in: {timer.ElapsedMilliseconds} milliseconds");
			}
			if (PendingPersistentIdQueries.ContainsKey(persistentId))
			{
				PendingPersistentIdQueries.Remove(persistentId);
			}
			onComplete(targetZdo);
		}

		public void Reset()
		{
			_zdoGuidLookup.Clear();
		}

		public static bool GetPersistentID(ZDO zdo, out int id)
		{
			id = zdo.GetInt(ZdoVarController.PersistentUidHash, 0);
			return id != 0;
		}

		public static int ZdoIdToId(ZDOID zdoid)
		{
			return (int)((ZDOID)(ref zdoid)).UserID + (int)((ZDOID)(ref zdoid)).ID;
		}

		public int GetOrCreatePersistentID(ZDO? zdo)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (zdo == null)
			{
				Logger.LogWarning((object)"GetOrCreatePersistentID called with a null ZDO, this will be disabled in the future.");
			}
			if (zdo == null)
			{
				zdo = new ZDO();
			}
			int @int = zdo.GetInt(ZdoVarController.PersistentUidHash, 0);
			if (@int != 0)
			{
				return @int;
			}
			for (@int = ZdoIdToId(zdo.m_uid); _zdoGuidLookup.ContainsKey(@int); @int++)
			{
			}
			zdo.Set(ZdoVarController.PersistentUidHash, @int, false);
			_zdoGuidLookup[@int] = zdo;
			return @int;
		}

		public void HandleRegisterPersistentId(ZDO zdo)
		{
			if (GetPersistentID(zdo, out var id))
			{
				_zdoGuidLookup[id] = zdo;
			}
		}

		private void HandleDeregisterPersistentId(ZDO zdo)
		{
			if (GetPersistentID(zdo, out var id))
			{
				_zdoGuidLookup.Remove(id);
			}
		}

		public void Deserialize(ZDO zdo)
		{
			HandleRegisterPersistentId(zdo);
			if (OnDeserialize == null)
			{
				return;
			}
			try
			{
				OnDeserialize(zdo);
			}
			catch
			{
				Logger.LogError((object)"OnDeserialize had an error");
			}
		}

		public void Load(ZDO zdo)
		{
			HandleRegisterPersistentId(zdo);
			if (OnLoad == null)
			{
				return;
			}
			try
			{
				OnLoad(zdo);
			}
			catch
			{
				Logger.LogError((object)"OnLoad had an error");
			}
		}

		public void Reset(ZDO zdo)
		{
			HandleDeregisterPersistentId(zdo);
			if (OnReset == null)
			{
				return;
			}
			try
			{
				OnReset(zdo);
			}
			catch
			{
				Logger.LogError((object)"OnReset had an error");
			}
		}

		public ZDO? GetZdo(int id)
		{
			if (!_zdoGuidLookup.TryGetValue(id, out ZDO value))
			{
				return null;
			}
			return value;
		}

		public GameObject? GetGameObject(int id)
		{
			ZNetView instance = GetInstance(id);
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return null;
			}
			if (instance == null)
			{
				return null;
			}
			return ((Component)instance).gameObject;
		}

		public ZNetView? GetInstance(int id)
		{
			ZDO zdo = GetZdo(id);
			if (zdo == null)
			{
				return null;
			}
			return ZNetScene.instance.FindInstance(zdo);
		}
	}
	[BepInPlugin("zolantris.ZdoWatcher", "ZdoWatcher", "1.1.0")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class ZdoWatcherPlugin : BaseUnityPlugin
	{
		public const string Author = "zolantris";

		public const string Version = "1.1.0";

		public const string ModName = "ZdoWatcher";

		public const string ModGuid = "zolantris.ZdoWatcher";

		private static Harmony _harmony;

		public const string ModDescription = "Valheim Mod made to share Zdo Changes and side effect through one shareable interface";

		public const string CopyRight = "Copyright © 2023-2024, GNU-v3 licensed";

		public static string HarmonyGuid => "zolantris.ZdoWatcher";

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			ZdoWatcherConfig.BindConfig(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony(HarmonyGuid);
			_harmony.PatchAll(typeof(ZdoPatch));
			_harmony.PatchAll(typeof(ZNetScene_Patch));
			_harmony.PatchAll(typeof(ZDOMan_Patch));
			if (ZdoWatcherConfig.GuardAgainstInvalidZNetSceneSpam != null && ZdoWatcherConfig.GuardAgainstInvalidZNetSceneSpam.Value)
			{
				_harmony.PatchAll(typeof(InvalidZNetScenePatch));
			}
			ZdoWatchController.Instance = ((Component)this).gameObject.AddComponent<ZdoWatchController>();
		}
	}
}
namespace ZdoWatcher.Patches
{
	public class ZDOMan_Patch
	{
		[HarmonyPatch(typeof(ZDOMan), "AddPeer")]
		[HarmonyPostfix]
		private static void OnAddPeer(ZDOMan __instance)
		{
			int num = __instance.m_peers.Count - 1;
			if (num >= 1)
			{
				ZDOPeer zdoPeer = __instance.m_peers[num];
				ZdoWatchController.Instance.SyncToPeer(zdoPeer);
			}
		}
	}
	[HarmonyPatch]
	public class ZdoPatch
	{
		[HarmonyPatch(typeof(ZDO), "Deserialize")]
		[HarmonyPostfix]
		private static void ZDO_Deserialize(ZDO __instance, ZPackage pkg)
		{
			ZdoWatchController.Instance.Deserialize(__instance);
		}

		[HarmonyPatch(typeof(ZDO), "Load")]
		[HarmonyPostfix]
		private static void ZDO_Load(ZDO __instance, ZPackage pkg, int version)
		{
			ZdoWatchController.Instance.Load(__instance);
		}

		[HarmonyPatch(typeof(ZDO), "Reset")]
		[HarmonyPrefix]
		private static void ZDO_Reset(ZDO __instance)
		{
			ZdoWatchController.Instance.Reset(__instance);
		}
	}
	public class ZNetScene_Patch
	{
		[HarmonyPatch(typeof(ZNetScene), "Shutdown")]
		[HarmonyPostfix]
		private static void ZNetScene_Shutdown()
		{
			ZdoWatchController.Instance.Reset();
		}
	}
}
namespace ZdoWatcher.ZdoWatcher.Config
{
	public class ConfigHelpers
	{
		public static ConfigDescription CreateConfigDescription(string description, bool isAdmin = false, bool isAdvanced = false)
		{
			//IL_000a: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			return new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = isAdmin,
				IsAdvanced = isAdvanced
			} });
		}
	}
	public static class ZdoWatcherConfig
	{
		public static ConfigFile? Config { get; private set; }

		public static ConfigEntry<bool>? GuardAgainstInvalidZNetSceneSpam { get; private set; }

		public static void BindConfig(ConfigFile config)
		{
			Config = config;
			GuardAgainstInvalidZNetSceneSpam = config.Bind<bool>("Patches", "GuardAgainstInvalidZNetScene", true, ConfigHelpers.CreateConfigDescription("Allows you to customize what piece the raft initializes with. Admins only as this can be overpowered.", isAdmin: true, isAdvanced: true));
		}
	}
	public class InvalidZNetScenePatch
	{
		[HarmonyPatch(typeof(ZNetScene), "RemoveObjects")]
		[HarmonyPrefix]
		private static bool RemoveObjects(ZNetScene __instance, List<ZDO> currentNearObjects, List<ZDO> currentDistantObjects)
		{
			byte b = (byte)((uint)Time.frameCount & 0xFFu);
			foreach (ZDO currentNearObject in currentNearObjects)
			{
				currentNearObject.TempRemoveEarmark = b;
			}
			foreach (ZDO currentDistantObject in currentDistantObjects)
			{
				currentDistantObject.TempRemoveEarmark = b;
			}
			__instance.m_tempRemoved.Clear();
			foreach (ZNetView value in __instance.m_instances.Values)
			{
				if (Object.op_Implicit((Object)(object)value) && value.GetZDO().TempRemoveEarmark != b)
				{
					__instance.m_tempRemoved.Add(value);
				}
			}
			for (int i = 0; i < __instance.m_tempRemoved.Count; i++)
			{
				ZNetView val = __instance.m_tempRemoved[i];
				if (Object.op_Implicit((Object)(object)val))
				{
					ZDO zDO = val.GetZDO();
					val.ResetZDO();
					Object.Destroy((Object)(object)((Component)val).gameObject);
					if (!zDO.Persistent && zDO.IsOwner())
					{
						ZDOMan.instance.DestroyZDO(zDO);
					}
					__instance.m_instances.Remove(zDO);
				}
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}