Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimRAFTAnchorFix v1.1.0
BepInEx/plugins/ValheimRAFTAnchorFix/ValheimRAFTAnchorFix.dll
Decompiled 16 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using ValheimVehicles.Controllers; using ValheimVehicles.Propulsion.Rudder; using ValheimVehicles.SharedScripts; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimRAFT Anchor Fix")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyVersion("1.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ValheimRAFTAnchorFix { [BepInPlugin("com.l4zershark.valheimraftanchorfix", "ValheimRAFT Anchor Fix", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency("com.jotunn.jotunn", "2.30.2")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Id = "com.l4zershark.valheimraftanchorfix"; private static readonly Harmony Patches = new Harmony("com.l4zershark.valheimraftanchorfix"); internal static bool Active; internal static ConfigEntry<bool> HorizontalLock; internal static ConfigEntry<bool> VerticalLock; private void Awake() { //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_002c: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //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_0067: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown try { HorizontalLock = ((BaseUnityPlugin)this).Config.Bind<bool>("Anchor", "HorizontalLock", true, new ConfigDescription("Keep anchored ships at their parked horizontal position. Rotation remains locked. [Synced with Server]", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); VerticalLock = ((BaseUnityPlugin)this).Config.Bind<bool>("Anchor", "VerticalLock", false, new ConfigDescription("Keep anchored ships at their parked height. Leave disabled to allow wave bobbing. [Synced with Server]", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); string text; using (SHA256 sHA = SHA256.Create()) { text = BitConverter.ToString(sHA.ComputeHash(File.ReadAllBytes(typeof(VehicleMovementController).Assembly.Location))).Replace("-", ""); } if (text != "432B674C5CDDB69FBC763372507E3E687B733480F0ABEE218DEDDE8872B91E29") { throw new NotSupportedException("Expected the reviewed ValheimRAFT 5.0.7 ValheimVehicles.dll."); } SetEnabled(enabled: true); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Anchor position persistence active for ValheimRAFT 5.0.7. Install on every client and the server."); } catch (Exception ex) { Patches.UnpatchSelf(); Active = false; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Anchor fix inactive: " + ex.Message)); } } internal static void SetEnabled(bool enabled) { if (enabled == Active) { return; } if (enabled) { Patches.PatchAll(typeof(Plugin).Assembly); } else { AnchorControls.Clear(); Patches.UnpatchSelf(); foreach (VehicleMovementController instance in VehicleMovementController.Instances) { AnchorLock.ReleaseLocal(instance); } } Active = enabled; } private void OnDestroy() { SetEnabled(enabled: false); } } [HarmonyPatch(typeof(VehicleMovementController), "Setup")] internal static class SetupPatch { private static void Postfix(VehicleMovementController __instance) { AnchorLock.Hold(__instance); } } [HarmonyPatch(typeof(VehicleMovementController), "SyncAnchor")] internal static class AnchorSyncPatch { private static bool Prefix(VehicleMovementController __instance) { //IL_000b: 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) if (AnchorLock.TryPendingAnchor(__instance, out var anchor)) { __instance.vehicleAnchorState = anchor; if (Object.op_Implicit((Object)(object)__instance.PiecesController)) { __instance.PiecesController.UpdateAnchorState(anchor); } return false; } if (!__instance.CanAnchor && AnchorLock.IsAnchored(__instance)) { __instance.vehicleAnchorState = (AnchorState)2; return false; } return true; } } [HarmonyPatch(typeof(VehicleMovementController), "UpdateAnchorCapabilities")] internal static class AnchorCapabilityPatch { private static void Postfix(VehicleMovementController __instance) { if (AnchorLock.IsAnchored(__instance)) { __instance.CanAnchor = true; } } } [HarmonyPatch(typeof(AnchorMechanismController), "Start")] internal static class AnchorPieceStartPatch { internal static readonly HashSet<AnchorMechanismController> Starting = new HashSet<AnchorMechanismController>(); private static void Prefix(AnchorMechanismController __instance) { Starting.Add(__instance); } private static void Postfix(AnchorMechanismController __instance) { VehicleAnchorMechanismController val = (VehicleAnchorMechanismController)(object)((__instance is VehicleAnchorMechanismController) ? __instance : null); if (Object.op_Implicit((Object)(object)val) && AnchorLock.IsAnchored(val.MovementController)) { ((AnchorMechanismController)val).UpdateAnchorState((AnchorState)2, VehicleAnchorMechanismController.GetCurrentStateTextStatic((AnchorState)2, val.IsLandVehicle())); } } private static void Finalizer(AnchorMechanismController __instance) { Starting.Remove(__instance); } } [HarmonyPatch(typeof(VehicleAnchorMechanismController), "OnAnchorStateChange")] internal static class AnchorPieceStartupCallbackPatch { private static bool Prefix(VehicleAnchorMechanismController __instance, AnchorState newState) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)newState == 4 && AnchorPieceStartPatch.Starting.Contains((AnchorMechanismController)(object)__instance)) { return !AnchorLock.IsAnchored(__instance.MovementController); } return true; } } [HarmonyPatch(typeof(VehicleMovementController), "SetAnchor")] internal static class SetAnchorPatch { private static void Postfix(VehicleMovementController __instance, AnchorState state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) AnchorLock.AnchorChanged(__instance, state); } } [HarmonyPatch(typeof(VehicleMovementController), "RPC_SpeedChange")] internal static class SpeedReleasePatch { private static void Postfix(VehicleMovementController __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsOwner() && (int)__instance.vehicleAnchorState == 3 && AnchorLock.IsAnchored(__instance)) { __instance.SetAnchor((AnchorState)3, false); } } } [HarmonyPatch(typeof(VehicleMovementController), "GuardedFixedUpdate")] internal static class FixedUpdatePatch { private static void Prefix(VehicleMovementController __instance) { AnchorLock.Hold(__instance); } private static void Postfix(VehicleMovementController __instance) { AnchorLock.Hold(__instance); } } [HarmonyPatch(typeof(VehicleMovementController), "VehicleMovementUpdatesOwnerOnly")] internal static class WaterPhysicsPatch { private static void Prefix(VehicleMovementController __instance) { __instance.UpdateAnchorCapabilities(); AnchorLock.Hold(__instance); } private static void Postfix(VehicleMovementController __instance) { AnchorLock.Hold(__instance); } } [HarmonyPatch(typeof(VehicleZSyncTransform), "OwnerSync")] internal static class OwnerSyncPatch { private static void Prefix(VehicleZSyncTransform __instance) { AnchorLock.Hold(((Component)__instance).GetComponent<VehicleMovementController>()); } private static void Postfix(VehicleZSyncTransform __instance) { AnchorLock.Hold(((Component)__instance).GetComponent<VehicleMovementController>()); } } [HarmonyPatch(typeof(VehicleZSyncTransform), "ClientSync")] internal static class ClientSyncPatch { private static void Postfix(VehicleZSyncTransform __instance) { AnchorLock.Hold(((Component)__instance).GetComponent<VehicleMovementController>()); } } [HarmonyPatch(typeof(VehicleMovementController), "SetIsTeleporting")] internal static class TeleportPatch { private static void Postfix(VehicleMovementController __instance, bool isTeleporting) { if (isTeleporting) { AnchorLock.Suspend(__instance); } } } [HarmonyPatch(typeof(VehicleMovementController), "FixShipRotation")] internal static class AutomaticRightingPatch { private static bool Prefix(VehicleMovementController __instance, ref IEnumerator __result) { if (!AnchorLock.Hold(__instance)) { return true; } __result = Empty(); return false; } private static IEnumerator Empty() { yield break; } } internal static class AnchorLock { private sealed class LocalState { internal bool Held; internal bool CaptureCurrent; internal RigidbodyConstraints PreviousConstraints; internal int PendingAnchor = -1; internal float PendingSince; internal Vector3 PendingPosition; internal Quaternion PendingRotation; } internal const string ValidKey = "L4zerShark.RaftAnchorFix.v1.valid"; internal const string PositionKey = "L4zerShark.RaftAnchorFix.v1.position"; internal const string RotationKey = "L4zerShark.RaftAnchorFix.v1.rotation"; internal const string LockedAxesKey = "L4zerShark.RaftAnchorFix.v2.lockedAxes"; private const int Horizontal = 1; private const int Vertical = 2; private const int AllAxes = 3; private const string AnchorKey = "VehicleAnchorState"; private static readonly ConditionalWeakTable<VehicleMovementController, LocalState> States = new ConditionalWeakTable<VehicleMovementController, LocalState>(); internal static bool IsAnchored(VehicleMovementController ship) { if (Object.op_Implicit((Object)(object)ship) && Object.op_Implicit((Object)(object)ship.m_nview) && ship.m_nview.IsValid()) { return ship.m_nview.GetZDO().GetInt("VehicleAnchorState", 0) == 2; } return false; } internal static bool TryPendingAnchor(VehicleMovementController ship, out AnchorState anchor) { anchor = (AnchorState)0; if (!Object.op_Implicit((Object)(object)ship) || !Object.op_Implicit((Object)(object)ship.m_nview) || !ship.m_nview.IsValid() || !States.TryGetValue(ship, out var value) || value.PendingAnchor < 0) { return false; } if (ship.m_nview.IsOwner() || ship.m_nview.GetZDO().GetInt("VehicleAnchorState", 0) == value.PendingAnchor || Time.realtimeSinceStartup - value.PendingSince >= 2f) { value.PendingAnchor = -1; return false; } anchor = (AnchorState)value.PendingAnchor; return true; } internal static void ReleaseLocal(VehicleMovementController ship) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)ship) && States.TryGetValue(ship, out var value) && value.Held) { if (Object.op_Implicit((Object)(object)((ValheimBaseGameShip)ship).m_body)) { ((ValheimBaseGameShip)ship).m_body.constraints = value.PreviousConstraints; } value.Held = false; } } internal static void Suspend(VehicleMovementController ship) { if (Object.op_Implicit((Object)(object)ship)) { ReleaseLocal(ship); States.GetOrCreateValue(ship).CaptureCurrent = true; if (Object.op_Implicit((Object)(object)ship.m_nview) && ship.m_nview.IsValid() && ship.m_nview.IsOwner()) { ship.m_nview.GetZDO().Set("L4zerShark.RaftAnchorFix.v1.valid", false); } } } internal static void AnchorChanged(VehicleMovementController ship, AnchorState anchor) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected I4, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!Object.op_Implicit((Object)(object)ship) || !Object.op_Implicit((Object)(object)ship.m_nview) || !ship.m_nview.IsValid()) { return; } LocalState orCreateValue = States.GetOrCreateValue(ship); if (!ship.m_nview.IsOwner() && Object.op_Implicit((Object)(object)((ValheimBaseGameShip)ship).m_body)) { orCreateValue.PendingAnchor = (int)anchor; orCreateValue.PendingSince = Time.realtimeSinceStartup; orCreateValue.PendingPosition = ((ValheimBaseGameShip)ship).m_body.position; orCreateValue.PendingRotation = ((ValheimBaseGameShip)ship).m_body.rotation; } else { orCreateValue.PendingAnchor = -1; } if ((int)anchor != 2) { if (ship.m_nview.IsOwner()) { ship.m_nview.GetZDO().Set("L4zerShark.RaftAnchorFix.v1.valid", false); } ReleaseLocal(ship); States.GetOrCreateValue(ship).CaptureCurrent = true; } else { if (ship.m_nview.IsOwner() && !ship.m_nview.GetZDO().GetBool("L4zerShark.RaftAnchorFix.v1.valid", false)) { States.GetOrCreateValue(ship).CaptureCurrent = true; } Hold(ship); } } internal static bool Hold(VehicleMovementController ship) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Invalid comparison between Unknown and I4 //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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: 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_0157: 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_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02db: 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_02fd: 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_0302: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0284: 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_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_030d: 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_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: 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_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: 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_03cb: 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_0408: 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_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ship) || !Object.op_Implicit((Object)(object)ship.m_nview) || !ship.m_nview.IsValid() || !Object.op_Implicit((Object)(object)((ValheimBaseGameShip)ship).m_body) || (Object)(object)ship.Manager == (Object)null) { return false; } ZDO zDO = ship.m_nview.GetZDO(); LocalState orCreateValue = States.GetOrCreateValue(ship); int num = (Plugin.HorizontalLock.Value ? 1 : 0) | (Plugin.VerticalLock.Value ? 2 : 0); AnchorState anchor; bool flag = TryPendingAnchor(ship, out anchor); if (flag ? ((int)anchor != 2) : (!IsAnchored(ship))) { ReleaseLocal(ship); if (ship.m_nview.IsOwner() && zDO.GetBool("L4zerShark.RaftAnchorFix.v1.valid", false)) { zDO.Set("L4zerShark.RaftAnchorFix.v1.valid", false); } return false; } if (ship.Manager.IsLandVehicle || (Object)(object)ship.Manager.VehicleParent != (Object)null || zDO.GetInt("MBParentId", 0) != 0 || ship.isCreative || ship.IsTeleporting || ship.isPlayerHaulingVehicle) { Suspend(ship); return false; } int num2 = zDO.GetInt("L4zerShark.RaftAnchorFix.v2.lockedAxes", 3) & 3; int num3 = num; bool flag2 = flag || zDO.GetBool("L4zerShark.RaftAnchorFix.v1.valid", false); Vector3 val; Quaternion val2; if (flag) { val = orCreateValue.PendingPosition; val2 = orCreateValue.PendingRotation; flag2 = Finite(val) && Finite(val2); } else if (flag2) { val = zDO.GetVec3("L4zerShark.RaftAnchorFix.v1.position", zDO.GetPosition()); val2 = zDO.GetQuaternion("L4zerShark.RaftAnchorFix.v1.rotation", zDO.GetRotation()); flag2 = Finite(val) && Finite(val2); } else { val = default(Vector3); val2 = default(Quaternion); } int num4; Vector3 position; if (!flag2) { if (orCreateValue.CaptureCurrent) { num4 = (ship.m_nview.IsOwner() ? 1 : 0); if (num4 != 0) { position = ((ValheimBaseGameShip)ship).m_body.position; goto IL_01e9; } } else { num4 = 0; } position = zDO.GetPosition(); goto IL_01e9; } if (!flag && num2 != num) { if (ship.m_nview.IsOwner()) { int axes = num & ~num2; val = ProjectPosition(val, ((ValheimBaseGameShip)ship).m_body.position, axes); if (!Finite(val)) { ReleaseLocal(ship); return false; } zDO.Set("L4zerShark.RaftAnchorFix.v1.position", val); zDO.Set("L4zerShark.RaftAnchorFix.v2.lockedAxes", num); } else { num3 &= num2; } } goto IL_02c5; IL_0411: Vector3 position2; Vector3 val3; Quaternion rotation; if (ship.m_nview.IsOwner()) { position2 = zDO.GetPosition(); if (!((Vector3)(ref position2)).Equals(val3)) { zDO.SetPosition(val3); } rotation = zDO.GetRotation(); if (!((Quaternion)(ref rotation)).Equals(val2)) { zDO.SetRotation(val2); } zDO.Set(ZDOVars.s_velHash, ProjectPosition(zDO.GetVec3(ZDOVars.s_velHash, Vector3.zero), Vector3.zero, num3)); zDO.Set(ZDOVars.s_bodyVelHash, ProjectPosition(zDO.GetVec3(ZDOVars.s_bodyVelHash, Vector3.zero), Vector3.zero, num3)); zDO.Set(ZDOVars.s_bodyAVelHash, Vector3.zero); } return true; IL_01e9: val = position; val2 = ((num4 != 0) ? ((ValheimBaseGameShip)ship).m_body.rotation : zDO.GetRotation()); if (!Finite(val) || !Finite(val2)) { ReleaseLocal(ship); return false; } if (ship.m_nview.IsOwner()) { zDO.Set("L4zerShark.RaftAnchorFix.v1.position", val); zDO.Set("L4zerShark.RaftAnchorFix.v1.rotation", val2); zDO.Set("L4zerShark.RaftAnchorFix.v2.lockedAxes", num); zDO.Set("L4zerShark.RaftAnchorFix.v1.valid", true); } num2 = num; goto IL_02c5; IL_02c5: orCreateValue.CaptureCurrent = false; if (!orCreateValue.Held) { orCreateValue.PreviousConstraints = ((ValheimBaseGameShip)ship).m_body.constraints; orCreateValue.Held = true; } ship.vehicleAnchorState = (AnchorState)2; RigidbodyConstraints val4 = (RigidbodyConstraints)112; if ((num3 & 1) != 0) { val4 = (RigidbodyConstraints)(val4 | 0xA); } if ((num3 & 2) != 0) { val4 = (RigidbodyConstraints)(val4 | 4); } ((ValheimBaseGameShip)ship).m_body.constraints = val4; if (!((ValheimBaseGameShip)ship).m_body.isKinematic) { ((ValheimBaseGameShip)ship).m_body.linearVelocity = ProjectPosition(((ValheimBaseGameShip)ship).m_body.linearVelocity, Vector3.zero, num3); ((ValheimBaseGameShip)ship).m_body.angularVelocity = Vector3.zero; } val3 = ProjectPosition(((ValheimBaseGameShip)ship).m_body.position, val, num3); Vector3 val5 = ProjectPosition(((Component)ship).transform.position, val, num3); position2 = ((ValheimBaseGameShip)ship).m_body.position; if (!((Vector3)(ref position2)).Equals(val3)) { ((ValheimBaseGameShip)ship).m_body.position = val3; } rotation = ((ValheimBaseGameShip)ship).m_body.rotation; if (!((Quaternion)(ref rotation)).Equals(val2)) { ((ValheimBaseGameShip)ship).m_body.rotation = val2; } position2 = ((Component)ship).transform.position; if (((Vector3)(ref position2)).Equals(val5)) { rotation = ((Component)ship).transform.rotation; if (((Quaternion)(ref rotation)).Equals(val2)) { goto IL_0411; } } ((Component)ship).transform.SetPositionAndRotation(val5, val2); goto IL_0411; } private static Vector3 ProjectPosition(Vector3 current, Vector3 reference, int axes) { //IL_0007: 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_0031: 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) if ((axes & 1) != 0) { current.x = reference.x; current.z = reference.z; } if ((axes & 2) != 0) { current.y = reference.y; } return current; } private static bool Number(float x) { if (!float.IsNaN(x)) { return !float.IsInfinity(x); } return false; } private static bool Finite(Vector3 x) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (Number(x.x) && Number(x.y)) { return Number(x.z); } return false; } private static bool Finite(Quaternion x) { //IL_0000: 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_000d: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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) float num = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w; if (Number(x.x) && Number(x.y) && Number(x.z) && Number(x.w) && num > 0.99f) { return num < 1.01f; } return false; } } internal static class AnchorControls { private sealed class Request { internal bool Active; internal Player Player; internal SteeringWheelComponent Wheel; internal long PlayerId; internal long World; internal int OriginalState; internal AnchorState DesiredState; internal float Started; } internal sealed class CompletionScope { internal VehicleMovementController Ship; internal bool WasHolding; } private const string AnchorKey = "VehicleAnchorState"; private const float RequestLifetime = 5f; private static readonly FieldRef<VehicleMovementController, bool> Holding = AccessTools.FieldRefAccess<VehicleMovementController, bool>("_isHoldingAnchor"); private static readonly FieldRef<VehicleMovementController, bool> Handoff = AccessTools.FieldRefAccess<VehicleMovementController, bool>("_isControlHandoffInProgress"); private static readonly FieldInfo Doodad = AccessTools.Field(typeof(Player), "m_doodadController"); private static readonly FieldInfo AttachPoint = AccessTools.Field(typeof(Player), "m_attachPoint"); private static readonly FieldInfo Mechanisms = AccessTools.Field(typeof(VehiclePiecesController), "m_anchorMechanismComponents"); private static ConditionalWeakTable<VehicleMovementController, Request> Requests = new ConditionalWeakTable<VehicleMovementController, Request>(); internal static void Clear() { Requests = new ConditionalWeakTable<VehicleMovementController, Request>(); } private static bool LocalHelm(VehicleMovementController ship, out Player player, out SteeringWheelComponent wheel) { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Invalid comparison between Unknown and I4 player = Player.m_localPlayer; wheel = null; if (!Object.op_Implicit((Object)(object)ship) || !Object.op_Implicit((Object)(object)ship.m_nview) || !ship.m_nview.IsValid() || (Object)(object)ship.Manager == (Object)null || !ship.CanAnchor || ship.Manager.IsLandVehicle || ship.IsFlying() || !Object.op_Implicit((Object)(object)player) || ((Character)player).IsDead() || ((Character)player).IsTeleporting() || !((Character)player).IsAttached() || !(AttachPoint.GetValue(player) is Transform) || !ship.HaveControllingPlayer() || ship.m_nview.GetZDO().GetLong(ZDOVars.s_user, 0L) != player.GetPlayerID() || (Object)(object)ZNet.instance == (Object)null || ZNet.World == null || (!ZNet.instance.IsServer() && (int)ZNet.GetConnectionStatus() != 2)) { return false; } object? value = Doodad.GetValue(player); wheel = (SteeringWheelComponent)((value is SteeringWheelComponent) ? value : null); if (Object.op_Implicit((Object)(object)wheel) && wheel.ControllersInstance != null) { return (Object)(object)wheel.ControllersInstance.MovementController == (Object)(object)ship; } return false; } internal static bool BeforeKey(VehicleMovementController ship) { //IL_015e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ship) || !ship.CanAnchor || VehicleMovementController.GetAnchorKeyUp() || !VehicleMovementController.GetAnchorKeyDown() || Holding.Invoke(ship)) { return true; } if (!LocalHelm(ship, out var player, out var wheel)) { return true; } if (Requests.TryGetValue(ship, out var value) && value.Active) { value.Active = false; if (Time.realtimeSinceStartup - value.Started < 5f && (Object)(object)value.Player == (Object)(object)player && (Object)(object)value.Wheel == (Object)(object)wheel && value.PlayerId == player.GetPlayerID() && value.World == ZNet.instance.GetWorldUID() && ship.m_nview.GetZDO().GetInt("VehicleAnchorState", 0) == value.OriginalState) { value.Active = true; Holding.Invoke(ship) = true; return false; } } if (ship.m_nview.IsOwner() && !Handoff.Invoke(ship)) { return true; } Request orCreateValue = Requests.GetOrCreateValue(ship); orCreateValue.Player = player; orCreateValue.Wheel = wheel; orCreateValue.PlayerId = player.GetPlayerID(); orCreateValue.World = ZNet.instance.GetWorldUID(); orCreateValue.OriginalState = ship.m_nview.GetZDO().GetInt("VehicleAnchorState", 0); orCreateValue.DesiredState = (AnchorState)((!ship.isAnchored) ? 1 : 3); orCreateValue.Started = Time.realtimeSinceStartup; orCreateValue.Active = true; Holding.Invoke(ship) = true; return false; } internal static void Tick(VehicleMovementController ship) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Invalid comparison between I4 and Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ship) || !Requests.TryGetValue(ship, out var value) || !value.Active) { return; } if (Time.realtimeSinceStartup - value.Started >= 5f || !LocalHelm(ship, out var player, out var wheel) || (Object)(object)player != (Object)(object)value.Player || (Object)(object)wheel != (Object)(object)value.Wheel || player.GetPlayerID() != value.PlayerId || ZNet.instance.GetWorldUID() != value.World) { value.Active = false; return; } int num = ship.m_nview.GetZDO().GetInt("VehicleAnchorState", 0); if (num == (int)value.DesiredState || num != value.OriginalState) { value.Active = false; } else { if (!ship.m_nview.IsOwner() || Handoff.Invoke(ship)) { return; } value.Active = false; bool flag = Holding.Invoke(ship); try { Holding.Invoke(ship) = false; ship.SendSetAnchor(value.DesiredState); } finally { if (Object.op_Implicit((Object)(object)ship)) { Holding.Invoke(ship) = flag; } } } } internal static CompletionScope BeginCompletion(VehicleAnchorMechanismController anchor, AnchorState next) { //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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between I4 and Unknown if (!Object.op_Implicit((Object)(object)anchor) || AnchorPieceStartPatch.Starting.Contains((AnchorMechanismController)(object)anchor)) { return null; } VehicleMovementController movementController = anchor.MovementController; if (!Object.op_Implicit((Object)(object)movementController) || !Object.op_Implicit((Object)(object)movementController.m_nview) || !movementController.m_nview.IsValid() || !movementController.m_nview.IsOwner() || (Object)(object)movementController.PiecesController == (Object)null || movementController.IsFlying() || ((AnchorMechanismController)anchor).currentState != next || !(Mechanisms.GetValue(movementController.PiecesController) is IList list) || !list.Contains(anchor)) { return null; } AnchorState val; if ((int)next == 2) { val = (AnchorState)1; } else { if ((int)next != 4) { return null; } val = (AnchorState)3; } if (movementController.vehicleAnchorState != val || movementController.m_nview.GetZDO().GetInt("VehicleAnchorState", 0) != (int)val || !Holding.Invoke(movementController)) { return null; } CompletionScope result = new CompletionScope { Ship = movementController, WasHolding = Holding.Invoke(movementController) }; Holding.Invoke(movementController) = false; return result; } internal static void EndCompletion(CompletionScope scope) { if (scope != null && Object.op_Implicit((Object)(object)scope.Ship)) { Holding.Invoke(scope.Ship) = scope.WasHolding; } } } [HarmonyPatch(typeof(VehicleMovementController), "OnAnchorKeyPress")] internal static class AnchorHandoffInputPatch { private static bool Prefix(VehicleMovementController __instance) { return AnchorControls.BeforeKey(__instance); } } [HarmonyPatch(typeof(VehicleMovementController), "GuardedFixedUpdate")] internal static class AnchorHandoffDispatchPatch { private static void Postfix(VehicleMovementController __instance) { AnchorControls.Tick(__instance); } } [HarmonyPatch(typeof(VehicleAnchorMechanismController), "OnAnchorStateChange")] internal static class AnchorCompletionDebouncePatch { private static void Prefix(VehicleAnchorMechanismController __instance, AnchorState newState, out AnchorControls.CompletionScope __state) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) __state = AnchorControls.BeginCompletion(__instance, newState); } private static Exception Finalizer(Exception __exception, AnchorControls.CompletionScope __state) { AnchorControls.EndCompletion(__state); return __exception; } } internal static class AnchorGeometry { private sealed class Initialization { } private static readonly ConditionalWeakTable<AnchorMechanismController, Initialization> Initialized = new ConditionalWeakTable<AnchorMechanismController, Initialization>(); private static readonly FieldRef<AnchorMechanismController, Rigidbody> Body = AccessTools.FieldRefAccess<AnchorMechanismController, Rigidbody>("anchorRb"); internal static void AfterAwake(AnchorMechanismController anchor) { if (anchor is VehicleAnchorMechanismController && Object.op_Implicit((Object)(object)Body.Invoke(anchor)) && Object.op_Implicit((Object)(object)anchor.anchorTransform)) { Initialized.GetOrCreateValue(anchor); } } internal static bool Ready(AnchorMechanismController anchor) { if (Object.op_Implicit((Object)(object)anchor) && Initialized.TryGetValue(anchor, out var _) && Object.op_Implicit((Object)(object)Body.Invoke(anchor))) { return Object.op_Implicit((Object)(object)anchor.anchorTransform); } return false; } internal static void AfterPlacement(VehicleAnchorMechanismController anchor) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (Ready((AnchorMechanismController)(object)anchor) && (int)((AnchorMechanismController)anchor).currentState == 2) { AlignBody((AnchorMechanismController)(object)anchor); } } internal static void RestoreAnchoredVisual(AnchorMechanismController component) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 VehicleAnchorMechanismController val = (VehicleAnchorMechanismController)(object)((component is VehicleAnchorMechanismController) ? component : null); if (Ready((AnchorMechanismController)(object)val) && (int)((AnchorMechanismController)val).currentState == 2 && Object.op_Implicit((Object)(object)val.MovementController) && !val.IsLandVehicle() && !val.MovementController.IsFlying() && AnchorLock.IsAnchored(val.MovementController)) { val.UpdateAnchorPositionIfNotNearGround(); } } private static void AlignBody(AnchorMechanismController anchor) { //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) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0033: Unknown result type (might be due to invalid IL or missing references) Rigidbody val = Body.Invoke(anchor); Vector3 position = anchor.anchorTransform.position; if (Finite(position)) { Vector3 position2 = val.position; if (!((Vector3)(ref position2)).Equals(position)) { val.position = position; } } } internal static bool BeforeDelayedGuard(AnchorMechanismController anchor) { //IL_001d: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!(anchor is VehicleAnchorMechanismController)) { return true; } if (!((Behaviour)anchor).isActiveAndEnabled || !Ready(anchor)) { return false; } if ((int)anchor.currentState != 0 && (int)anchor.currentState != 4) { return false; } Vector3 anchorStartLocalPosition = anchor.GetAnchorStartLocalPosition(); if (!Finite(anchorStartLocalPosition)) { return false; } anchor.anchorTransform.localPosition = anchorStartLocalPosition; AlignBody(anchor); return false; } private static bool Finite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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 (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z)) { return !float.IsInfinity(value.z); } return false; } } [HarmonyPatch(typeof(AnchorMechanismController), "Awake")] internal static class AnchorGeometryAwakePatch { private static void Postfix(AnchorMechanismController __instance) { AnchorGeometry.AfterAwake(__instance); } } [HarmonyPatch(typeof(VehicleAnchorMechanismController), "UpdateAnchorPositionIfNotNearGround")] internal static class AnchorGeometryEarlyPlacementPatch { private static bool Prefix(VehicleAnchorMechanismController __instance, out bool __state) { __state = AnchorGeometry.Ready((AnchorMechanismController)(object)__instance); return __state; } private static void Postfix(VehicleAnchorMechanismController __instance, bool __state) { if (__state) { AnchorGeometry.AfterPlacement(__instance); } } } [HarmonyPatch(typeof(AnchorMechanismController), "Start")] internal static class AnchorGeometryStartPatch { [HarmonyPriority(0)] private static void Postfix(AnchorMechanismController __instance) { AnchorGeometry.RestoreAnchoredVisual(__instance); } } [HarmonyPatch(typeof(VehiclePiecesController), "InitAnchorComponent")] internal static class AnchorGeometryParentPatch { private static void Postfix(VehicleAnchorMechanismController anchorComponent) { AnchorGeometry.RestoreAnchoredVisual((AnchorMechanismController)(object)anchorComponent); } } [HarmonyPatch(typeof(AnchorMechanismController), "GuardAgainstAnchorSyncIssue")] internal static class AnchorGeometryDelayedGuardPatch { private static bool Prefix(AnchorMechanismController __instance) { return AnchorGeometry.BeforeDelayedGuard(__instance); } } }