Decompiled source of ValheimRAFT v2.4.3

plugins\DynamicLocations.dll

Decompiled 3 weeks 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 3 weeks 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 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
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 UnityEngine;
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.Helpers;
using ValheimVehicles.LayerUtils;
using ValheimVehicles.ModSupport;
using ValheimVehicles.Patches;
using ValheimVehicles.Prefabs;
using ValheimVehicles.Prefabs.Registry;
using ValheimVehicles.Propulsion.Rudder;
using ValheimVehicles.Propulsion.Sail;
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 ZdoWatcher.ZdoWatcher.Config;
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.4.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.4.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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_009c: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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.Vehicles
{
	public struct DrawTargetColliders
	{
		public BoxCollider collider { get; set; }

		public Color lineColor { get; set; }

		public GameObject parent { get; set; }

		public float width { get; set; }

		public DrawTargetColliders()
		{
			//IL_000a: 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)
			collider = null;
			lineColor = default(Color);
			parent = null;
			width = 1f;
		}
	}
	public class VehicleDebugHelpers : MonoBehaviour
	{
		private struct DrawLineData
		{
			public Color color;

			public Material material;

			public GameObject parent;

			public BoxCollider boxCollider;

			public List<LineRenderer>? lineItems;

			public float width;

			public void Deconstruct(out Color o_color, out Material o_material, out GameObject o_parent, out BoxCollider o_boxCollider, out List<LineRenderer>? o_lineItems, out float o_width)
			{
				//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)
				o_color = color;
				o_material = material;
				o_parent = parent;
				o_boxCollider = boxCollider;
				o_lineItems = lineItems;
				o_width = width;
			}
		}

		private Dictionary<string, List<LineRenderer>> lines = new Dictionary<string, List<LineRenderer>>();

		public bool autoUpdateColliders;

		private List<DrawTargetColliders> targetColliders = new List<DrawTargetColliders>();

		public GameObject VehicleObj;

		public VehicleShip VehicleShipInstance;

		private Coroutine? _drawColliderCoroutine;

		private InvokeBinder repeatInvoke;

		private static readonly Color LineColorDefault = Color.green;

		private void FixedUpdate()
		{
			if (((Behaviour)this).isActiveAndEnabled && (autoUpdateColliders || VehicleDebugConfig.AutoShowVehicleColliders.Value))
			{
				DrawAllColliders();
			}
		}

		private void OnDestroy()
		{
			lines.Values.ToList().ForEach(delegate(List<LineRenderer> x)
			{
				x.ForEach((Action<LineRenderer>)Object.Destroy);
			});
			lines.Clear();
		}

		public void StartRenderAllCollidersLoop()
		{
			autoUpdateColliders = !autoUpdateColliders;
			if (autoUpdateColliders)
			{
				return;
			}
			foreach (KeyValuePair<string, List<LineRenderer>> line in lines)
			{
				if (!lines.TryGetValue(line.Key, out List<LineRenderer> value) || value == null)
				{
					continue;
				}
				foreach (LineRenderer item in line.Value.ToList().OfType<LineRenderer>())
				{
					Object.Destroy((Object)(object)((Component)item).gameObject);
					value.Remove(item);
				}
			}
		}

		private static RaycastHit? RaycastToPiecesUnderPlayerCamera()
		{
			//IL_0021: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return null;
			}
			RaycastHit value = default(RaycastHit);
			if (!Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref value, 50f, LayerMask.GetMask(new string[1] { "piece" })))
			{
				return null;
			}
			return value;
		}

		public static VehicleDebugHelpers GetOnboardVehicleDebugHelper()
		{
			return GetVehiclePiecesController()?.VehicleInstance?.Instance?.VehicleDebugHelpersInstance;
		}

		public static VehicleDebugHelpers? GetOnboardMBRaftDebugHelper()
		{
			return GetMBRaftController()?.shipController?.VehicleDebugHelpersInstance;
		}

		public static MoveableBaseRootComponent? GetMBRaftController()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit? val = RaycastToPiecesUnderPlayerCamera();
			if (!val.HasValue)
			{
				return null;
			}
			RaycastHit valueOrDefault = val.GetValueOrDefault();
			return ((Component)((RaycastHit)(ref valueOrDefault)).collider).GetComponentInParent<MoveableBaseRootComponent>();
		}

		public static VehiclePiecesController? GetVehiclePiecesController()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit? val = RaycastToPiecesUnderPlayerCamera();
			if (!val.HasValue)
			{
				return null;
			}
			RaycastHit valueOrDefault = val.GetValueOrDefault();
			return ((Component)((Component)((RaycastHit)(ref valueOrDefault)).collider).transform.root).GetComponent<VehiclePiecesController>();
		}

		public void FlipShip()
		{
			//IL_008c: 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)
			if (Object.op_Implicit((Object)(object)VehicleShipInstance?.MovementController?.m_body) && !((Object)(object)VehicleShipInstance == (Object)null) && !((Object)(object)VehicleShipInstance.MovementController == (Object)null))
			{
				if (!VehicleShipInstance.isCreative)
				{
					VehicleShipInstance.MovementController.m_body.isKinematic = true;
				}
				VehicleShipInstance.MovementController.m_body.rotation = Quaternion.Euler(0f, VehicleObj.transform.eulerAngles.y, 0f);
				if (!VehicleShipInstance.isCreative)
				{
					VehicleShipInstance.MovementController.m_body.isKinematic = false;
				}
			}
		}

		public void MoveShip(Vector3 vector)
		{
			//IL_0044: 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_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_006a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)VehicleShipInstance.MovementController.m_body))
			{
				VehicleShipInstance.MovementController.m_body.isKinematic = true;
				((Component)this).transform.rotation = Quaternion.Euler(0f, VehicleObj.transform.eulerAngles.y, 0f);
				Transform transform = ((Component)this).transform;
				transform.position += vector;
				VehicleShipInstance.MovementController.m_body.isKinematic = false;
			}
		}

		private static void DrawLine(Vector3 start, Vector3 end, int index, DrawLineData data)
		{
			//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_0065: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			DrawLineData drawLineData = data;
			var (val5, material, val6, val7, list2, num2) = (DrawLineData)(ref drawLineData);
			if (list2 == null)
			{
				throw new ArgumentNullException("lineItems");
			}
			LineRenderer val8;
			if (index < list2.Count)
			{
				val8 = list2[index];
			}
			else
			{
				val8 = new GameObject($"{((Object)val7).name}_Line_{index}").AddComponent<LineRenderer>();
				((Component)val8).transform.SetParent(val6.transform);
			}
			((Renderer)val8).material = material;
			val8.startColor = val5;
			val8.endColor = val5;
			val8.startWidth = num2;
			val8.endWidth = num2;
			val8.positionCount = 2;
			val8.useWorldSpace = true;
			val8.SetPosition(0, start);
			val8.SetPosition(1, end);
			if (index < list2.Count)
			{
				list2[index] = val8;
			}
			else
			{
				list2.Add(val8);
			}
		}

		public void AddColliderToRerender(DrawTargetColliders drawTargetColliders)
		{
			targetColliders.Add(drawTargetColliders);
		}

		private IEnumerable DrawCollidersCoroutine()
		{
			Logger.LogDebug((object)"called DrawCollidersCoroutine");
			while (autoUpdateColliders)
			{
				Logger.LogDebug((object)"DrawCollidersCoroutine Update");
				DrawAllColliders();
				yield return null;
			}
			yield return null;
		}

		private bool DrawAllColliders()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			foreach (DrawTargetColliders targetCollider in targetColliders)
			{
				DrawColliders(targetCollider.collider, ((Component)targetCollider.collider).gameObject, targetCollider.lineColor);
			}
			return true;
		}

		public void DrawColliders(BoxCollider boxCollider, GameObject parent, Color? lineColor)
		{
			//IL_0015: 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_001a: 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_002f: 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_0037: Expected O, but got Unknown
			//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_0046: 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_005a: 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_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_006f: 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_0080: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00bd: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_00fe: 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_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_010e: 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_0116: 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_011d: 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_0120: 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_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_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)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_0150: 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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0174: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: 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_018c: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: 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_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: 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_01cd: 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_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			Color color = (Color)(((??)lineColor) ?? LineColorDefault);
			if (!((Object)(object)boxCollider == (Object)null))
			{
				Material material = new Material(LoadValheimAssets.CustomPieceShader)
				{
					color = color
				};
				Vector3 val = ((Component)boxCollider).transform.right;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				val = ((Component)boxCollider).transform.forward;
				Vector3 normalized2 = ((Vector3)(ref val)).normalized;
				val = ((Component)boxCollider).transform.up;
				Vector3 normalized3 = ((Vector3)(ref val)).normalized;
				Vector3 val2 = ((Component)boxCollider).transform.position + boxCollider.center;
				Vector3 size = boxCollider.size;
				size.x *= ((Component)boxCollider).transform.lossyScale.x;
				size.y *= ((Component)boxCollider).transform.lossyScale.y;
				size.z *= ((Component)boxCollider).transform.lossyScale.z;
				Vector3 val3 = size / 2f;
				Vector3 val4 = normalized3 * val3.y;
				Vector3 val5 = normalized * val3.x;
				Vector3 val6 = normalized2 * val3.z;
				Vector3 val7 = val2 + val4 + val5 + val6;
				Vector3 val8 = val2 - val4 + val5 + val6;
				Vector3 val9 = val2 + val4 - val5 + val6;
				Vector3 end = val2 - val4 - val5 + val6;
				Vector3 start = val2 + val4 + val5 - val6;
				Vector3 val10 = val2 - val4 + val5 - val6;
				Vector3 val11 = val2 + val4 - val5 - val6;
				Vector3 val12 = val2 - val4 - val5 - val6;
				if (!lines.TryGetValue(((Object)boxCollider).name, out List<LineRenderer> value))
				{
					value = new List<LineRenderer>();
					lines.Add(((Object)boxCollider).name, value);
				}
				DrawLineData drawLineData = default(DrawLineData);
				drawLineData.color = color;
				drawLineData.boxCollider = boxCollider;
				drawLineData.parent = parent;
				drawLineData.material = material;
				drawLineData.lineItems = value;
				drawLineData.width = 0.1f;
				DrawLineData data = drawLineData;
				int num = 0;
				DrawLine(val7, val9, num, data);
				num++;
				DrawLine(val8, end, num, data);
				num++;
				DrawLine(val7, val8, num, data);
				num++;
				DrawLine(val9, end, num, data);
				num++;
				DrawLine(start, val11, num, data);
				num++;
				DrawLine(val10, val12, num, data);
				num++;
				DrawLine(start, val10, num, data);
				num++;
				DrawLine(val11, val12, num, data);
				num++;
				DrawLine(val11, val9, num, data);
				num++;
				DrawLine(val12, end, num, data);
				num++;
				DrawLine(start, val7, num, data);
				num++;
				DrawLine(val10, val8, num, data);
				lines[((Object)boxCollider).name] = value;
			}
		}
	}
	public class VehicleObject
	{
		public string itemId;

		public string prefabName;

		public float prefabHealth;

		public float prefabState;
	}
	public class BaseVehicleItemStorage
	{
		public string vehicleId;

		public string vehicleName;

		public Dictionary<string, VehicleObject> registeredItems = new Dictionary<string, VehicleObject>();

		public void setItemRegistry(VehicleObject item)
		{
			registeredItems.Add(item.itemId, item);
		}

		public List<KeyValuePair<string, VehicleObject>> GetVehicleItems()
		{
			return registeredItems.ToList();
		}
	}
	public class ValheimBaseGameShip : MonoBehaviour
	{
		internal float m_sendRudderTime;

		[Header("Objects")]
		public GameObject m_sailObject;

		public GameObject m_mastObject;

		public GameObject m_rudderObject;

		public Transform? m_controlGuiPos;

		public BoxCollider m_floatcollider;

		public float m_waterLevelOffset = 1.5f;

		public float m_forceDistance = 1f;

		public float m_force = 0.5f;

		public float m_damping = 0.05f;

		public float m_dampingSideway = 0.05f;

		public float m_dampingForward = 0.01f;

		public float m_angularDamping = 0.01f;

		public float m_disableLevel = -0.5f;

		public float m_sailForceOffset;

		public float m_sailForceFactor = 0.1f;

		public float m_stearForceOffset = -10f;

		public float m_stearForce = 0.5f;

		public float m_stearVelForceFactor = 0.1f;

		public float m_backwardForce = 50f;

		public float m_rudderRotationMax = 30f;

		public float m_minWaterImpactForce = 2.5f;

		public float m_minWaterImpactInterval = 2f;

		public float m_waterImpactDamage = 10f;

		public float m_upsideDownDmgInterval = 1f;

		public float m_upsideDownDmg = 20f;

		public EffectList m_waterImpactEffect = new EffectList();

		internal bool m_sailWasInPosition;

		internal Vector3 m_windChangeVelocity = Vector3.zero;

		internal Vector3 m_sailForce = Vector3.zero;

		public List<Player> m_players = new List<Player>();

		internal WaterVolume m_previousCenter;

		internal WaterVolume m_previousLeft;

		internal WaterVolume m_previousRight;

		internal WaterVolume m_previousForward;

		internal WaterVolume m_previousBack;

		internal static readonly List<ValheimBaseGameShip> s_currentShips = new List<ValheimBaseGameShip>();

		internal ZNetView m_nview;

		internal Cloth m_sailCloth;

		internal float m_lastDepth = -9999f;

		internal float m_lastWaterImpactTime;

		internal float m_upsideDownDmgTimer;

		internal float m_rudderPaddleTimer;

		private bool m_cachedWindControlStatus;

		private float lastUpdateWindControlStatus;

		public Rigidbody m_body { get; set; }

		public Cloth? GetSailCloth()
		{
			if (!Object.op_Implicit((Object)(object)m_sailObject))
			{
				return null;
			}
			if (!Object.op_Implicit((Object)(object)m_sailCloth))
			{
				m_sailCloth = m_sailObject.GetComponent<Cloth>();
			}
			if (!Object.op_Implicit((Object)(object)m_sailCloth))
			{
				m_sailCloth = m_sailObject.AddComponent<Cloth>();
			}
			return m_sailCloth;
		}

		internal void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)m_nview))
			{
				Logger.LogError((object)"ValheimBaseShip initialized without NetView, or netview is not available yet (ghost mode?)");
			}
			WearNTear component = ((Component)this).GetComponent<WearNTear>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed));
			}
			m_body = ((Component)this).GetComponent<Rigidbody>();
			if (!Object.op_Implicit((Object)(object)m_body))
			{
				Logger.LogError((object)"No rigidbody detected, ship must have a Rigidbody to work");
			}
			m_body.mass = 2000f;
			m_body.useGravity = true;
			m_body.maxDepenetrationVelocity = 2f;
			ZNetView nview = m_nview;
			if (((nview != null) ? nview.GetZDO() : null) == null)
			{
				((Behaviour)this).enabled = false;
			}
			Heightmap.ForceGenerateAll();
		}

		public bool CanBeRemoved()
		{
			return m_players.Count == 0;
		}

		internal void PrintStats()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (m_players.Count != 0)
			{
				Vector3 velocity = m_body.velocity;
				Logger.LogDebug((object)("Vel:" + ((Vector3)(ref velocity)).magnitude.ToString("0.0")));
			}
		}

		internal static float GetUpwardsForce(float targetY, float currentY, float maxForce)
		{
			float num = targetY - currentY;
			if (num == 0f)
			{
				return 0f;
			}
			return Mathf.Clamp(1f / (25f / (num * num)) * ((num > 0f) ? maxForce : (0f - maxForce)), 0f - maxForce, maxForce);
		}

		public void UpdateUpsideDmg(float dt)
		{
			//IL_0006: 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_004f: Expected O, but got Unknown
			//IL_0067: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)this).transform.up.y >= 0f)
			{
				return;
			}
			m_upsideDownDmgTimer += dt;
			if (!(m_upsideDownDmgTimer <= m_upsideDownDmgInterval))
			{
				m_upsideDownDmgTimer = 0f;
				IDestructible component = ((Component)this).GetComponent<IDestructible>();
				if (component != null)
				{
					HitData val = new HitData();
					val.m_damage.m_blunt = m_upsideDownDmg;
					val.m_point = ((Component)this).transform.position;
					val.m_dir = Vector3.up;
					component.Damage(val);
				}
			}
		}

		public Vector3 GetSailForce(float sailSize, float dt)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0047: 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_0058: 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_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_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_0081: Unknown result type (might be due to invalid IL or missing references)
			Vector3 windDir = EnvMan.instance.GetWindDir();
			float windIntensity = EnvMan.instance.GetWindIntensity();
			float num = Mathf.Lerp(0.25f, 1f, windIntensity);
			float windAngleFactor = GetWindAngleFactor();
			windAngleFactor *= num;
			Vector3 val = Vector3.Normalize(windDir + ((Component)this).transform.forward) * windAngleFactor * m_sailForceFactor * sailSize;
			m_sailForce = Vector3.SmoothDamp(m_sailForce, val, ref m_windChangeVelocity, 1f, 99f);
			return m_sailForce;
		}

		public float GetWindAngleFactor()
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Dot(EnvMan.instance.GetWindDir(), -((Component)this).transform.forward);
			float num2 = Mathf.Lerp(0.7f, 1f, 1f - Mathf.Abs(num));
			float num3 = 1f - Utils.LerpStep(0.75f, 0.8f, num);
			return num2 * num3;
		}

		public void UpdateWaterForce(float depth, float dt)
		{
			//IL_0069: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			if (m_lastDepth == -9999f)
			{
				m_lastDepth = depth;
				return;
			}
			float num = depth - m_lastDepth;
			m_lastDepth = depth;
			float num2 = num / dt;
			if (num2 > 0f || !(Mathf.Abs(num2) > m_minWaterImpactForce) || !(Time.time - m_lastWaterImpactTime > m_minWaterImpactInterval))
			{
				return;
			}
			m_lastWaterImpactTime = Time.time;
			m_waterImpactEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
			if (m_players.Count > 0)
			{
				IDestructible component = ((Component)this).GetComponent<IDestructible>();
				if (component != null)
				{
					HitData val = new HitData();
					val.m_damage.m_blunt = m_waterImpactDamage;
					val.m_point = ((Component)this).transform.position;
					val.m_dir = Vector3.up;
					component.Damage(val);
				}
			}
		}

		public void ApplyEdgeForce(float dt)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			Vector3 position = ((Component)this).transform.position;
			float magnitude = ((Vector3)(ref position)).magnitude;
			float num = 10420f;
			if (magnitude > num)
			{
				Vector3 val = Vector3.Normalize(((Component)this).transform.position);
				float num2 = Utils.LerpStep(num, 10500f, magnitude) * 8f;
				Vector3 val2 = val * num2;
				m_body.AddForce(val2 * dt, (ForceMode)2);
			}
		}

		internal void FixTilt()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_00f5: 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_00c2: 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)
			float num = Mathf.Asin(((Component)this).transform.right.y);
			float num2 = Mathf.Asin(((Component)this).transform.forward.y);
			if (Mathf.Abs(num) > (float)Math.PI / 6f)
			{
				if (num > 0f)
				{
					((Component)this).transform.RotateAround(((Component)this).transform.position, ((Component)this).transform.forward, (0f - Time.fixedDeltaTime) * 20f);
				}
				else
				{
					((Component)this).transform.RotateAround(((Component)this).transform.position, ((Component)this).transform.forward, Time.fixedDeltaTime * 20f);
				}
			}
			if (Mathf.Abs(num2) > (float)Math.PI / 6f)
			{
				if (num2 > 0f)
				{
					((Component)this).transform.RotateAround(((Component)this).transform.position, ((Component)this).transform.right, (0f - Time.fixedDeltaTime) * 20f);
				}
				else
				{
					((Component)this).transform.RotateAround(((Component)this).transform.position, ((Component)this).transform.right, Time.fixedDeltaTime * 20f);
				}
			}
		}

		internal void UpdateOwner()
		{
			if (m_nview.IsValid() && m_nview.IsOwner() && Object.op_Implicit((Object)(object)Player.m_localPlayer) && m_players.Count > 0 && !IsPlayerInBoat(Player.m_localPlayer))
			{
				long owner = ((Character)m_players[0]).GetOwner();
				m_nview.GetZDO().SetOwner(owner);
				Logger.LogDebug((object)("Changing ship owner to " + owner + ", name: " + m_players[0].GetPlayerName()));
			}
		}

		public bool IsPlayerInBoat(ZDOID zdoid)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			foreach (Player player in m_players)
			{
				if (((Character)player).GetZDOID() == zdoid)
				{
					return true;
				}
			}
			return false;
		}

		public bool IsPlayerInBoat(Player player)
		{
			if (m_players.Contains(player))
			{
				return true;
			}
			if ((Object)(object)((Component)player).transform.root != (Object)null && ((Object)((Component)player).transform.root).name.Contains("ValheimVehicles_piecesContainer"))
			{
				return true;
			}
			return WaterZoneUtils.IsOnboard((Character)(object)player);
		}

		public bool IsPlayerInBoat(long playerId)
		{
			Player player = Player.GetPlayer(playerId);
			if ((Object)(object)player != (Object)null)
			{
				return IsPlayerInBoat(player);
			}
			return false;
		}

		public bool HasPlayerOnboard()
		{
			return m_players.Count > 0;
		}

		public void OnDestroyed()
		{
			if (m_nview.IsValid() && m_nview.IsOwner())
			{
				Gogan.LogEvent("Game", "ShipDestroyed", ((Object)((Component)this).gameObject).name, 0L);
			}
			s_currentShips.Remove(this);
		}

		public bool IsWindControllActive()
		{
			if (lastUpdateWindControlStatus < 2f)
			{
				lastUpdateWindControlStatus += Time.fixedDeltaTime;
				return m_cachedWindControlStatus;
			}
			foreach (Player player in m_players)
			{
				if (((Character)player).GetSEMan().HaveStatusAttribute((StatusAttribute)4))
				{
					m_cachedWindControlStatus = true;
					return m_cachedWindControlStatus;
				}
			}
			m_cachedWindControlStatus = false;
			return m_cachedWindControlStatus;
		}

		public static ValheimBaseGameShip GetLocalShip()
		{
			if (s_currentShips.Count != 0)
			{
				return s_currentShips[s_currentShips.Count - 1];
			}
			return null;
		}

		public bool IsOwner()
		{
			if (!Object.op_Implicit((Object)(object)m_nview))
			{
				return false;
			}
			if (m_nview.IsValid())
			{
				return m_nview.IsOwner();
			}
			return false;
		}

		public float GetSpeed()
		{
			//IL_0006: 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)
			return Vector3.Dot(m_body.velocity, ((Component)this).transform.forward);
		}

		public float GetShipYawAngle()
		{
			//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)
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)mainCamera == (Object)null)
			{
				return 0f;
			}
			return 0f - Utils.YawFromDirection(((Component)mainCamera).transform.InverseTransformDirection(((Component)this).transform.forward));
		}
	}
	public class VehicleMovementController : ValheimBaseGameShip, IVehicleMovement, IValheimShip, IMonoUpdater
	{
		public enum DirectionChange
		{
			Forward,
			Backward,
			Stop
		}

		public enum PhysicsTarget
		{
			VehicleShip,
			VehiclePieces
		}

		private bool _hasRegister;

		public bool isAnchored;

		private bool _isHoldingAnchor;

		public SteeringWheelComponent lastUsedWheelComponent;

		private VehicleShip vehicleShip;

		public Vector3 detachOffset = new Vector3(0f, 0.5f, 0f);

		internal bool m_forwardPressed;

		internal bool m_backwardPressed;

		internal new float m_sendRudderTime;

		internal float m_rudder;

		public float m_rudderSpeed = 0.5f;

		internal float m_rudderValue;

		public ZSyncTransform zsyncTransform;

		private Speed vehicleSpeed;

		private bool _isAscending;

		private bool _isDescending;

		private bool _isHoldingDescend;

		private bool _isHoldingAscend;

		private const float InitialTargetHeight = 0f;

		public const string m_attachAnimation = "Standing Torch Idle right";

		private float _rudderForce = 1f;

		private GameObject _ghostContainer;

		private ImpactEffect _impactEffect;

		public VehicleOnboardController OnboardController;

		public const float m_balanceForce = 0.03f;

		public const float m_liftForce = 20f;

		public const RigidbodyConstraints FreezeBothXZ = 80;

		public bool isBeached;

		private GameObject _vehiclePiecesContainerInstance;

		private GUIStyle myButtonStyle;

		public static PhysicsTarget PhysicsSyncTarget = PhysicsTarget.VehicleShip;

		[FormerlySerializedAs("TargetHeightObj")]
		public GameObject DebugTargetHeightObj;

		public Vector3 lastPosition = Vector3.zero;

		public float lastPositionUpdate;

		public const string vehicleKeyPrefix = "valheim_vehicle";

		public string vehicleMapKey = "";

		public float groundHeightPaddingOffset = 2f;

		private float _lastHighestGroundPoint;

		private float prevFrontUpwardForce;

		private float prevBackUpwardsForce;

		private float prevLeftUpwardsForce;

		private float prevRightUpwardsForce;

		private float prevCenterUpwardsForce;

		private float vehicleStatSyncTimer;

		private bool previousSyncFlight;

		private bool previousSyncSubmerged;

		private bool _prevGravity = true;

		public float lastFlyingDt;

		public bool cachedFlyingValue;

		private bool HasPendingAnchor;

		private Coroutine? _debouncedForceTakeoverControlsInstance;

		private float _previousTargetHeight;

		private ShipFloatation? _currentShipFloatation;

		public static float maxFlyingHeight = 5000f;

		private const float MaxFlightOffset = 10000f;

		public float cachedMaxDepthOffset;

		private float lastForceUpdateTimer;

		private const string InUseMessage = "$msg_inuse";

		public IVehicleShip? ShipInstance => vehicleShip;

		public VehiclePiecesController? PiecesController => vehicleShip?.PiecesController;

		public VehicleMovementFlags MovementFlags { get; set; }

		public Rigidbody rigidbody => base.m_body;

		public float TargetHeight { get; private set; }

		public Transform AttachPoint { get; set; }

		public bool HasOceanSwayDisabled { get; set; }

		public GameObject RudderObject { get; set; }

		public bool isCreative => (ShipInstance?.Instance?.isCreative).GetValueOrDefault();

		private Speed VehicleSpeed => GetSpeedSetting();

		public Transform ShipDirection { get; set; }

		public static List<VehicleMovementController> Instances { get; } = new List<VehicleMovementController>();


		public static List<IMonoUpdater> MonoUpdaterInstances { get; } = new List<IMonoUpdater>();


		public new Transform m_controlGuiPos { get; set; }

		public BoxCollider BlockingCollider { get; set; }

		public BoxCollider OnboardCollider { get; set; }

		public BoxCollider FloatCollider
		{
			get
			{
				return m_floatcollider;
			}
			set
			{
				m_floatcollider = value;
			}
		}

		public Transform ControlGuiPosition
		{
			get
			{
				return m_controlGuiPos;
			}
			set
			{
				m_controlGuiPos = value;
			}
		}

		private bool IsNotFlying => !IsFlying();

		public static bool HasPieceSyncTarget => PhysicsSyncTarget == PhysicsTarget.VehiclePieces;

		public ShipFloatation ShipFloatationObj
		{
			get
			{
				if (_currentShipFloatation.HasValue)
				{
					return _currentShipFloatation.Value;
				}
				_currentShipFloatation = GetShipFloatationObj();
				return _currentShipFloatation.Value;
			}
		}

		public static bool IsBallastAndFlightDisabled
		{
			get
			{
				if (!ValheimRaftPlugin.Instance.AllowFlight.Value)
				{
					return !WaterConfig.WaterBallastEnabled.Value;
				}
				return false;
			}
		}

		public bool GetAscendKeyPress
		{
			get
			{
				if (!ZInput.GetButton("Jump"))
				{
					return ZInput.GetButton("JoyJump");
				}
				return true;
			}
		}

		public bool GetDescendKeyPress
		{
			get
			{
				if (!ZInput.GetButton("Crouch"))
				{
					return ZInput.GetButton("JoyCrouch");
				}
				return true;
			}
		}

		public bool CanDescend
		{
			get
			{
				if (!WaterConfig.WaterBallastEnabled.Value || !IsNotFlying)
				{
					return IsFlying();
				}
				return true;
			}
		}

		private float GetMaxVerticalOffset()
		{
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			if (ValheimRaftPlugin.Instance.AllowFlight.Value)
			{
				if (!IsFlying())
				{
					Bounds bounds = ((Collider)OnboardCollider).bounds;
					if (!(((Bounds)(ref bounds)).max.y > ZoneSystem.instance.m_waterLevel) && !(TargetHeight - 2f > GetSurfaceOffsetWaterVehicleOnly()))
					{
						goto IL_005c;
					}
				}
				return PropulsionConfig.FlightClimbingOffset.Value;
			}
			goto IL_005c;
			IL_005c:
			return PropulsionConfig.BallastClimbingOffset.Value;
		}

		public Rigidbody GetRigidbody()
		{
			if (Object.op_Implicit((Object)(object)base.m_body))
			{
				return base.m_body;
			}
			if (!Object.op_Implicit((Object)(object)base.m_body))
			{
				base.m_body = ((Component)this).GetComponent<Rigidbody>();
			}
			return base.m_body;
		}

		private void RemovePlayersBeforeDestroyingBoat()
		{
			foreach (Player player in m_players)
			{
				if (Object.op_Implicit((Object)(object)player) && player != null)
				{
					Transform transform = ((Component)player).transform;
					if (transform != null)
					{
						transform.SetParent((Transform)null);
					}
				}
			}
		}

		private float GetRudderForcePerSpeed()
		{
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected I4, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			if (!ValheimRaftPlugin.Instance.AllowCustomRudderSpeeds.Value)
			{
				_rudderForce = 1f;
				return _rudderForce;
			}
			Speed val = VehicleSpeed;
			switch ((int)val)
			{
			case 0:
				_rudderForce = 0f;
				break;
			case 1:
				_rudderForce = Mathf.Clamp(ValheimRaftPlugin.Instance.VehicleRudderSpeedBack.Value, 0f, ValheimRaftPlugin.Instance.MaxPropulsionSpeed.Value);
				break;
			case 2:
				_rudderForce = Mathf.Clamp(ValheimRaftPlugin.Instance.VehicleRudderSpeedSlow.Value, 0f, ValheimRaftPlugin.Instance.MaxPropulsionSpeed.Value);
				break;
			case 3:
				_rudderForce = Mathf.Clamp(ValheimRaftPlugin.Instance.VehicleRudderSpeedHalf.Value, 0f, ValheimRaftPlugin.Instance.MaxPropulsionSpeed.Value);
				break;
			case 4:
				_rudderForce = Mathf.Clamp(ValheimRaftPlugin.Instance.VehicleRudderSpeedFull.Value, 0f, ValheimRaftPlugin.Instance.MaxPropulsionSpeed.Value);
				break;
			default:
				Logger.LogError((object)$"Speed value could not handle this variant, {VehicleSpeed}");
				_rudderForce = 1f;
				break;
			}
			return _rudderForce;
		}

		public bool HaveControllingPlayer()
		{
			if (m_players.Count != 0)
			{
				return HaveValidUser();
			}
			return false;
		}

		public bool IsReady()
		{
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (component == null)
			{
				return false;
			}
			return ((Behaviour)component).isActiveAndEnabled;
		}

		public void UpdateVehicleSpeedThrottle()
		{
			ZNetView nview = m_nview;
			bool flag = nview != null && nview.IsOwner();
			base.m_body.maxAngularVelocity = (flag ? ValheimRaftPlugin.Instance.MaxPropulsionSpeed.Value : 500f);
			base.m_body.maxLinearVelocity = (flag ? ValheimRaftPlugin.Instance.MaxPropulsionSpeed.Value : 500f);
		}

		public void InitColliders()
		{
			GameObject vehicleMovementCollidersObj = VehicleShip.GetVehicleMovementCollidersObj(((Component)this).transform);
			Transform val = vehicleMovementCollidersObj.transform.Find("VehicleShip_FloatCollider");
			Transform val2 = vehicleMovementCollidersObj.transform.Find("VehicleShip_BlockingCollider");
			Transform val3 = vehicleMovementCollidersObj.transform.Find("VehicleShip_OnboardTriggerCollider");
			if (Object.op_Implicit((Object)(object)((val3 != null) ? ((Component)val3).gameObject : null)))
			{
				OnboardController = ((Component)val3).gameObject.AddComponent<VehicleOnboardController>();
				if (!Object.op_Implicit((Object)(object)OnboardController.GetMovementController()))
				{
					Logger.LogError((object)"OnboardController controller initialized but null controller, manually initializng from VehicleMovementController parent");
					OnboardController.SetMovementController(this);
				}
			}
			((Object)val3).name = "VehicleShip_OnboardTriggerCollider";
			((Object)val).name = "VehicleShip_FloatCollider";
			((Object)val2).name = "VehicleShip_BlockingCollider";
			ShipDirection = val.Find("VehicleShip_MovementOrientation");
			BlockingCollider = ((Component)val2).GetComponent<BoxCollider>();
			FloatCollider = ((Component)val).GetComponent<BoxCollider>();
			OnboardCollider = ((Component)val3).GetComponent<BoxCollider>();
		}

		public void SetupImpactEffect()
		{
			//IL_00cd: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			_impactEffect = ((Component)this).GetComponent<ImpactEffect>();
			if (!Object.op_Implicit((Object)(object)_impactEffect))
			{
				_impactEffect = ((Component)this).gameObject.AddComponent<ImpactEffect>();
				_impactEffect.m_triggerMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[9]
				{
					"Default",
					"character",
					"piece",
					"terrain",
					"static_solid",
					"Default_small",
					"character_net",
					"vehicle",
					LayerMask.LayerToName(29)
				}));
				_impactEffect.m_toolTier = 1000;
			}
			_impactEffect.m_nview = m_nview;
			_impactEffect.m_body = base.m_body;
			_impactEffect.m_hitType = (HitType)17;
			_impactEffect.m_interval = 0.5f;
			_impactEffect.m_minVelocity = 0.1f;
		}

		private IEnumerator ShipFixRoutine()
		{
			while (((Behaviour)this).isActiveAndEnabled)
			{
				yield return FixShipRotation();
				yield return (object)new WaitForSeconds(5f);
			}
		}

		public void SetupPhysicsSync()
		{
			if (!Object.op_Implicit((Object)(object)zsyncTransform))
			{
				zsyncTransform = ((Component)this).GetComponent<ZSyncTransform>();
			}
			if (Object.op_Implicit((Object)(object)zsyncTransform))
			{
				zsyncTransform.m_body = GetRigidbody();
			}
		}

		public static void SetPhysicsSyncTarget(VehiclePhysicsMode val)
		{
			PhysicsSyncTarget = ((val == VehiclePhysicsMode.DesyncedJointRigidbodyBody) ? PhysicsTarget.VehiclePieces : PhysicsTarget.VehicleShip);
			foreach (VehicleMovementController instance in Instances)
			{
				instance.SetupPhysicsSync();
			}
		}

		public void SetupZsyncTransform()
		{
			zsyncTransform = ((Component)this).GetComponent<ZSyncTransform>();
			if (!((Object)(object)zsyncTransform == (Object)null))
			{
				zsyncTransform.m_syncPosition = true;
				zsyncTransform.m_syncBodyVelocity = true;
				zsyncTransform.m_syncRotation = true;
			}
		}

		public void AwakeSetupShipComponents()
		{
			//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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			vehicleShip = ((Component)this).GetComponent<VehicleShip>();
			GetRigidbody();
			SetupZsyncTransform();
			SetupPhysicsSync();
			SetupImpactEffect();
			InitColliders();
			UpdateVehicleSpeedThrottle();
			if (!Object.op_Implicit((Object)(object)m_mastObject))
			{
				GameObject val = new GameObject
				{
					name = "ValheimVehicles_VehicleSailMast"
				};
				val.transform.parent = ((Component)this).transform;
				m_mastObject = val;
			}
			if (!Object.op_Implicit((Object)(object)m_sailObject))
			{
				GameObject val2 = new GameObject
				{
					name = "ValheimVehicles_VehicleSail"
				};
				val2.transform.parent = ((Component)this).transform;
				m_sailObject = val2;
			}
		}

		public IEnumerator FixShipRotation()
		{
			Quaternion rotation = ((Component)this).transform.rotation;
			Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
			float x = eulerAngles.x;
			float y = eulerAngles.y;
			float z = eulerAngles.z;
			float num = x;
			float num2 = z;
			bool flag = false;
			float num3 = Mathf.Abs(x);
			if (num3 > 60f && num3 < 300f)
			{
				num = 0f;
				flag = true;
			}
			num3 = Mathf.Abs(z);
			if (num3 > 60f && num3 < 300f)
			{
				num2 = 0f;
				flag = true;
			}
			if (flag)
			{
				((Component)this).transform.rotation = Quaternion.Euler(num, y, num2);
			}
			yield return null;
		}

		private void UpdateRemovePieceCollisionExclusions()
		{
			//IL_0093: 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)
			int mask = LayerMask.GetMask(new string[1] { "piece_nonsolid" });
			if (!Object.op_Implicit((Object)(object)base.m_body))
			{
				GetRigidbody();
			}
			if (Object.op_Implicit((Object)(object)base.m_body))
			{
				int mask2 = LayerMask.GetMask(new string[9]
				{
					"Default",
					"character",
					"piece",
					"terrain",
					"static_solid",
					"Default_small",
					"character_net",
					"vehicle",
					LayerMask.LayerToName(29)
				});
				base.m_body.includeLayers = LayerMask.op_Implicit(mask2);
				base.m_body.excludeLayers = LayerMask.op_Implicit(mask);
			}
		}

		private new void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			AwakeSetupShipComponents();
			m_nview = ((Component)this).GetComponent<ZNetView>();
			int mask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" });
			base.m_body.excludeLayers = LayerMask.op_Implicit(mask);
			if (!Object.op_Implicit((Object)(object)m_nview))
			{
				m_nview = ((Component)this).GetComponent<ZNetView>();
			}
			if (ValheimRaftPlugin.Instance.AllowFlight.Value)
			{
				OnFlightChangePolling();
			}
			base.Awake();
		}

		public void Setup()
		{
			((MonoBehaviour)this).Invoke("UpdateRemovePieceCollisionExclusions", 5f);
			if (!Object.op_Implicit((Object)(object)m_nview))
			{
				m_nview = ((Component)this).GetComponent<ZNetView>();
			}
			if (!Object.op_Implicit((Object)(object)base.m_body))
			{
				base.m_body = ((Component)this).GetComponent<Rigidbody>();
			}
			VehicleMovementFlags @int = (VehicleMovementFlags)m_nview.GetZDO().GetInt(VehicleZdoVars.VehicleFlags, 0);
			MovementFlags = @int;
			isAnchored = MovementFlags.HasFlag(VehicleMovementFlags.IsAnchored);
			((MonoBehaviour)this).StartCoroutine(ShipFixRoutine());
			InitializeRPC();
			SyncShip();
		}

		public void Start()
		{
			Setup();
		}

		public void DEBUG_VisualizeFloatPoint()
		{
			//IL_007a: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			DebugTargetHeightObj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)DebugTargetHeightObj).name = "DEBUG_TargetHeightObj";
			DebugTargetHeightObj.transform.SetParent(((Component)this).transform);
			MeshRenderer component = DebugTargetHeightObj.GetComponent<MeshRenderer>();
			MeshFilter component2 = DebugTargetHeightObj.GetComponent<MeshFilter>();
			Object.Destroy((Object)(object)component);
			Object.Destroy((Object)(object)component2);
			DebugTargetHeightObj.layer = LayerHelpers.NonSolidLayer;
			DebugTargetHeightObj.transform.rotation = ((Component)FloatCollider).transform.rotation;
			Transform transform = DebugTargetHeightObj.transform;
			BoxCollider floatCollider = FloatCollider;
			transform.localScale = ((floatCollider != null) ? floatCollider.size : Vector3.one);
		}

		public string GetVehicleMapKey()
		{
			return string.Format("{0}_{1}", "valheim_vehicle", m_nview.GetZDO().GetOwner());
		}

		public void UpdateVehicleLocation(float deltaTime)
		{
			//IL_0025: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (lastPositionUpdate < 3f)
			{
				lastPositionUpdate += deltaTime;
			}
			else
			{
				lastPositionUpdate = deltaTime;
			}
			if (!(Vector3.Distance(lastPosition, ((Component)this).transform.position) < 3f))
			{
				MapMode mode = Minimap.m_instance.m_mode;
				if (vehicleMapKey != "")
				{
					ZoneSystem.m_instance.RemoveGlobalKey(vehicleMapKey);
				}
				vehicleMapKey = GetVehicleMapKey();
				if (vehicleMapKey != "")
				{
					ZoneSystem.m_instance.SetGlobalKey(vehicleMapKey);
					Minimap.m_instance.SetMapMode(mode);
				}
			}
		}

		public void CustomFixedUpdate(float deltaTime)
		{
			//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_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_0081: 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)
			if (!Object.op_Implicit((Object)(object)base.m_body) || !Object.op_Implicit((Object)(object)m_floatcollider))
			{
				return;
			}
			if (VehicleDebugConfig.AutoShowVehicleColliders.Value && (Object)(object)DebugTargetHeightObj != (Object)null)
			{
				DebugTargetHeightObj.transform.position = VectorUtils.MergeVectors(((Component)this).transform.position, Vector3.up * TargetHeight);
				Transform transform = DebugTargetHeightObj.transform;
				BoxCollider floatCollider = FloatCollider;
				transform.localScale = ((floatCollider != null) ? floatCollider.size : Vector3.one);
			}
			if (!vehicleShip.PiecesController.isInitialActivationComplete)
			{
				base.m_body.isKinematic = true;
				return;
			}
			if (ValheimRaftPlugin.Instance.AllowFlight.Value || WaterConfig.WaterBallastEnabled.Value)
			{
				SyncTargetHeight();
			}
			UpdateShipWheelTurningSpeed();
			if (!isCreative)
			{
				if (base.m_body.isKinematic)
				{
					base.m_body.isKinematic = false;
				}
				VehiclePhysicsFixedUpdateAllClients();
				VehicleMovementUpdatesOwnerOnly();
			}
		}

		public void CustomUpdate(float deltaTime, float time)
		{
			if (!((Object)(object)PiecesController == (Object)null))
			{
				PiecesController.Sync();
			}
		}

		public void CustomLateUpdate(float deltaTime)
		{
			SyncShip();
		}

		public void UpdateShipDirection(Quaternion steeringWheelRotation)
		{
			//IL_0007: 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_001b: 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_0044: 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)
			Quaternion val = Quaternion.Euler(0f, ((Quaternion)(ref steeringWheelRotation)).eulerAngles.y, 0f);
			if (!Object.op_Implicit((Object)(object)ShipDirection))
			{
				ShipDirection = ((Component)this).transform;
				return;
			}
			Quaternion localRotation = ShipDirection.localRotation;
			if (!((Quaternion)(ref localRotation)).Equals(val))
			{
				ShipDirection.localRotation = val;
			}
		}

		private static Vector3 CalculateAnchorStopVelocity(Vector3 currentVelocity)
		{
			//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_0006: 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_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)
			Vector3 zero = Vector3.zero;
			return Vector3.SmoothDamp(currentVelocity * 0.5f, Vector3.zero, ref zero, 5f);
		}

		public void AddForceAtPosition(Vector3 force, Vector3 position, ForceMode forceMode)
		{
			//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)
			base.m_body.AddForceAtPosition(force, position, forceMode);
		}

		private float GetFloatSizeFromDirection(Vector3 direction)
		{
			//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_002a: 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)
			if (direction == Vector3.right)
			{
				return m_floatcollider.size.x / 2f;
			}
			return m_floatcollider.size.z / 2f;
		}

		private float GetHighestGroundPoint(ShipFloatation shipFloatation)
		{
			float[] source = new float[5] { shipFloatation.GroundLevelCenter, shipFloatation.GroundLevelBack, shipFloatation.GroundLevelForward, shipFloatation.GroundLevelLeft, shipFloatation.GroundLevelRight };
			_lastHighestGroundPoint = source.Max();
			return _lastHighestGroundPoint;
		}

		public static void UpdateYPosition(Transform targetTransform, float newYPosition)
		{
			//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_0008: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = targetTransform.localPosition;
			targetTransform.localPosition = new Vector3(localPosition.x, newYPosition, localPosition.z);
		}

		public void UpdateCenterOfMass()
		{
			//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_001a: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00c5: 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_005a: 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_0062: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			base.m_body.automaticCenterOfMass = false;
			Bounds bounds = ((Collider)OnboardCollider).bounds;
			float y = ((Bounds)(ref bounds)).min.y;
			bounds = ((Collider)BlockingCollider).bounds;
			if (y > ((Bounds)(ref bounds)).min.y)
			{
				Rigidbody body = base.m_body;
				float x = OnboardCollider.center.x;
				bounds = ((Collider)OnboardCollider).bounds;
				body.centerOfMass = new Vector3(x, ((Bounds)(ref bounds)).center.y, OnboardCollider.center.z);
			}
			else
			{
				Rigidbody body2 = base.m_body;
				float x2 = BlockingCollider.center.x;
				bounds = ((Collider)BlockingCollider).bounds;
				body2.centerOfMass = new Vector3(x2, ((Bounds)(ref bounds)).center.y, BlockingCollider.center.z);
			}
		}

		private void UpdateColliderPositions()
		{
			//IL_001a: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009c: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PiecesController == (Object)null)
			{
				return;
			}
			float y = ((Component)BlockingCollider).transform.position.y;
			Bounds bounds = ((Collider)BlockingCollider).bounds;
			float num = y - ((Bounds)(ref bounds)).extents.y;
			if (!IsFlying() && WaterConfig.WaterBallastEnabled.Value)
			{
				if (_lastHighestGroundPoint > num)
				{
					float num2 = _lastHighestGroundPoint - ((Component)BlockingCollider).transform.position.y;
					UpdateTargetHeight(TargetHeight + num2);
				}
				float lastHighestGroundPoint = _lastHighestGroundPoint;
				bounds = ((Collider)OnboardCollider).bounds;
				if (lastHighestGroundPoint > ((Bounds)(ref bounds)).min.y)
				{
					float lastHighestGroundPoint2 = _lastHighestGroundPoint;
					bounds = ((Collider)OnboardCollider).bounds;
					float num3 = lastHighestGroundPoint2 - ((Bounds)(ref bounds)).min.y;
					UpdateTargetHeight(TargetHeight + num3);
				}
				if (_lastHighestGroundPoint > ((Component)BlockingCollider).transform.position.y)
				{
					((Component)this).transform.position = new Vector3(((Component)this).transform.position.x, ((Component)this).transform.position.y + (_lastHighestGroundPoint - ((Component)BlockingCollider).transform.position.y), ((Component)this).transform.position.z);
					UpdateTargetHeight(0f);
				}
			}
		}

		public float GetFlyingTargetHeight()
		{
			return TargetHeight;
		}

		public void Flying_UpdateShipBalancingForce()
		{
			//IL_0006: 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_001c: 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_0030: 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_003a: 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_004c: 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_0061: 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_0075: 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_0087: 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_009c: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: 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_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ShipDirection.position + ShipDirection.forward * FloatCollider.size.z / 2f;
			Vector3 val2 = ShipDirection.position - ShipDirection.forward * FloatCollider.size.z / 2f;
			Vector3 val3 = ShipDirection.position - ShipDirection.right * FloatCollider.size.x / 2f;
			Vector3 val4 = ShipDirection.position + ShipDirection.right * FloatCollider.size.x / 2f;
			Vector3 position = ShipDirection.position;
			Vector3 pointVelocity = base.m_body.GetPointVelocity(val);
			Vector3 pointVelocity2 = base.m_body.GetPointVelocity(val2);
			Vector3 pointVelocity3 = base.m_body.GetPointVelocity(val3);
			Vector3 pointVelocity4 = base.m_body.GetPointVelocity(val4);
			float flyingTargetHeight = GetFlyingTargetHeight();
			float upwardsForce = ValheimBaseGameShip.GetUpwardsForce(flyingTargetHeight, val.y + pointVelocity.y, 0.03f);
			float upwardsForce2 = ValheimBaseGameShip.GetUpwardsForce(flyingTargetHeight, val2.y + pointVelocity2.y, 0.03f);
			float upwardsForce3 = ValheimBaseGameShip.GetUpwardsForce(flyingTargetHeight, val3.y + pointVelocity3.y, 0.03f);
			float upwardsForce4 = ValheimBaseGameShip.GetUpwardsForce(flyingTargetHeight, val4.y + pointVelocity4.y, 0.03f);
			float upwardsForce5 = ValheimBaseGameShip.GetUpwardsForce(flyingTargetHeight, position.y + base.m_body.velocity.y, 20f);
			float num = 3f + PropulsionConfig.VerticalSmoothingSpeed.Value * 10f;
			upwardsForce = Mathf.SmoothDamp(prevFrontUpwardForce, upwardsForce, ref prevFrontUpwardForce, num);
			upwardsForce2 = Mathf.SmoothDamp(prevBackUpwardsForce, upwardsForce2, ref prevBackUpwardsForce, num);
			upwardsForce3 = Mathf.SmoothDamp(prevLeftUpwardsForce, upwardsForce3, ref prevLeftUpwardsForce, num);
			upwardsForce4 = Mathf.SmoothDamp(prevRightUpwardsForce, upwardsForce4, ref prevRightUpwardsForce, num);
			upwardsForce5 = Mathf.SmoothDamp(prevCenterUpwardsForce, upwardsForce5, ref prevCenterUpwardsForce, num);
			AddForceAtPosition(Vector3.up * upwardsForce, val, (ForceMode)2);
			AddForceAtPosition(Vector3.up * upwardsForce2, val2, (ForceMode)2);
			AddForceAtPosition(Vector3.up * upwardsForce3, val3, (ForceMode)2);
			AddForceAtPosition(Vector3.up * upwardsForce4, val4, (ForceMode)2);
			AddForceAtPosition(Vector3.up * upwardsForce5, position, (ForceMode)2);
		}

		public float GetForwardVelocity()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = base.m_body.velocity;
			return Vector3.Dot(ShipDirection.InverseTransformDirection(velocity), Vector3.forward);
		}

		public void UpdateAndFreezeRotation()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_002d: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Invalid comparison between Unknown and I4
			Quaternion rotation = base.m_body.rotation;
			bool num = Mathf.Approximately(((Quaternion)(ref rotation)).eulerAngles.x, 0f);
			rotation = base.m_body.rotation;
			bool flag = Mathf.Approximately(((Quaternion)(ref rotation)).eulerAngles.z, 0f);
			if (!num || !flag)
			{
				base.m_body.constraints = (RigidbodyConstraints)0;
				rotation = base.m_body.rotation;
				Quaternion val = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f);
				base.m_body.MoveRotation(val);
			}
			if ((int)base.m_body.constraints != 80)
			{
				base.m_body.constraints = (RigidbodyConstraints)80;
			}
		}

		public void UpdateFlyingVehicle()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			UpdateVehicleStats(flight: true, submerged: false);
			UpdateAndFreezeRotation();
			if (!UpdateAnchorVelocity(base.m_body.velocity))
			{
				base.m_body.WakeUp();
				Flying_UpdateShipBalancingForce();
				if (!ValheimRaftPlugin.Instance.FlightHasRudderOnly.Value)
				{
					ApplySailForce(this, isFlying: true);
				}
			}
		}

		public void UpdateShipLandSpeed()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			UpdateVehicleStats(flight: false, submerged: false);
			if (!UpdateAnchorVelocity(base.m_body.velocity))
			{
				base.m_body.WakeUp();
				if (!ValheimRaftPlugin.Instance.AllowFlight.Value && PropulsionConfig.EnableLandVehicles.Value)
				{
					ApplySailForce(this);
				}
			}
		}

		private float GetDamageFromImpact()
		{
			if (!Object.op_Implicit((Object)(object)base.m_body))
			{
				return 50f;
			}
			Rigidbody body = base.m_body;
			float num = ((body != null) ? body.mass : 1000f) * 0.01f;
			return Math.Min(500f, 25f + num);
		}

		private void UpdateFlightStats()
		{
			m_angularDamping = PhysicsConfig.flightSteerForce.Value;
			m_damping = PhysicsConfig.flightDamping.Value;
			m_dampingSideway = PhysicsConfig.flightSidewaysDamping.Value;
			m_sailForceFactor = PhysicsConfig.flightSailForceFactor.Value;
			m_stearForce = PhysicsConfig.flightSteerForce.Value;
			float value = PhysicsConfig.flightDrag.Value;
			float value2 = PhysicsConfig.flightAngularDrag.Value;
			ShipInstance?.VehiclePiecesController?.SyncRigidbodyStats(value, value2, flight: true);
		}

		public void UpdateSubmergedStats()
		{
			m_angularDamping = PhysicsConfig.submersibleAngularDamping.Value;
			m_damping = PhysicsConfig.submersibleDamping.Value;
			m_dampingSideway = PhysicsConfig.submersibleSidewaysDamping.Value;
			m_sailForceFactor = PhysicsConfig.submersibleSailForceFactor.Value;
			m_stearForce = PhysicsConfig.submersibleSteerForce.Value;
			float value = PhysicsConfig.submersibleDrag.Value;
			float value2 = PhysicsConfig.submersibleAngularDrag.Value;
			ShipInstance?.VehiclePiecesController?.SyncRigidbodyStats(value, value2, flight: false);
		}

		public void UpdateWaterStats()
		{
			m_angularDamping = PhysicsConfig.waterAngularDamping.Value;
			m_damping = PhysicsConfig.waterDamping.Value;
			m_dampingSideway = PhysicsConfig.waterSidewaysDamping.Value;
			m_sailForceFactor = PhysicsConfig.waterSailForceFactor.Value;
			m_stearForce = PhysicsConfig.waterSteerForce.Value;
			float value = PhysicsConfig.waterDrag.Value;
			float value2 = PhysicsConfig.waterAngularDrag.Value;
			ShipInstance?.VehiclePiecesController?.SyncRigidbodyStats(value, value2, flight: false);
		}

		public void UpdateVehicleStats(bool flight, bool submerged, bool forceUpdate = false)
		{
			if (!forceUpdate)
			{
				float num = vehicleStatSyncTimer;
				if (num > 0f && num < 30f && previousSyncFlight == flight && previousSyncSubmerged == submerged)
				{
					vehicleStatSyncTimer += Time.fixedDeltaTime;
					return;
				}
			}
			vehicleStatSyncTimer = Time.fixedDeltaTime;
			previousSyncFlight = flight;
			previousSyncSubmerged = submerged;
			if (flight)
			{
				UpdateFlightStats();
			}
			else if (submerged)
			{
				UpdateSubmergedStats();
			}
			else
			{
				UpdateWaterStats();
			}
			m_force = 3f;
			m_forceDistance = 5f;
			m_stearVelForceFactor = 1.3f;
			m_waterImpactDamage = 0f;
			m_backwardForce = 1f;
			if (Object.op_Implicit((Object)(object)_impactEffect))
			{
				_impactEffect.m_damages.m_blunt = GetDamageFromImpact();
			}
			else
			{
				Logger.LogDebug((object)"No Ship ImpactEffect detected, this needs to be added to the custom ship");
			}
		}

		public void UpdateWaterForce(ShipFloatation shipFloatation)
		{
			//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_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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_007f: 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_008d: 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_009c: 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_00af: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0122: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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_0163: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: 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_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 shipLeft = shipFloatation.ShipLeft;
			Vector3 shipForward = shipFloatation.ShipForward;
			Vector3 shipBack = shipFloatation.ShipBack;
			Vector3 shipRight = shipFloatation.ShipRight;
			float waterLevelLeft = shipFloatation.WaterLevelLeft;
			float waterLevelRight = shipFloatation.WaterLevelRight;
			float waterLevelForward = shipFloatation.WaterLevelForward;
			float waterLevelBack = shipFloatation.WaterLevelBack;
			float currentDepth = shipFloatation.CurrentDepth;
			Vector3 worldCenterOfMass = base.m_body.worldCenterOfMass;
			if (!shipFloatation.IsAboveBuoyantLevel)
			{
				base.m_body.WakeUp();
				if (m_waterImpactDamage > 0f)
				{
					UpdateWaterForce(currentDepth, Time.fixedDeltaTime);
				}
				Vector3 val = new Vector3(shipLeft.x, waterLevelLeft, shipLeft.z);
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(shipRight.x, waterLevelRight, shipRight.z);
				Vector3 val3 = new Vector3(shipForward.x, waterLevelForward, shipForward.z);
				Vector3 val4 = default(Vector3);
				((Vector3)(ref val4))..ctor(shipBack.x, waterLevelBack, shipBack.z);
				float num = Time.fixedDeltaTime * 50f;
				float num2 = Mathf.Clamp01(Mathf.Abs(currentDepth) / m_forceDistance);
				Vector3 val5 = Vector3.up * m_force * num2;
				AddForceAtPosition(val5 * num, worldCenterOfMass, (ForceMode)2);
				float num3 = Vector3.Dot(base.m_body.velocity, ShipDirection.forward);
				float num4 = Vector3.Dot(base.m_body.velocity, ShipDirection.right);
				Vector3 val6 = base.m_body.velocity;
				float num5 = val6.y * val6.y * Mathf.Sign(val6.y) * m_damping * num2;
				float num6 = num3 * num3 * Mathf.Sign(num3) * m_dampingForward * num2;
				float num7 = num4 * num4 * Mathf.Sign(num4) * m_dampingSideway * num2;
				val6.y -= Mathf.Clamp(num5, -1f, 1f);
				val6 -= ShipDirection.forward * Mathf.Clamp(num6, -1f, 1f);
				val6 -= ShipDirection.right * Mathf.Clamp(num7, -1f, 1f);
				float magnitude = ((Vector3)(ref val6)).magnitude;
				Vector3 velocity = base.m_body.velocity;
				if (magnitude > ((Vector3)(ref velocity)).magnitude)
				{
					Vector3 normalized = ((Vector3)(ref val6)).normalized;
					velocity = base.m_body.velocity;
					val6 = normalized * ((Vector3)(ref velocity)).magnitude;
				}
				base.m_body.velocity = val6;
				Rigidbody body = base.m_body;
				body.angularVelocity -= base.m_body.angularVelocity * m_angularDamping * num2;
				float num8 = 0.15f;
				float num9 = 0.5f;
				float num10 = Mathf.Clamp((val3.y - shipForward.y) * num8, 0f - num9, num9);
				float num11 = Mathf.Clamp((val4.y - shipBack.y) * num8, 0f - num9, num9);
				float num12 = Mathf.Clamp((val.y - shipLeft.y) * num8, 0f - num9, num9);
				float num13 = Mathf.Clamp((val2.y - shipRight.y) * num8, 0f - num9, num9);
				num10 = Mathf.Sign(num10) * Mathf.Abs(Mathf.Pow(num10, 2f));
				num11 = Mathf.Sign(num11) * Mathf.Abs(Mathf.Pow(num11, 2f));
				num12 = Mathf.Sign(num12) * Mathf.Abs(Mathf.Pow(num12, 2f));
				num13 = Mathf.Sign(num13) * Mathf.Abs(Mathf.Pow(num13, 2f));
				AddForceAtPosition(Vector3.up * num10 * num, shipForward, (ForceMode)2);
				AddForceAtPosition(Vector3.up * num11 * num, shipBack, (ForceMode)2);
				AddForceAtPosition(Vector3.up * num12 * num, shipLeft, (ForceMode)2);
				AddForceAtPosition(Vector3.up * num13 * num, shipRight, (ForceMode)2);
			}
		}

		public void UpdateShipFloatation(ShipFloatation shipFloatation)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			UpdateVehicleStats(flight: false, IsSubmerged());
			UpdateWaterForce(shipFloatation);
			ApplyEdgeForce(Time.fixedDeltaTime);
			if (HasOceanSwayDisabled)
			{
				UpdateAndFreezeRotation();
			}
			else if ((int)base.m_body.constraints == 80)
			{
				base.m_body.constraints = (RigidbodyConstraints)0;
			}
			if (!UpdateAnchorVelocity(base.m_body.velocity))
			{
				ApplySailForce(this);
			}
		}

		private bool UpdateAnchorVelocity(Vector3 velocity)
		{
			//IL_0017: 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_001d: 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_002e: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			if (m_players.Count != 0 && !isAnchored)
			{
				return false;
			}
			Vector3 velocity2 = CalculateAnchorStopVelocity(velocity);
			Vector3 angularVelocity = CalculateAnchorStopVelocity(base.m_body.angularVelocity);
			base.m_body.velocity = velocity2;
			base.m_body.angularVelocity = angularVelocity;
			return true;
		}

		public ShipFloatation GetShipFloatationObj()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0063: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//I

plugins\ZdoWatcher.dll

Decompiled 3 weeks 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)
		{
		}
	}
}