using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] namespace Obelisk.MoveBuildPieces; [BepInPlugin("obelisk.valheim.movebuildpieces", "MoveBuildPieces", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class MoveBuildPiecesPlugin : BaseUnityPlugin { public const string PluginGuid = "obelisk.valheim.movebuildpieces"; public const string PluginName = "MoveBuildPieces"; public const string PluginVersion = "1.1.1"; private static ConfigEntry _enabled; private static ConfigEntry _moveMode; private static ConfigEntry _buildModeMoveHotkey; private static ConfigEntry _worldModeMoveHotkey; private static ConfigEntry _mixedModeMoveHotkey; private static ConfigEntry _requireKnownPiece; private static ConfigEntry _blockTerrainModifiers; private static ConfigEntry _blockDynamicObjects; private static ConfigEntry _moveLockTimeoutSeconds; private Harmony _harmony; internal static bool IsEnabled => _enabled.Value; internal static MoveActivationMode ActiveMode => _moveMode.Value; internal static KeyboardShortcut BuildModeMoveHotkey => _buildModeMoveHotkey.Value; internal static KeyboardShortcut WorldModeMoveHotkey => _worldModeMoveHotkey.Value; internal static KeyboardShortcut MixedModeMoveHotkey => _mixedModeMoveHotkey.Value; internal static bool RequireKnownPiece => MoveController.ResolveRequireKnownPiece(_requireKnownPiece.Value); internal static bool BlockTerrainModifiers => MoveController.ResolveBlockTerrainModifiers(_blockTerrainModifiers.Value); internal static bool BlockDynamicObjects => MoveController.ResolveBlockDynamicObjects(_blockDynamicObjects.Value); internal static float MoveLockTimeoutSeconds { get { float value = _moveLockTimeoutSeconds.Value; return MoveController.ResolveMoveLockTimeout((float.IsNaN(value) || float.IsInfinity(value)) ? 45f : Mathf.Clamp(value, 5f, 300f)); } } private void Awake() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_015a: Expected O, but got Unknown _enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable moving already built player-built pieces."); _moveMode = ((BaseUnityPlugin)this).Config.Bind("General", "Move mode", MoveActivationMode.Mixed, "Choose whether moving works in build mode, world mode, or both through Mixed mode."); _buildModeMoveHotkey = ((BaseUnityPlugin)this).Config.Bind("Hotkeys", "Build mode move hotkey", new KeyboardShortcut((KeyCode)117, Array.Empty()), "Press while hovering a buildable player-built piece in build mode to start or cancel moving it."); _worldModeMoveHotkey = ((BaseUnityPlugin)this).Config.Bind("Hotkeys", "World mode move hotkey", new KeyboardShortcut((KeyCode)117, Array.Empty()), "Press while hovering a buildable player-built piece outside build mode to start or cancel moving it."); _mixedModeMoveHotkey = ((BaseUnityPlugin)this).Config.Bind("Hotkeys", "Mixed mode move hotkey", new KeyboardShortcut((KeyCode)117, Array.Empty()), "Press in or outside build mode to start or cancel moving a piece while Move mode is Mixed."); _requireKnownPiece = ((BaseUnityPlugin)this).Config.Bind("Safety", "Require known piece", false, "Only allow moving pieces the player has learned. Disable to move player-built pieces before learning their recipes."); _blockTerrainModifiers = ((BaseUnityPlugin)this).Config.Bind("Safety", "Block terrain modifiers", true, "Do not move pieces that contain TerrainModifier or TerrainOp components."); _blockDynamicObjects = ((BaseUnityPlugin)this).Config.Bind("Safety", "Block dynamic objects", true, "Do not move ships, carts, characters, or pieces with non-kinematic rigidbodies."); _moveLockTimeoutSeconds = ((BaseUnityPlugin)this).Config.Bind("Safety", "Move lock timeout seconds", 45f, "How long a move lock can survive without being released, used as a multiplayer disconnect safety net."); MoveController.Initialize(); _harmony = new Harmony("obelisk.valheim.movebuildpieces"); _harmony.PatchAll(); AAABuildMenuCompatibility.Apply(_harmony); } private void OnDestroy() { MoveController.Reset(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal enum MoveActivationMode { BuildMenu, World, Mixed } [HarmonyPatch(typeof(Player), "Update")] internal static class PlayerUpdatePatch { private static void Postfix(Player __instance) { MoveController.Update(__instance); } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] internal static class PlayerUpdatePlacementPatch { private static bool Prefix(Player __instance) { return !MoveController.ShouldSkipVanillaUpdatePlacement(__instance); } } [HarmonyPatch(typeof(Player), "LateUpdate")] internal static class PlayerLateUpdatePatch { private static void Postfix(Player __instance) { MoveController.UpdateVisuals(__instance); } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] internal static class PlayerUpdatePlacementGhostPatch { private static bool Prefix(Player __instance) { return MoveController.ShouldRunPlacementGhostUpdate(__instance); } private static IEnumerable Transpiler(IEnumerable instructions) { MethodInfo overlapSphereWithMask = AccessTools.Method(typeof(Physics), "OverlapSphere", new Type[3] { typeof(Vector3), typeof(float), typeof(int) }, (Type[])null); MethodInfo filteredOverlapSphereWithMask = AccessTools.Method(typeof(PlacementPhysicsBridge), "OverlapSphere", new Type[3] { typeof(Vector3), typeof(float), typeof(int) }, (Type[])null); MethodInfo overlapSphere = AccessTools.Method(typeof(Physics), "OverlapSphere", new Type[2] { typeof(Vector3), typeof(float) }, (Type[])null); MethodInfo filteredOverlapSphere = AccessTools.Method(typeof(PlacementPhysicsBridge), "OverlapSphere", new Type[2] { typeof(Vector3), typeof(float) }, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Call && object.Equals(instruction.operand, overlapSphereWithMask)) { instruction.operand = filteredOverlapSphereWithMask; } else if (instruction.opcode == OpCodes.Call && object.Equals(instruction.operand, overlapSphere)) { instruction.operand = filteredOverlapSphere; } yield return instruction; } } } [HarmonyPatch(typeof(Player), "TestGhostClipping")] internal static class PlayerTestGhostClippingPatch { private static bool Prefix(Player __instance, GameObject ghost, float maxPenetration, ref bool __result) { return !MoveController.TryTestGhostClippingIgnoringMovedPiece(__instance, ghost, maxPenetration, out __result); } } [HarmonyPatch(typeof(Player), "IsOverlappingOtherPiece")] internal static class PlayerPieceOverlapPatch { private static bool Prefix(Player __instance, Vector3 p, Quaternion rotation, string pieceName, List pieces, bool allowRotatedOverlap, ref bool __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return !MoveController.TryEvaluatePieceOverlapIgnoringMovedPiece(__instance, p, rotation, pieceName, pieces, allowRotatedOverlap, out __result); } } [HarmonyPatch(typeof(StationExtension), "OtherExtensionInRange")] internal static class StationExtensionRangePatch { private static bool Prefix(StationExtension __instance, float radius, ref bool __result) { return !MoveController.TryEvaluateExtensionRangeIgnoringMovedPiece(__instance, radius, out __result); } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class PlayerSetControlsPatch { private static void Prefix(Player __instance, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold) { MoveController.SuppressAttackControls(__instance, ref attack, ref attackHold, ref secondaryAttack, ref secondaryAttackHold); } } [HarmonyPatch(typeof(Player), "TeleportTo")] internal static class PlayerTeleportToPatch { private static void Prefix(Player __instance) { MoveController.CancelForTeleport(__instance); } } [HarmonyPatch(typeof(Player), "OnDeath")] internal static class PlayerOnDeathPatch { private static void Prefix(Player __instance) { MoveController.CancelForDeath(__instance); } } [HarmonyPatch(typeof(Player), "OnDestroy")] internal static class PlayerOnDestroyPatch { private static void Prefix(Player __instance) { MoveController.CancelForPlayerDestroyed(__instance); } } [HarmonyPatch(typeof(Door), "Interact")] internal static class DoorInteractPatch { private static void Postfix(Humanoid character, bool hold, bool __result) { if (__result && !hold) { Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { MoveController.NotifyDoorInteracted(val); } } } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] internal static class PlayerHaveRequirementsPatch { private static bool Prefix(Player __instance, Piece piece, RequirementMode mode, ref bool __result) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) if (MoveController.ShouldBypassRequirements(__instance, piece, mode)) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(PieceTable), "UpdateAvailable", new Type[] { typeof(HashSet), typeof(Player), typeof(bool), typeof(bool) })] internal static class PieceTableUpdateAvailablePatch { private static bool Prefix(PieceTable __instance) { return !MoveController.IsTemporaryPieceTable(__instance); } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] internal static class PlayerTryPlacePiecePatch { private static bool Prefix(Player __instance, Piece piece, ref bool __result) { if (!MoveController.ShouldHandlePlacement(__instance)) { return true; } __result = false; MoveController.TryFinishMove(__instance); return false; } } [HarmonyPatch(typeof(Player), "RemovePiece")] internal static class PlayerRemovePiecePatch { private static bool Prefix(Player __instance, ref bool __result) { if (!MoveController.ShouldBlockBuildAction(__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Player), "CopyPiece")] internal static class PlayerCopyPiecePatch { private static bool Prefix(Player __instance, ref bool __result) { if (!MoveController.ShouldBlockBuildAction(__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(ZRoutedRpc), "RPC_RoutedRPC")] internal static class RoutedRpcSenderValidationPatch { private static bool Prefix(ZRoutedRpc __instance, ZRpc rpc, ZPackage pkg) { return MoveController.ValidateRoutedRpcSender(__instance, rpc, pkg); } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class ZNetAwakePatch { private static void Postfix(ZNet __instance) { MoveController.OnNetworkStarted(__instance); } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] internal static class ZNetNewConnectionPatch { private static void Postfix(ZNetPeer peer) { MoveController.RegisterNetworkPeer(peer); } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] internal static class ZNetDestroyPatch { private static void Prefix(ZNet __instance) { MoveController.OnNetworkStopped(__instance); } } [HarmonyPatch(typeof(ZNet), "Disconnect")] internal static class ZNetDisconnectPatch { private static void Prefix(ZNetPeer peer) { MoveController.UnregisterNetworkPeer(peer); } } [HarmonyPatch(typeof(ZNetScene), "Shutdown")] internal static class ZNetSceneShutdownPatch { private static void Prefix() { MoveController.PrepareForNetworkShutdown(); } } internal sealed class MovePieceTableMarker : MonoBehaviour { } internal static class AAABuildMenuCompatibility { internal const string PluginGuid = "Azumatt.AAABuildMenu"; private const string EnhancedBuildMenuTypeName = "AAABuildMenu.EnhancedBuildMenu"; private static PropertyInfo _needsRefreshProperty; internal static void Apply(Harmony harmony) { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown _needsRefreshProperty = null; if (harmony == null || !Chainloader.PluginInfos.ContainsKey("Azumatt.AAABuildMenu")) { return; } Type type = AccessTools.TypeByName("AAABuildMenu.EnhancedBuildMenu"); if (type == null) { Debug.LogWarning((object)"[MoveBuildPieces] AAABuildMenu is installed, but its enhanced menu type was not found; compatibility mode was not enabled."); return; } MethodInfo methodInfo = AccessTools.Method(type, "ApplyFilter", new Type[3] { typeof(Player), typeof(PieceTable), typeof(bool) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "CaptureMasterAndApply", new Type[2] { typeof(Player), typeof(PieceTable) }, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(AAABuildMenuCompatibility), "AllowPieceTableMutation", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo3 == null) { Debug.LogWarning((object)"[MoveBuildPieces] AAABuildMenu is installed, but its filter API was not found; compatibility mode was not enabled."); return; } try { _needsRefreshProperty = AccessTools.Property(type, "NeedsRefresh"); HarmonyMethod val = new HarmonyMethod(methodInfo3); harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } Debug.Log((object)"[MoveBuildPieces] AAABuildMenu compatibility enabled."); } catch (Exception ex) { Debug.LogWarning((object)("[MoveBuildPieces] AAABuildMenu compatibility failed: " + ex.GetBaseException().Message)); } } private static bool AllowPieceTableMutation(object[] __args) { PieceTable table = null; if (__args != null) { foreach (object obj in __args) { PieceTable val = (PieceTable)((obj is PieceTable) ? obj : null); if (val != null) { table = val; break; } } } if (!MoveController.IsTemporaryPieceTable(table)) { return true; } try { PropertyInfo needsRefreshProperty = _needsRefreshProperty; if ((object)needsRefreshProperty != null && needsRefreshProperty.CanWrite) { _needsRefreshProperty.SetValue(null, false, null); } } catch { } return false; } } public static class PlacementPhysicsBridge { public static Collider[] OverlapSphere(Vector3 position, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return MoveController.FilterPlacementOverlap(Physics.OverlapSphere(position, radius)); } public static Collider[] OverlapSphere(Vector3 position, float radius, int layerMask) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return MoveController.FilterPlacementOverlap(Physics.OverlapSphere(position, radius, layerMask)); } } internal static class MoveController { private enum MoveContext { Build, World } private sealed class MoveState { public Player Player; public Piece Piece; public ZNetView NetView; public string PrefabName; public MoveContext Context; public MoveActivationMode ActivationMode; public GameObject RelocateTableObject; public PieceTable OriginalBuildPieces; public PieceTable ActivePieceTable; public Vector3 OriginalPosition; public List OriginalBuildAreas; public long LockPlayerId; public long LockPeerId; public long LockToken; public long LockOwnerPeerId; public long LockRequestOwnerPeerId; public float LastLockRefreshTime; public bool WaitingForMoveResult; public long MoveRequestOwnerPeerId; public float MoveRequestStartedAt; public float FirstMoveRequestStartedAt; public int MoveRequestAttempts; public float LastServerVerifyRequestAt; public float MoveFailureReceivedAt; public string MoveFailureMessage; public Vector3 PendingTargetPosition; public Quaternion PendingTargetRotation; public bool UpdateBedSpawnPoint; public Vector3 BedSpawnLocalPoint; public Vector3 BedOriginalProfileSpawnPoint; public GameObject HighlightedGhost; public bool GhostHighlighted; public bool OriginGeometryCached; public Vector3 OriginGroundPoint; public Vector3 OriginLinkPoint; public float OriginRingRadius; public bool VisualGeometryCached; public Vector3 LastGhostPosition; public Quaternion LastGhostRotation; public bool LastGhostVisible; } private sealed class PendingMoveRequest { public Player Player; public Piece Piece; public ZNetView NetView; public MoveContext Context; public MoveActivationMode ActivationMode; public long PlayerId; public long LockToken; public long ExpectedOwnerPeerId; public float StartedAt; public float LastRequestAt; } private sealed class CancelledLockRequest { public ZDOID ZdoId; public long PlayerId; public long LockToken; public long ExpectedOwnerPeerId; public float CancelledAt; } private sealed class OwnerMoveSnapshot { public Vector3 TransformPosition; public Quaternion TransformRotation; public Vector3 ZdoPosition; public Quaternion ZdoRotation; public long LastMoveToken; public long LastMovePeer; public long LastMovePlayer; public long LockOwner; public long LockPeer; public long LockToken; public long LockUntil; public string LockName; public List RigidbodyStates; public List ComponentFields; } private sealed class RigidbodySnapshot { public Rigidbody Body; public Vector3 Position; public Quaternion Rotation; public Vector3 LinearVelocity; public Vector3 AngularVelocity; } private sealed class FieldValueSnapshot { public object Target; public FieldInfo Field; public object Value; } private sealed class RaycastHitDistanceComparer : IComparer { public static readonly RaycastHitDistanceComparer Instance = new RaycastHitDistanceComparer(); public int Compare(RaycastHit x, RaycastHit y) { return ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance); } } private static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost"); private static readonly FieldInfo BuildPiecesField = AccessTools.Field(typeof(Player), "m_buildPieces"); private static readonly FieldInfo PlacementStatusField = AccessTools.Field(typeof(Player), "m_placementStatus"); private static readonly FieldInfo EyeField = AccessTools.Field(typeof(Character), "m_eye"); private static readonly FieldInfo MaxPlaceDistanceField = AccessTools.Field(typeof(Player), "m_maxPlaceDistance"); private static readonly FieldInfo MaxInteractDistanceField = AccessTools.Field(typeof(Player), "m_maxInteractDistance"); private static readonly FieldInfo RemoveRayMaskField = AccessTools.Field(typeof(Player), "m_removeRayMask"); private static readonly FieldInfo PlaceRayMaskField = AccessTools.Field(typeof(Player), "m_placeRayMask"); private static readonly FieldInfo InteractMaskField = AccessTools.Field(typeof(Player), "m_interactMask"); private static readonly FieldInfo PlaceRotationField = AccessTools.Field(typeof(Player), "m_placeRotation"); private static readonly FieldInfo ScrollCurrentAmountField = AccessTools.Field(typeof(Player), "m_scrollCurrAmount"); private static readonly FieldInfo RotatePieceTimerField = AccessTools.Field(typeof(Player), "m_rotatePieceTimer"); private static readonly FieldInfo PieceTableAvailablePiecesField = AccessTools.Field(typeof(PieceTable), "m_availablePieces"); private static readonly FieldInfo PieceTableSelectedCategoryField = AccessTools.Field(typeof(PieceTable), "m_selectedCategory"); private static readonly FieldInfo AttackField = AccessTools.Field(typeof(Character), "m_attack"); private static readonly FieldInfo AttackHoldField = AccessTools.Field(typeof(Character), "m_attackHold"); private static readonly FieldInfo SecondaryAttackField = AccessTools.Field(typeof(Character), "m_secondaryAttack"); private static readonly FieldInfo SecondaryAttackHoldField = AccessTools.Field(typeof(Character), "m_secondaryAttackHold"); private static readonly FieldInfo QueuedAttackTimerField = AccessTools.Field(typeof(Player), "m_queuedAttackTimer"); private static readonly FieldInfo QueuedSecondAttackTimerField = AccessTools.Field(typeof(Player), "m_queuedSecondAttackTimer"); private static readonly FieldInfo AttackDrawTimeField = AccessTools.Field(typeof(Humanoid), "m_attackDrawTime"); private static readonly FieldInfo WearNTearCollidersField = AccessTools.Field(typeof(WearNTear), "m_colliders"); private static readonly FieldInfo WearNTearBoundsField = AccessTools.Field(typeof(WearNTear), "m_bounds"); private static readonly FieldInfo WearNTearClearCachedSupportField = AccessTools.Field(typeof(WearNTear), "m_clearCachedSupport"); private static readonly FieldInfo WearNTearRoofField = AccessTools.Field(typeof(WearNTear), "m_roof"); private static readonly FieldInfo WearNTearAshRoofField = AccessTools.Field(typeof(WearNTear), "m_ashroof"); private static readonly FieldInfo WearNTearBiomeField = AccessTools.Field(typeof(WearNTear), "m_biome"); private static readonly FieldInfo WearNTearHeightmapField = AccessTools.Field(typeof(WearNTear), "m_heightmap"); private static readonly FieldInfo WearNTearConnectedHeightmapField = AccessTools.Field(typeof(WearNTear), "m_connectedHeightMap"); private static readonly FieldInfo WearNTearGroundDistanceField = AccessTools.Field(typeof(WearNTear), "m_groundDist"); private static readonly FieldInfo WearNTearInAshlandsField = AccessTools.Field(typeof(WearNTear), "m_inAshlands"); private static readonly FieldInfo WearNTearLavaValueField = AccessTools.Field(typeof(WearNTear), "m_lavaValue"); private static readonly FieldInfo WearNTearLavaTimerField = AccessTools.Field(typeof(WearNTear), "m_lavaTimer"); private static readonly FieldInfo WearNTearAshTimerField = AccessTools.Field(typeof(WearNTear), "m_ashTimer"); private static readonly FieldInfo WearNTearRainTimerField = AccessTools.Field(typeof(WearNTear), "m_rainTimer"); private static readonly FieldInfo WearNTearUpdateCoverTimerField = AccessTools.Field(typeof(WearNTear), "m_updateCoverTimer"); private static readonly FieldInfo WearNTearHaveRoofField = AccessTools.Field(typeof(WearNTear), "m_haveRoof"); private static readonly FieldInfo WearNTearHaveAshRoofField = AccessTools.Field(typeof(WearNTear), "m_haveAshRoof"); private static readonly FieldInfo WearNTearShieldChangeIdField = AccessTools.Field(typeof(WearNTear), "m_shieldChangeID"); private static readonly FieldInfo WearNTearPreviousWaterVolumeField = AccessTools.Field(typeof(WearNTear), "m_previousWaterVolume"); private static readonly FieldInfo SapCollectorRootField = AccessTools.Field(typeof(SapCollector), "m_root"); private static readonly FieldInfo SapCollectorConnectedObjectField = AccessTools.Field(typeof(SapCollector), "m_connectedObject"); private static readonly FieldInfo ShieldGeneratorRadiusSentField = AccessTools.Field(typeof(ShieldGenerator), "m_radiusSent"); private static readonly FieldInfo FireplaceBiomeField = AccessTools.Field(typeof(Fireplace), "m_biome"); private static readonly FieldInfo CinderSpawnerBiomeField = AccessTools.Field(typeof(CinderSpawner), "m_biome"); private static readonly FieldInfo StaticRotationValueField = AccessTools.Field(typeof(StaticRotation), "m_rotation"); private static readonly PropertyInfo RigidbodyLinearVelocityProperty = AccessTools.Property(typeof(Rigidbody), "linearVelocity") ?? AccessTools.Property(typeof(Rigidbody), "velocity"); private static readonly EventInfo HeightmapSupportCacheEvent = typeof(Heightmap).GetEvent("m_clearConnectedWearNTearCache", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PrivateAreasField = AccessTools.Field(typeof(PrivateArea), "m_allAreas"); private static readonly FieldInfo PrivateAreaConnectionUpdateTimeField = AccessTools.Field(typeof(PrivateArea), "m_connectionUpdateTime"); private static readonly FieldInfo StationExtensionsField = AccessTools.Field(typeof(StationExtension), "m_allExtensions"); private static readonly FieldInfo CraftingStationsField = AccessTools.Field(typeof(CraftingStation), "m_allStations"); private static readonly FieldInfo CraftingStationExtensionTimerField = AccessTools.Field(typeof(CraftingStation), "m_updateExtensionTimer"); private static readonly FieldInfo EffectAreaColliderField = AccessTools.Field(typeof(EffectArea), "m_collider"); private static readonly FieldInfo EffectAreaNoMonsterAreaField = AccessTools.Field(typeof(EffectArea), "noMonsterArea"); private static readonly FieldInfo EffectAreaNoMonsterCloseAreaField = AccessTools.Field(typeof(EffectArea), "noMonsterCloseToArea"); private static readonly FieldInfo EffectAreaBurnCloseAreaField = AccessTools.Field(typeof(EffectArea), "burnCloseToArea"); private static readonly FieldInfo EffectAreaNoMonsterAreasField = AccessTools.Field(typeof(EffectArea), "s_noMonsterAreas"); private static readonly FieldInfo EffectAreaNoMonsterCloseAreasField = AccessTools.Field(typeof(EffectArea), "s_noMonsterCloseToAreas"); private static readonly FieldInfo EffectAreaBurningAreasField = AccessTools.Field(typeof(EffectArea), "s_BurningAreas"); private static readonly FieldInfo RoutedRpcFunctionsField = AccessTools.Field(typeof(ZRoutedRpc), "m_functions"); private static readonly MethodInfo SetupPlacementGhostMethod = AccessTools.Method(typeof(Player), "SetupPlacementGhost", (Type[])null, (Type[])null); private static readonly MethodInfo UpdatePlacementGhostMethod = AccessTools.Method(typeof(Player), "UpdatePlacementGhost", (Type[])null, (Type[])null); private static readonly MethodInfo UpdateAvailablePiecesListMethod = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null); private static readonly MethodInfo ClearLocalSupportCacheMethod = AccessTools.Method(typeof(WearNTear), "ClearCachedSupport", (Type[])null, (Type[])null); private static readonly MethodInfo UpdateSupportMethod = AccessTools.Method(typeof(WearNTear), "UpdateSupport", (Type[])null, (Type[])null); private static readonly MethodInfo HaveSupportMethod = AccessTools.Method(typeof(WearNTear), "HaveSupport", (Type[])null, (Type[])null); private static readonly MethodInfo PrivateAreaIsEnabledMethod = AccessTools.Method(typeof(PrivateArea), "IsEnabled", (Type[])null, (Type[])null); private static readonly MethodInfo PrivateAreaIsPermittedMethod = AccessTools.Method(typeof(PrivateArea), "IsPermitted", (Type[])null, (Type[])null); private static readonly FieldInfo[] WearNTearRelocationFields = new FieldInfo[19] { WearNTearCollidersField, WearNTearBoundsField, WearNTearClearCachedSupportField, WearNTearRoofField, WearNTearAshRoofField, WearNTearBiomeField, WearNTearHeightmapField, WearNTearConnectedHeightmapField, WearNTearGroundDistanceField, WearNTearInAshlandsField, WearNTearLavaValueField, WearNTearLavaTimerField, WearNTearAshTimerField, WearNTearRainTimerField, WearNTearUpdateCoverTimerField, WearNTearHaveRoofField, WearNTearHaveAshRoofField, WearNTearShieldChangeIdField, WearNTearPreviousWaterVolumeField }; private static readonly Color GhostColor = new Color(0.22f, 0.66f, 1f, 0.75f); private static readonly Color GhostEmissionColor = new Color(0.05f, 0.42f, 0.9f, 0.9f); private static readonly Color LinkColor = new Color(1f, 0.9f, 0.2f, 0.92f); private static readonly Color RingColor = new Color(1f, 0.95f, 0.35f, 0.9f); private const int RingSegments = 28; private const float LinkWidth = 0.075f; private const float DashLength = 0.35f; private const float MinRingRadius = 0.6f; private const float MaxRingRadius = 8f; private const float RingPadding = 0.25f; private const float TopLinkPadding = 0.15f; private const float DefaultLinkHeight = 1.25f; private const float MinUsefulBoundsSize = 0.05f; private static readonly HashSet SupportPieces = new HashSet(); private static readonly Dictionary CancelledLockRequests = new Dictionary(); private static readonly List ExpiredRequestTokens = new List(); private static readonly RaycastHit[] FloorHits = (RaycastHit[])(object)new RaycastHit[16]; private static readonly RaycastHit[] DoorInteractHits = (RaycastHit[])(object)new RaycastHit[32]; private static readonly List BoundsColliderBuffer = new List(); private static readonly List BoundsRendererBuffer = new List(); private static readonly List BoundsMeshFilterBuffer = new List(); private static readonly List BoundsSnapPointBuffer = new List(); private static Collider[] _supportColliderBuffer = (Collider[])(object)new Collider[128]; private const string TemporaryPieceTableName = "MoveBuildPieces_TemporaryPieceTable"; private const string MoveRpcName = "MoveBuildPiecesV4_Move"; private const string MoveResultRpcName = "MoveBuildPiecesV4_MoveResult"; private const string ApplyVisualRpcName = "MoveBuildPiecesV4_ApplyVisual"; private const string LockRequestRpcName = "MoveBuildPiecesV4_LockRequest"; private const string LockResponseRpcName = "MoveBuildPiecesV4_LockResponse"; private const string LockReleaseRpcName = "MoveBuildPiecesV4_LockRelease"; private const string ServerProbeRpcName = "MoveBuildPiecesV4_ServerProbe"; private const string ServerProbeResultRpcName = "MoveBuildPiecesV4_ServerProbeResult"; private const string ServerVerifyMoveRpcName = "MoveBuildPiecesV4_ServerVerifyMove"; private const string ServerVerifyMoveResultRpcName = "MoveBuildPiecesV4_ServerVerifyMoveResult"; private const int MoveProtocolVersion = 4; private static readonly int LockOwnerHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LockOwner"); private static readonly int LockPeerHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LockPeer"); private static readonly int LockTokenHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LockToken"); private static readonly int LockUntilHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LockUntil"); private static readonly int LockNameHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LockName"); private static readonly int LastMoveTokenHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LastMoveToken"); private static readonly int LastMovePeerHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LastMovePeer"); private static readonly int LastMovePlayerHash = StringExtensionMethods.GetStableHashCode("MoveBuildPieces.LastMovePlayer"); private const float PendingRequestTimeoutSeconds = 5f; private const float MoveResultTimeoutSeconds = 8f; private const float LockRefreshIntervalSeconds = 2f; private const float ServerVerificationIntervalSeconds = 0.5f; private const float ServerCapabilityLeaseSeconds = 12f; private const float MoveFailureGraceSeconds = 2.5f; private const int MaxMoveRequestAttempts = 3; private const int MaxSupportColliderBufferSize = 2048; private static MoveState _state; private static PendingMoveRequest _pendingRequest; private static GameObject _lineObject; private static LineRenderer _dashLine; private static LineRenderer _originRing; private static LineRenderer _ghostRing; private static Texture2D _dashTexture; private static int _floorMask; private static int _supportLayerMask; private static int _lastDoorInteractFrame = -1; private static Player _suppressAttackPlayer; private static float _suppressAttackUntilTime; private static float _nextCancelledRequestCleanupAt; private static long _requestTokenCounter; private static readonly List RegisteredPeerRpcs = new List(); private static readonly Dictionary PeerLastVerifyTimes = new Dictionary(); private static ZRoutedRpc _registeredRoutedRpc; private static bool _routedHandlersActive; private static ZRpc _serverRpc; private static long _serverProbeNonce; private static float _lastServerProbeAt; private static float _lastServerPolicyAckAt; private static bool _serverCapabilityConfirmed; private static bool _serverPolicyEnabled; private static bool _serverPolicyRequireKnownPiece; private static bool _serverPolicyBlockTerrainModifiers; private static bool _serverPolicyBlockDynamicObjects; private static float _serverPolicyMoveLockTimeoutSeconds = 45f; private static bool _runningFinalPlacementValidation; private static Player _placementValidationPlayer; private static Player _skipPlacementGhostPlayer; private static int _skipPlacementGhostFrame = -1; internal static bool NetworkMovesEnabled { get { if ((Object)(object)ZNet.instance != (Object)null) { if (!ZNet.instance.IsServer()) { if (IsServerCapabilityCurrent()) { return _serverPolicyEnabled; } return false; } return MoveBuildPiecesPlugin.IsEnabled; } return false; } } public static void Initialize() { Reset(); if ((Object)(object)ZNet.instance != (Object)null) { OnNetworkStarted(ZNet.instance); } } public static void Reset() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) ClearNetworkSession(); if (_state != null) { Cancel(_state.Player, showMessage: false); } if (_pendingRequest != null) { ReleaseMoveLock(_pendingRequest.NetView, _pendingRequest.PlayerId, _pendingRequest.LockToken, _pendingRequest.ExpectedOwnerPeerId); _pendingRequest = null; } foreach (CancelledLockRequest value in CancelledLockRequests.Values) { ReleaseMoveLock(ResolvePieceNetView(value.ZdoId), value.PlayerId, value.LockToken, value.ExpectedOwnerPeerId); } CancelledLockRequests.Clear(); ExpiredRequestTokens.Clear(); _suppressAttackPlayer = null; _suppressAttackUntilTime = 0f; _nextCancelledRequestCleanupAt = 0f; _lastDoorInteractFrame = -1; _floorMask = 0; _supportLayerMask = 0; _runningFinalPlacementValidation = false; _placementValidationPlayer = null; _skipPlacementGhostPlayer = null; _skipPlacementGhostFrame = -1; DestroyLine(); } public static void OnNetworkStarted(ZNet network) { ClearNetworkSession(); if (!((Object)(object)network == (Object)null)) { RegisterGlobalRoutedRpcs(); _serverCapabilityConfirmed = network.IsServer(); _serverProbeNonce = CreateRequestToken(); List peers = network.GetPeers(); for (int i = 0; i < peers.Count; i++) { RegisterNetworkPeer(peers[i]); } } } public static void OnNetworkStopped(ZNet network) { if ((Object)(object)network == (Object)null || (Object)(object)network == (Object)(object)ZNet.instance) { ClearNetworkSession(); } } public static void PrepareForNetworkShutdown() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (_state != null) { Cancel(_state.Player, showMessage: false); } if (_pendingRequest != null) { CancelPendingRequest(_pendingRequest.Player, showMessage: false, null); } foreach (CancelledLockRequest value in CancelledLockRequests.Values) { try { ReleaseMoveLock(ResolvePieceNetView(value.ZdoId), value.PlayerId, value.LockToken, value.ExpectedOwnerPeerId); } catch { } } } public static void RegisterNetworkPeer(ZNetPeer peer) { ZRpc val = peer?.m_rpc; if (val == null) { return; } for (int i = 0; i < RegisteredPeerRpcs.Count; i++) { if (RegisteredPeerRpcs[i] == val) { return; } } val.Register("MoveBuildPiecesV4_ServerProbe", (Action)HandleServerProbe); val.Register("MoveBuildPiecesV4_ServerProbeResult", (Action)HandleServerProbeResult); val.Register("MoveBuildPiecesV4_ServerVerifyMove", (Action)HandleServerVerifyMove); val.Register("MoveBuildPiecesV4_ServerVerifyMoveResult", (Action)HandleServerVerifyMoveResult); RegisteredPeerRpcs.Add(val); if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { _serverRpc = val; _serverCapabilityConfirmed = false; _lastServerProbeAt = 0f; _lastServerPolicyAckAt = 0f; } } public static void UnregisterNetworkPeer(ZNetPeer peer) { ZRpc val = peer?.m_rpc; if (val == null) { return; } val.Unregister("MoveBuildPiecesV4_ServerProbe"); val.Unregister("MoveBuildPiecesV4_ServerProbeResult"); val.Unregister("MoveBuildPiecesV4_ServerVerifyMove"); val.Unregister("MoveBuildPiecesV4_ServerVerifyMoveResult"); for (int num = RegisteredPeerRpcs.Count - 1; num >= 0; num--) { if (RegisteredPeerRpcs[num] == val) { RegisteredPeerRpcs.RemoveAt(num); } } PeerLastVerifyTimes.Remove(val); if (_serverRpc == val) { _serverRpc = null; InvalidateServerCapability(null); } } private static void ClearNetworkSession() { UnregisterGlobalRoutedRpcs(); for (int i = 0; i < RegisteredPeerRpcs.Count; i++) { ZRpc val = RegisteredPeerRpcs[i]; if (val != null) { val.Unregister("MoveBuildPiecesV4_ServerProbe"); val.Unregister("MoveBuildPiecesV4_ServerProbeResult"); val.Unregister("MoveBuildPiecesV4_ServerVerifyMove"); val.Unregister("MoveBuildPiecesV4_ServerVerifyMoveResult"); } } RegisteredPeerRpcs.Clear(); PeerLastVerifyTimes.Clear(); _serverRpc = null; _serverProbeNonce = 0L; _lastServerProbeAt = 0f; _lastServerPolicyAckAt = 0f; _serverCapabilityConfirmed = false; _serverPolicyEnabled = false; _serverPolicyRequireKnownPiece = false; _serverPolicyBlockTerrainModifiers = true; _serverPolicyBlockDynamicObjects = true; _serverPolicyMoveLockTimeoutSeconds = 45f; } private static void UpdateServerCapability() { float realtimeSinceStartup = Time.realtimeSinceStartup; if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && _serverCapabilityConfirmed && (_lastServerPolicyAckAt <= 0f || realtimeSinceStartup - _lastServerPolicyAckAt > 12f)) { InvalidateServerCapability("MoveBuildPieces server protocol stopped responding"); } float num = (_serverCapabilityConfirmed ? 5f : 1f); if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && _serverRpc != null && _serverRpc.IsConnected() && !(realtimeSinceStartup - _lastServerProbeAt < num)) { _lastServerProbeAt = realtimeSinceStartup; _serverRpc.Invoke("MoveBuildPiecesV4_ServerProbe", new object[2] { 4, _serverProbeNonce }); } } private static void InvalidateServerCapability(string message) { bool num = _state != null || _pendingRequest != null; _serverCapabilityConfirmed = false; _serverPolicyEnabled = false; _lastServerPolicyAckAt = 0f; _lastServerProbeAt = 0f; _serverProbeNonce = CreateRequestToken(); if (_state != null) { Cancel(_state.Player, showMessage: false); } if (_pendingRequest != null) { CancelPendingRequest(_pendingRequest.Player, showMessage: false, null); } if (num && !string.IsNullOrEmpty(message)) { Message(Player.m_localPlayer, message); } } private static void HandleServerProbe(ZRpc rpc, int protocolVersion, long nonce) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && protocolVersion == 4 && nonce != 0L && TryGetReadyPeer(rpc, out var _)) { ZPackage val = new ZPackage(); val.Write(4); val.Write(nonce); val.Write(MoveBuildPiecesPlugin.IsEnabled); val.Write(MoveBuildPiecesPlugin.RequireKnownPiece); val.Write(MoveBuildPiecesPlugin.BlockTerrainModifiers); val.Write(MoveBuildPiecesPlugin.BlockDynamicObjects); val.Write(MoveBuildPiecesPlugin.MoveLockTimeoutSeconds); rpc.Invoke("MoveBuildPiecesV4_ServerProbeResult", new object[1] { val }); } } private static void HandleServerProbeResult(ZRpc rpc, ZPackage package) { if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || rpc != _serverRpc || package == null) { return; } try { int num = package.ReadInt(); long num2 = package.ReadLong(); bool flag = package.ReadBool(); bool serverPolicyRequireKnownPiece = package.ReadBool(); bool serverPolicyBlockTerrainModifiers = package.ReadBool(); bool serverPolicyBlockDynamicObjects = package.ReadBool(); float num3 = package.ReadSingle(); if (num != 4 || num2 != _serverProbeNonce || float.IsNaN(num3) || float.IsInfinity(num3)) { return; } bool flag2 = _state != null || _pendingRequest != null; _serverPolicyEnabled = flag; _serverPolicyRequireKnownPiece = serverPolicyRequireKnownPiece; _serverPolicyBlockTerrainModifiers = serverPolicyBlockTerrainModifiers; _serverPolicyBlockDynamicObjects = serverPolicyBlockDynamicObjects; _serverPolicyMoveLockTimeoutSeconds = Mathf.Clamp(num3, 5f, 300f); _serverCapabilityConfirmed = true; _lastServerPolicyAckAt = Time.realtimeSinceStartup; if (!flag && flag2) { if (_state != null) { Cancel(_state.Player, showMessage: false); } if (_pendingRequest != null) { CancelPendingRequest(_pendingRequest.Player, showMessage: false, null); } Message(Player.m_localPlayer, "MoveBuildPieces is disabled by the server policy"); } } catch { } } private static void HandleServerVerifyMove(ZRpc rpc, ZPackage package) { //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_012d: 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_0147: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_010e: 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) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || package == null || !TryGetReadyPeer(rpc, out var peer)) { return; } double networkTimeSeconds = GetNetworkTimeSeconds(); if (PeerLastVerifyTimes.TryGetValue(rpc, out var value) && networkTimeSeconds - value < 0.1) { return; } PeerLastVerifyTimes[rpc] = networkTimeSeconds; ZDOID val = ZDOID.None; long num = 0L; Vector3 val2 = Vector3.zero; Quaternion val3 = Quaternion.identity; bool flag = false; try { val = package.ReadZDOID(); long num2 = package.ReadLong(); num = package.ReadLong(); val2 = package.ReadVector3(); val3 = package.ReadQuaternion(); object obj; if (((ZDOID)(ref peer.m_characterID)).IsNone()) { obj = null; } else { ZDOMan instance = ZDOMan.instance; obj = ((instance != null) ? instance.GetZDO(peer.m_characterID) : null); } ZDO val4 = (ZDO)obj; ZDOMan instance2 = ZDOMan.instance; ZDO zdo = ((instance2 != null) ? instance2.GetZDO(val) : null); flag = MoveBuildPiecesPlugin.IsEnabled && val4 != null && val4.GetOwner() == peer.m_uid && val4.GetLong(ZDOVars.s_playerID, 0L) == num2 && IsCommittedMove(zdo, peer.m_uid, num2, num, val2, val3); } catch { flag = false; } ZPackage val5 = new ZPackage(); val5.Write(val); val5.Write(num); val5.Write(val2); val5.Write(val3); val5.Write(flag); rpc.Invoke("MoveBuildPiecesV4_ServerVerifyMoveResult", new object[1] { val5 }); } private static void HandleServerVerifyMoveResult(ZRpc rpc, ZPackage package) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_00b6: 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_00c8: 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_00df: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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) if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || rpc != _serverRpc || package == null) { return; } try { ZDOID val = package.ReadZDOID(); long num = package.ReadLong(); Vector3 val2 = package.ReadVector3(); Quaternion val3 = package.ReadQuaternion(); if (package.ReadBool() && _serverCapabilityConfirmed && NetworkMovesEnabled && _state != null && _state.WaitingForMoveResult && _state.LockToken == num && !((Object)(object)_state.NetView == (Object)null) && _state.NetView.IsValid() && !(_state.NetView.GetZDO().m_uid != val) && !(Vector3.Distance(_state.PendingTargetPosition, val2) > 0.001f) && !(Quaternion.Angle(_state.PendingTargetRotation, val3) > 0.01f)) { MoveState state = _state; ReleaseMoveLock(state.NetView, state.LockPlayerId, state.LockToken, state.LockOwnerPeerId); ApplyVisualMoveLocally(state.NetView, val2, val3); FinishSuccessfulMove(state.Player, state.Piece, val2, val3); } } catch { } } private static bool TryGetReadyPeer(ZRpc rpc, out ZNetPeer peer) { peer = null; if (rpc == null || (Object)(object)ZNet.instance == (Object)null) { return false; } List peers = ZNet.instance.GetPeers(); for (int i = 0; i < peers.Count; i++) { ZNetPeer val = peers[i]; if (val != null && val.m_rpc == rpc && val.IsReady() && val.m_uid != 0L && !((ZDOID)(ref val.m_characterID)).IsNone()) { peer = val; return true; } } return false; } private static void RegisterGlobalRoutedRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && (_registeredRoutedRpc != instance || !_routedHandlersActive)) { UnregisterGlobalRoutedRpcs(); instance.Register("MoveBuildPiecesV4_Move", (Method)HandleRoutedMoveRpc); instance.Register("MoveBuildPiecesV4_MoveResult", (Method)HandleRoutedMoveResultRpc); instance.Register("MoveBuildPiecesV4_ApplyVisual", (Method)HandleRoutedVisualMoveRpc); instance.Register("MoveBuildPiecesV4_LockRequest", (Method)HandleRoutedLockRequestRpc); instance.Register("MoveBuildPiecesV4_LockResponse", (Method)HandleRoutedLockResponseRpc); instance.Register("MoveBuildPiecesV4_LockRelease", (Action)HandleRoutedLockReleaseRpc); _registeredRoutedRpc = instance; _routedHandlersActive = true; } } private static void UnregisterGlobalRoutedRpcs() { if (_registeredRoutedRpc != null && RoutedRpcFunctionsField?.GetValue(_registeredRoutedRpc) is IDictionary dictionary) { dictionary.Remove(StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_Move")); dictionary.Remove(StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_MoveResult")); dictionary.Remove(StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_ApplyVisual")); dictionary.Remove(StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_LockRequest")); dictionary.Remove(StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_LockResponse")); dictionary.Remove(StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_LockRelease")); } _routedHandlersActive = false; _registeredRoutedRpc = null; } private static bool TryResolvePieceNetView(ZDOID zdoId, out ZNetView netView) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) netView = (_routedHandlersActive ? ResolvePieceNetView(zdoId) : null); return (Object)(object)netView != (Object)null; } private static ZNetView ResolvePieceNetView(ZDOID zdoId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (((ZDOID)(ref zdoId)).IsNone() || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return null; } ZDO zDO = ZDOMan.instance.GetZDO(zdoId); ZNetView val = ((zDO != null) ? ZNetScene.instance.FindInstance(zDO) : null); if (!((Object)(object)val != (Object)null) || !val.IsValid() || val.GetZDO() != zDO || !((Object)(object)((Component)val).GetComponent() != (Object)null)) { return null; } return val; } private static void HandleRoutedMoveRpc(long sender, ZDOID zdoId, long playerId, long lockToken, Vector3 position, Quaternion rotation) { //IL_0000: 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_0010: Unknown result type (might be due to invalid IL or missing references) if (TryResolvePieceNetView(zdoId, out var netView)) { ApplyMoveRpc(netView, sender, playerId, lockToken, position, rotation); } } private static void HandleRoutedMoveResultRpc(long sender, ZDOID zdoId, bool success, string message, long lockToken) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (TryResolvePieceNetView(zdoId, out var netView)) { ApplyMoveResultRpc(netView, sender, success, message, lockToken); } } private static void HandleRoutedVisualMoveRpc(long sender, ZDOID zdoId, long lockToken, Vector3 position, Quaternion rotation) { //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_000e: Unknown result type (might be due to invalid IL or missing references) if (TryResolvePieceNetView(zdoId, out var netView)) { ApplyVisualMoveRpc(netView, sender, lockToken, position, rotation); } } private static void HandleRoutedLockRequestRpc(long sender, ZDOID zdoId, long playerId, long lockToken, bool refreshOnly) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (TryResolvePieceNetView(zdoId, out var netView)) { ApplyLockRequestRpc(netView, sender, playerId, lockToken, refreshOnly); } } private static void HandleRoutedLockResponseRpc(long sender, ZDOID zdoId, bool granted, string message, long lockToken) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (TryResolvePieceNetView(zdoId, out var netView)) { ApplyLockResponseRpc(netView, sender, granted, message, lockToken); } } private static void HandleRoutedLockReleaseRpc(long sender, ZDOID zdoId, long playerId, long lockToken) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (TryResolvePieceNetView(zdoId, out var netView)) { ApplyLockReleaseRpc(netView, sender, playerId, lockToken); } } private static bool InvokePieceRpc(ZNetView netView, long targetPeerId, string methodName, params object[] arguments) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)netView == (Object)null || !netView.IsValid() || string.IsNullOrEmpty(methodName) || ZRoutedRpc.instance == null) { return false; } object[] array = new object[arguments.Length + 1]; array[0] = netView.GetZDO().m_uid; Array.Copy(arguments, 0, array, 1, arguments.Length); ZRoutedRpc.instance.InvokeRoutedRPC(targetPeerId, methodName, array); return true; } public static bool ValidateRoutedRpcSender(ZRoutedRpc routedRpc, ZRpc rpc, ZPackage package) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (routedRpc == null || rpc == null || package == null || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return true; } int pos = package.GetPos(); try { package.ReadLong(); long num = package.ReadLong(); package.ReadLong(); package.ReadZDOID(); if (!IsMoveProtocolMethod(package.ReadInt())) { return true; } List peers = ZNet.instance.GetPeers(); for (int i = 0; i < peers.Count; i++) { ZNetPeer val = peers[i]; if (val != null && val.m_rpc == rpc) { return num != 0L && num == val.m_uid; } } return false; } catch { return false; } finally { package.SetPos(pos); } } private static bool IsMoveProtocolMethod(int methodHash) { if (methodHash != StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_Move") && methodHash != StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_MoveResult") && methodHash != StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_ApplyVisual") && methodHash != StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_LockRequest") && methodHash != StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_LockResponse")) { return methodHash == StringExtensionMethods.GetStableHashCode("MoveBuildPiecesV4_LockRelease"); } return true; } public static void Update(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } CleanupCancelledLockRequests(); UpdateServerCapability(); if (!MoveBuildPiecesPlugin.IsEnabled) { if (_state != null) { Cancel(player, showMessage: false); } if (_pendingRequest != null) { CancelPendingRequest(player, showMessage: false, null); } return; } if (_pendingRequest != null && (Object)(object)_pendingRequest.Player == (Object)(object)player && (((Character)player).IsDead() || ((Character)player).IsTeleporting())) { CancelPendingRequest(player, showMessage: false, null); } else if (_pendingRequest != null && (Object)(object)_pendingRequest.Player == (Object)(object)player && Time.realtimeSinceStartup - _pendingRequest.StartedAt > 5f) { CancelPendingRequest(player, showMessage: false, "Move lock request timed out or the object owner has an incompatible mod version"); } if (_pendingRequest != null && (!CanBeginPendingMove(_pendingRequest) || IsUiBlockingInput())) { CancelPendingRequest(player, showMessage: false, null); } if (_pendingRequest != null) { RetryPendingLockAfterOwnerChange(_pendingRequest); } if (ShouldCancelForUiOrState(player)) { Cancel(player, showMessage: false); } else { if (IsUiBlockingInput()) { return; } if ((_state == null || !TryInteractDoorInMoveMode(player)) && ShouldHandleMoveHotkey(player, out var context, out var activationMode)) { ToggleMove(player, context, activationMode); } if (_state == null) { return; } RefreshMoveLock(_state); if (_state == null) { return; } if (_state.WaitingForMoveResult) { RequestServerMoveVerification(_state); } if ((!_state.WaitingForMoveResult || !TryResolveCommittedMove(_state)) && (!_state.WaitingForMoveResult || !TryRetryMoveAfterOwnerChange(_state))) { if (_state.WaitingForMoveResult && _state.MoveFailureReceivedAt > 0f && Time.realtimeSinceStartup - _state.MoveFailureReceivedAt >= 2.5f) { Message(player, string.IsNullOrEmpty(_state.MoveFailureMessage) ? "$msg_invalidplacement" : _state.MoveFailureMessage); _state.WaitingForMoveResult = false; _state.MoveFailureReceivedAt = 0f; _state.MoveFailureMessage = null; _state.MoveRequestOwnerPeerId = 0L; _state.MoveRequestStartedAt = 0f; _state.FirstMoveRequestStartedAt = 0f; _state.MoveRequestAttempts = 0; _state.LastLockRefreshTime = 0f; } else if (_state.WaitingForMoveResult && Time.realtimeSinceStartup - _state.FirstMoveRequestStartedAt > 8f) { Message(player, "Move confirmation timed out; verify the object's position"); Cancel(player, showMessage: false); } else if (!_state.WaitingForMoveResult) { UpdateActiveMovePlacement(player); } } } } public static void UpdateVisuals(Player player) { if (MoveBuildPiecesPlugin.IsEnabled && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && _state != null) { UpdateLineAndGhost(player); } } public static void SuppressAttackControls(Player player, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold) { if (ShouldSuppressAttackControls(player, attack, attackHold, secondaryAttack, secondaryAttackHold)) { attack = false; attackHold = false; secondaryAttack = false; secondaryAttackHold = false; ClearQueuedAttackInput(player); } } private static bool ShouldSuppressAttackControls(Player player, bool attack, bool attackHold, bool secondaryAttack, bool secondaryAttackHold) { if (!MoveBuildPiecesPlugin.IsEnabled || (Object)(object)player == (Object)null) { return false; } if (_state != null && (Object)(object)player == (Object)(object)_state.Player) { return true; } if ((Object)(object)_suppressAttackPlayer == (Object)(object)player) { if ((attack || attackHold || secondaryAttack || secondaryAttackHold) && Time.realtimeSinceStartup <= _suppressAttackUntilTime) { return true; } _suppressAttackPlayer = null; _suppressAttackUntilTime = 0f; } return false; } public static bool ShouldHandlePlacement(Player player) { if (_state != null && (Object)(object)player != (Object)null) { return (Object)(object)player == (Object)(object)_state.Player; } return false; } public static bool ShouldBlockBuildAction(Player player) { if (_state != null && (Object)(object)player != (Object)null) { return (Object)(object)player == (Object)(object)_state.Player; } return false; } public static bool ShouldBypassRequirements(Player player, Piece piece, RequirementMode mode) { //IL_0014: 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_0019: Invalid comparison between Unknown and I4 if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { return false; } if ((int)mode != 0 && (int)mode != 2) { return false; } string prefabName = Utils.GetPrefabName(((Component)piece).gameObject); if (_state != null && (Object)(object)player == (Object)(object)_state.Player) { return prefabName == _state.PrefabName; } return false; } public static bool ShouldSkipVanillaUpdatePlacement(Player player) { if (_state != null && (Object)(object)player != (Object)null) { return (Object)(object)player == (Object)(object)_state.Player; } return false; } public static void NotifyDoorInteracted(Player player) { if (_state != null && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)_state.Player) { _lastDoorInteractFrame = Time.frameCount; } } public static void CancelForTeleport(Player player) { if (_state != null && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)_state.Player) { Cancel(player, showMessage: true); } if (_pendingRequest != null && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)_pendingRequest.Player) { CancelPendingRequest(player, showMessage: false, null); } } public static void CancelForDeath(Player player) { if (_state != null && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)_state.Player) { Cancel(player, showMessage: true); } if (_pendingRequest != null && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)_pendingRequest.Player) { CancelPendingRequest(player, showMessage: false, null); } } public static void CancelForPlayerDestroyed(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer)) { if (_state != null && (Object)(object)player == (Object)(object)_state.Player) { Cancel(player, showMessage: false); } if (_pendingRequest != null && (Object)(object)player == (Object)(object)_pendingRequest.Player) { CancelPendingRequest(player, showMessage: false, null); } } } public static void TryFinishMove(Player player) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00a2: 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_00ae: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if (_state == null || (Object)(object)player != (Object)(object)_state.Player || _state.WaitingForMoveResult) { return; } if (!IsMoveSelectionIntact(_state, player)) { Message(player, "Move cancelled because the selected build piece changed"); Cancel(player, showMessage: false); return; } if (!RunFinalPlacementValidation(player)) { Message(player, "$msg_invalidplacement"); return; } GameObject placementGhost = GetPlacementGhost(player); if ((Object)(object)placementGhost == (Object)null) { Message(player, "$msg_invalidplacement"); Cancel(player, showMessage: false); return; } PlacementStatus placementStatus = GetPlacementStatus(player); if ((int)placementStatus != 0) { Message(player, GetPlacementFailureMessage(placementStatus)); return; } Vector3 position = placementGhost.transform.position; Quaternion rotation = placementGhost.transform.rotation; if (!IsInsideOriginalBuildArea(_state, position)) { Message(player, "$msg_nobuildzone"); } else if (ValidateMoveTarget(player, _state.Piece)) { Piece piece = _state.Piece; _state.PendingTargetPosition = position; _state.PendingTargetRotation = rotation; if (!RequestMovePiece(_state, position, rotation, out var completedImmediately)) { Message(player, "$msg_invalidplacement"); } else if (!completedImmediately) { Message(player, "Moving " + Localization.instance.Localize(piece.m_name)); } else { FinishSuccessfulMove(player, piece, position, rotation); } } } private static bool RunFinalPlacementValidation(Player player) { if ((Object)(object)player == (Object)null || UpdatePlacementGhostMethod == null) { return false; } _runningFinalPlacementValidation = true; _placementValidationPlayer = player; try { UpdatePlacementGhostMethod.Invoke(player, new object[1] { true }); return true; } catch (Exception ex) { Debug.LogWarning((object)("[MoveBuildPieces] Final placement validation failed: " + ex.GetBaseException().Message)); return false; } finally { _runningFinalPlacementValidation = false; _placementValidationPlayer = null; _skipPlacementGhostPlayer = player; _skipPlacementGhostFrame = Time.frameCount; } } public static bool ShouldRunPlacementGhostUpdate(Player player) { if (_runningFinalPlacementValidation && (Object)(object)player == (Object)(object)_placementValidationPlayer) { return true; } if ((Object)(object)player == (Object)(object)_skipPlacementGhostPlayer && Time.frameCount == _skipPlacementGhostFrame) { return false; } if (Time.frameCount != _skipPlacementGhostFrame) { _skipPlacementGhostPlayer = null; _skipPlacementGhostFrame = -1; } return true; } public static Collider[] FilterPlacementOverlap(Collider[] overlaps) { Piece val = _state?.Piece; if ((Object)(object)val == (Object)null || overlaps == null || overlaps.Length == 0) { return overlaps; } int num = 0; foreach (Collider val2 in overlaps) { if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).GetComponentInParent() == (Object)(object)val) { num++; } } if (num == 0) { return overlaps; } Collider[] array = (Collider[])(object)new Collider[overlaps.Length - num]; int num2 = 0; foreach (Collider val3 in overlaps) { if ((Object)(object)val3 == (Object)null || (Object)(object)((Component)val3).GetComponentInParent() != (Object)(object)val) { array[num2++] = val3; } } return array; } public static bool TryTestGhostClippingIgnoringMovedPiece(Player player, GameObject ghost, float maxPenetration, out bool result) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00fc: Unknown result type (might be due to invalid IL or missing references) result = false; Piece val = (((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)_state?.Player) ? _state.Piece : null); if ((Object)(object)val == (Object)null) { return false; } if ((Object)(object)ghost == (Object)null || !(PlaceRayMaskField?.GetValue(player) is int num)) { result = true; return true; } Collider[] componentsInChildren = ghost.GetComponentsInChildren(); Collider[] array = Physics.OverlapSphere(ghost.transform.position, 10f, num); Vector3 val4 = default(Vector3); float num2 = default(float); foreach (Collider val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } foreach (Collider val3 in array) { if (!((Object)(object)val3 == (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent() == (Object)(object)val) && Physics.ComputePenetration(val2, ((Component)val2).transform.position, ((Component)val2).transform.rotation, val3, ((Component)val3).transform.position, ((Component)val3).transform.rotation, ref val4, ref num2) && num2 > maxPenetration) { result = true; return true; } } } return true; } public static bool TryEvaluatePieceOverlapIgnoringMovedPiece(Player player, Vector3 position, Quaternion rotation, string pieceName, List pieces, bool allowRotatedOverlap, out bool result) { //IL_0062: 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_0084: 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) result = false; Piece val = (((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)_state?.Player) ? _state.Piece : null); if ((Object)(object)val == (Object)null || pieces == null) { return false; } for (int i = 0; i < pieces.Count; i++) { Piece val2 = pieces[i]; if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)val) && Vector3.Distance(position, ((Component)val2).transform.position) < 0.05f && (!allowRotatedOverlap || Quaternion.Angle(((Component)val2).transform.rotation, rotation) <= 10f) && Utils.CustomStartsWith(((Object)((Component)val2).gameObject).name, pieceName)) { result = true; break; } } return true; } public static bool TryEvaluateExtensionRangeIgnoringMovedPiece(StationExtension extension, float radius, out bool result) { //IL_0076: 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) result = false; Piece val = _state?.Piece; if ((Object)(object)val == (Object)null || (Object)(object)extension == (Object)null || !(StationExtensionsField?.GetValue(null) is List list)) { return false; } for (int i = 0; i < list.Count; i++) { StationExtension val2 = list[i]; if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)extension) && !((Object)(object)((Component)val2).GetComponentInParent() == (Object)(object)val) && Vector3.Distance(((Component)val2).transform.position, ((Component)extension).transform.position) < radius) { result = true; break; } } return true; } private static void FinishSuccessfulMove(Player player, Piece movedPiece, Vector3 targetPosition, Quaternion targetRotation) { //IL_0024: 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_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) if ((Object)(object)movedPiece == (Object)null) { Message(player, "$msg_invalidplacement"); Cancel(player, showMessage: false); return; } MoveState state = _state; try { UpdateMovedBedSpawnPoint(state, targetPosition, targetRotation); SuppressAttackUntilRelease(player); Message(player, "Moved " + Localization.instance.Localize(movedPiece.m_name)); movedPiece.m_placeEffect.Create(targetPosition, targetRotation, ((Component)movedPiece).transform, 1f, -1); } catch (Exception ex) { Debug.LogWarning((object)("[MoveBuildPieces] Move completion effect failed: " + ex.GetBaseException().Message)); } finally { Cancel(player, showMessage: false, releaseLock: false); } } private static void UpdateMovedBedSpawnPoint(MoveState state, Vector3 targetPosition, Quaternion targetRotation) { //IL_0030: 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_0068: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0071: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (state != null && state.UpdateBedSpawnPoint && !((Object)(object)Game.instance == (Object)null)) { PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); if (playerProfile != null && playerProfile.HaveCustomSpawnPoint() && !(Vector3.Distance(playerProfile.GetCustomSpawnPoint(), state.BedOriginalProfileSpawnPoint) > 0.1f)) { Vector3 val = (((Object)(object)state.Piece != (Object)null) ? ((Component)state.Piece).transform.lossyScale : Vector3.one); Vector3 customSpawnPoint = targetPosition + targetRotation * Vector3.Scale(state.BedSpawnLocalPoint, val); playerProfile.SetCustomSpawnPoint(customSpawnPoint); } } } private static void SuppressAttackUntilRelease(Player player) { if (!((Object)(object)player == (Object)null)) { _suppressAttackPlayer = player; _suppressAttackUntilTime = Time.realtimeSinceStartup + 5f; ClearQueuedAttackInput(player); } } private static void ClearQueuedAttackInput(Player player) { if (!((Object)(object)player == (Object)null)) { AttackField?.SetValue(player, false); AttackHoldField?.SetValue(player, false); SecondaryAttackField?.SetValue(player, false); SecondaryAttackHoldField?.SetValue(player, false); QueuedAttackTimerField?.SetValue(player, 0f); QueuedSecondAttackTimerField?.SetValue(player, 0f); AttackDrawTimeField?.SetValue(player, 0f); } } private static bool ShouldHandleMoveHotkey(Player player, out MoveContext context, out MoveActivationMode activationMode) { //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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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) context = MoveContext.Build; activationMode = MoveBuildPiecesPlugin.ActiveMode; KeyboardShortcut val; if (_state != null && (Object)(object)player == (Object)(object)_state.Player) { context = _state.Context; activationMode = _state.ActivationMode; val = GetMoveHotkey(activationMode, context); return ((KeyboardShortcut)(ref val)).IsDown(); } if (_pendingRequest != null && (Object)(object)player == (Object)(object)_pendingRequest.Player) { context = _pendingRequest.Context; activationMode = _pendingRequest.ActivationMode; val = GetMoveHotkey(activationMode, context); return ((KeyboardShortcut)(ref val)).IsDown(); } bool flag = ((Character)player).InPlaceMode(); if (activationMode == MoveActivationMode.BuildMenu && flag) { val = MoveBuildPiecesPlugin.BuildModeMoveHotkey; if (((KeyboardShortcut)(ref val)).IsDown()) { context = MoveContext.Build; return true; } } if (activationMode == MoveActivationMode.World && !flag && !HasEquippedBuildTool(player)) { val = MoveBuildPiecesPlugin.WorldModeMoveHotkey; if (((KeyboardShortcut)(ref val)).IsDown()) { context = MoveContext.World; return true; } } if (activationMode == MoveActivationMode.Mixed) { val = MoveBuildPiecesPlugin.MixedModeMoveHotkey; if (((KeyboardShortcut)(ref val)).IsDown()) { if (flag) { context = MoveContext.Build; return true; } if (!HasEquippedBuildTool(player)) { context = MoveContext.World; return true; } } } return false; } private static KeyboardShortcut GetMoveHotkey(MoveActivationMode activationMode, MoveContext context) { //IL_0004: 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_000e: Unknown result type (might be due to invalid IL or missing references) if (activationMode == MoveActivationMode.Mixed) { return MoveBuildPiecesPlugin.MixedModeMoveHotkey; } if (context != MoveContext.World) { return MoveBuildPiecesPlugin.BuildModeMoveHotkey; } return MoveBuildPiecesPlugin.WorldModeMoveHotkey; } private static void ToggleMove(Player player, MoveContext context, MoveActivationMode activationMode) { if (_state != null) { Cancel(player, showMessage: true); } else if (_pendingRequest != null) { CancelPendingRequest(player, showMessage: true, null); } else { StartMove(player, context, activationMode); } } private static bool TryInteractDoorInMoveMode(Player player) { if ((Object)(object)player == (Object)null || _lastDoorInteractFrame == Time.frameCount || Hud.InRadial() || (!ZInput.GetButtonDown("Use") && !ZInput.GetButtonDown("JoyUse"))) { return false; } Door val = FindDoorForMoveModeInteraction(player); if ((Object)(object)val == (Object)null) { return false; } bool flag = ZInput.GetButton("AltPlace") || ZInput.GetButton("JoyAltPlace") || ZInput.GetButton("JoyAltKeys"); if (!val.Interact((Humanoid)(object)player, false, flag)) { return false; } _lastDoorInteractFrame = Time.frameCount; return true; } private static Door FindDoorForMoveModeInteraction(Player player) { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0167: 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) if ((Object)(object)player == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { return null; } int num = ((InteractMaskField?.GetValue(player) is int num2) ? num2 : LayerMask.GetMask(new string[5] { "piece", "piece_nonsolid", "Default", "static_solid", "Default_small" })); object? obj = EyeField?.GetValue(player); Transform val = (Transform)((obj is Transform) ? obj : null); float num3 = ((MaxInteractDistanceField?.GetValue(player) is float num4) ? num4 : 5f); Transform transform = ((Component)GameCamera.instance).transform; GameObject placementGhost = GetPlacementGhost(player); int num5 = Physics.RaycastNonAlloc(transform.position, transform.forward, DoorInteractHits, 50f, num); Array.Sort(DoorInteractHits, 0, num5, RaycastHitDistanceComparer.Instance); for (int i = 0; i < num5; i++) { RaycastHit val2 = DoorInteractHits[i]; Collider collider = ((RaycastHit)(ref val2)).collider; if (!((Object)(object)collider == (Object)null) && !IsPlayerCollider(player, collider) && (!((Object)(object)placementGhost != (Object)null) || !((Component)collider).transform.IsChildOf(placementGhost.transform))) { if (Vector3.Distance(((Object)(object)val != (Object)null) ? val.position : ((Component)player).transform.position, ((RaycastHit)(ref val2)).point) >= num3) { return null; } Door componentInParent = ((Component)collider).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { return componentInParent; } return null; } } return null; } private static bool IsPlayerCollider(Player player, Collider collider) { if ((Object)(object)player == (Object)null || (Object)(object)collider == (Object)null) { return false; } if ((Object)(object)collider.attachedRigidbody != (Object)null) { return (Object)(object)((Component)collider.attachedRigidbody).gameObject == (Object)(object)((Component)player).gameObject; } return false; } private static bool TryAcquireOrRequestMoveLock(Player player, Piece piece, MoveContext context, MoveActivationMode activationMode, ZNetView netView, long lockToken) { long num = (((Object)(object)player != (Object)null) ? player.GetPlayerID() : 0); long num2 = (((Object)(object)player != (Object)null) ? ((Character)player).GetOwner() : 0); if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null || (Object)(object)netView == (Object)null || !netView.IsValid() || num == 0L || num2 == 0L || lockToken == 0L) { Message(player, "$msg_invalidplacement"); return false; } if (!HasVerifiedServerProtocol()) { Message(player, "Matching MoveBuildPieces 1.1.1 is required on the server"); return false; } if (!NetworkMovesEnabled) { Message(player, "MoveBuildPieces is disabled by the server policy"); return false; } if (netView.IsOwner()) { if (!TryAcquireMoveLock(netView, num2, player, lockToken, refreshOnly: false, out var message)) { Message(player, message); return false; } return true; } _pendingRequest = new PendingMoveRequest { Player = player, Piece = piece, NetView = netView, Context = context, ActivationMode = activationMode, PlayerId = num, LockToken = lockToken, ExpectedOwnerPeerId = netView.GetZDO().GetOwner(), StartedAt = Time.realtimeSinceStartup, LastRequestAt = Time.realtimeSinceStartup }; if (_pendingRequest.ExpectedOwnerPeerId == 0L) { _pendingRequest = null; Message(player, "The object has no network owner yet"); return false; } InvokePieceRpc(netView, _pendingRequest.ExpectedOwnerPeerId, "MoveBuildPiecesV4_LockRequest", num, lockToken, false); Message(player, "Requesting move lock"); return false; } private static void RetryPendingLockAfterOwnerChange(PendingMoveRequest request) { if (!((Object)(object)request?.NetView == (Object)null) && request.NetView.IsValid() && !(Time.realtimeSinceStartup - request.LastRequestAt < 1.25f)) { ZDO zDO = request.NetView.GetZDO(); long num = ((zDO != null) ? zDO.GetOwner() : 0); if (num != 0L && num != request.ExpectedOwnerPeerId) { long expectedOwnerPeerId = request.ExpectedOwnerPeerId; ReleaseMoveLock(request.NetView, request.PlayerId, request.LockToken, expectedOwnerPeerId); request.ExpectedOwnerPeerId = num; request.LastRequestAt = Time.realtimeSinceStartup; InvokePieceRpc(request.NetView, num, "MoveBuildPiecesV4_LockRequest", request.PlayerId, request.LockToken, false); } } } private static bool TryAcquireMoveLock(ZNetView netView, long senderPeerId, Player player, long lockToken, bool refreshOnly, out string message) { //IL_01d2: Unknown result type (might be due to invalid IL or missing references) message = ""; ZDO val = (((Object)(object)netView != (Object)null && netView.IsValid()) ? netView.GetZDO() : null); long num = (((Object)(object)player != (Object)null) ? player.GetPlayerID() : 0); if (!NetworkMovesEnabled || !HasVerifiedServerProtocol() || val == null || !netView.IsOwner() || senderPeerId == 0L || num == 0L || lockToken == 0L || ((Character)player).GetOwner() != senderPeerId) { message = "$msg_invalidplacement"; return false; } long num2 = val.GetLong(LockOwnerHash, 0L); long num3 = val.GetLong(LockPeerHash, 0L); long num4 = val.GetLong(LockTokenHash, 0L); double num5 = (double)val.GetLong(LockUntilHash, 0L) / 1000.0; double networkTimeSeconds = GetNetworkTimeSeconds(); bool flag = num2 == num && num3 == senderPeerId && num4 == lockToken && num5 > networkTimeSeconds; if (refreshOnly && !flag) { message = "Move lock was lost"; return false; } if (num2 != 0L && num5 > networkTimeSeconds && (num2 != num || num3 != senderPeerId || num4 != lockToken)) { string text = val.GetString(LockNameHash, "another player"); message = "Already being moved by " + text; return false; } if (!flag && !CanGrantMoveLock(player, ((Component)netView).GetComponent(), out message)) { return false; } float moveLockTimeoutSeconds = MoveBuildPiecesPlugin.MoveLockTimeoutSeconds; double num6 = num5 - networkTimeSeconds; if (flag && num6 > (double)moveLockTimeoutSeconds - 0.5 && num6 <= (double)moveLockTimeoutSeconds + 0.5) { return true; } val.Set(LockOwnerHash, num); val.Set(LockPeerHash, senderPeerId); val.Set(LockTokenHash, lockToken); val.Set(LockUntilHash, SecondsToMillis(networkTimeSeconds + (double)moveLockTimeoutSeconds)); string playerName = player.GetPlayerName(); val.Set(LockNameHash, string.IsNullOrWhiteSpace(playerName) ? "another player" : playerName); ZDOMan instance = ZDOMan.instance; if (instance != null) { instance.ForceSendZDO(val.m_uid); } return true; } private static void RefreshMoveLock(MoveState state) { if ((Object)(object)state?.NetView == (Object)null || !state.NetView.IsValid() || state.NetView.GetZDO() == null || Time.realtimeSinceStartup - state.LastLockRefreshTime < 2f) { return; } state.LastLockRefreshTime = Time.realtimeSinceStartup; if (state.NetView.IsOwner()) { if (!TryAcquireMoveLock(state.NetView, state.LockPeerId, state.Player, state.LockToken, refreshOnly: true, out var _)) { Message(state.Player, "Move lock was lost"); Cancel(state.Player, showMessage: false); } } else if (state.NetView.HasOwner()) { long owner = state.NetView.GetZDO().GetOwner(); if (owner == 0L) { Message(state.Player, "Move lock was lost"); Cancel(state.Player, showMessage: false); return; } state.LockRequestOwnerPeerId = owner; state.LockOwnerPeerId = owner; InvokePieceRpc(state.NetView, owner, "MoveBuildPiecesV4_LockRequest", state.LockPlayerId, state.LockToken, true); } } private static void ReleaseMoveLock(ZNetView netView, long playerId, long lockToken, long expectedOwnerPeerId = 0L) { if ((Object)(object)netView == (Object)null || !netView.IsValid() || playerId == 0L || lockToken == 0L) { return; } if (netView.IsOwner()) { ClearMoveLock(netView, ZDOMan.GetSessionID(), playerId, lockToken); return; } long num = (netView.HasOwner() ? netView.GetZDO().GetOwner() : 0); if (expectedOwnerPeerId != 0L) { InvokePieceRpc(netView, expectedOwnerPeerId, "MoveBuildPiecesV4_LockRelease", playerId, lockToken); } if (num != 0L && num != expectedOwnerPeerId) { InvokePieceRpc(netView, num, "MoveBuildPiecesV4_LockRelease", playerId, lockToken); } } private static bool ClearMoveLock(ZNetView netView, long senderPeerId, long playerId, long lockToken) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) ZDO val = (((Object)(object)netView != (Object)null && netView.IsValid()) ? netView.GetZDO() : null); if (val == null || !netView.IsOwner() || senderPeerId == 0L || playerId == 0L || lockToken == 0L || val.GetLong(LockOwnerHash, 0L) != playerId || val.GetLong(LockPeerHash, 0L) != senderPeerId || val.GetLong(LockTokenHash, 0L) != lockToken) { return false; } val.Set(LockOwnerHash, 0L); val.Set(LockPeerHash, 0L); val.Set(LockTokenHash, 0L); val.Set(LockUntilHash, 0L); val.Set(LockNameHash, ""); ZDOMan instance = ZDOMan.instance; if (instance != null) { instance.ForceSendZDO(val.m_uid); } return true; } private static void ApplyLockRequestRpc(ZNetView netView, long sender, long playerId, long lockToken, bool refreshOnly) { if (!((Object)(object)netView == (Object)null) && netView.IsValid() && netView.IsOwner()) { Player player; bool num = TryGetAuthenticatedPlayer(sender, playerId, out player); string message = ""; bool flag = num && TryAcquireMoveLock(netView, sender, player, lockToken, refreshOnly, out message); if (!num) { message = "$msg_privatezone"; } if (sender != 0L) { InvokePieceRpc(netView, sender, "MoveBuildPiecesV4_LockResponse", flag, message, lockToken); } } } private static void ApplyLockResponseRpc(ZNetView netView, long sender, bool granted, string message, long lockToken) { //IL_00a9: 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) CancelledLockRequest value; if (_state != null && (Object)(object)_state.NetView == (Object)(object)netView && _state.LockToken == lockToken && _state.LockRequestOwnerPeerId == sender) { _state.LockRequestOwnerPeerId = 0L; if (granted) { _state.LockOwnerPeerId = sender; } if (!granted) { Message(_state.Player, string.IsNullOrEmpty(message) ? "Move lock was lost" : message); Cancel(_state.Player, showMessage: false); } } else if (CancelledLockRequests.TryGetValue(lockToken, out value)) { if ((Object)(object)netView != (Object)null && netView.IsValid() && netView.GetZDO().m_uid == value.ZdoId && value.ExpectedOwnerPeerId == sender) { CancelledLockRequests.Remove(lockToken); if (granted) { ReleaseMoveLock(netView, value.PlayerId, value.LockToken, value.ExpectedOwnerPeerId); } } } else if (_pendingRequest != null && !((Object)(object)netView == (Object)null) && !((Object)(object)_pendingRequest.NetView != (Object)(object)netView) && _pendingRequest.LockToken == lockToken && _pendingRequest.ExpectedOwnerPeerId == sender) { PendingMoveRequest pendingRequest = _pendingRequest; _pendingRequest = null; if (!granted) { Message(pendingRequest.Player, string.IsNullOrEmpty(message) ? "$msg_inuse" : message); } else if (!CanBeginPendingMove(pendingRequest) || !ValidateMoveTarget(pendingRequest.Player, pendingRequest.Piece)) { ReleaseMoveLock(pendingRequest.NetView, pendingRequest.PlayerId, pendingRequest.LockToken, pendingRequest.ExpectedOwnerPeerId); } else { BeginMoveWithLockedPiece(pendingRequest.Player, pendingRequest.Piece, pendingRequest.Context, pendingRequest.ActivationMode, pendingRequest.NetView, pendingRequest.LockToken, sender); } } } private static void ApplyLockReleaseRpc(ZNetView netView, long sender, long playerId, long lockToken) { if (!((Object)(object)netView == (Object)null) && netView.IsValid() && netView.IsOwner()) { ClearMoveLock(netView, sender, playerId, lockToken); } } private static bool TryGetAuthenticatedPlayer(long senderPeerId, long playerId, out Player player) { player = null; if (senderPeerId == 0L || playerId == 0L) { return false; } List allPlayers = Player.GetAllPlayers(); for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if ((Object)(object)val != (Object)null && val.GetPlayerID() == playerId && ((Character)val).GetOwner() == senderPeerId && !((Character)val).IsDead() && !((Character)val).IsTeleporting()) { player = val; return true; } } return false; } private static bool CanBeginPendingMove(PendingMoveRequest request) { if (!HasVerifiedServerProtocol() || !NetworkMovesEnabled || (Object)(object)request?.Player == (Object)null || ((Character)request.Player).IsDead() || ((Character)request.Player).IsTeleporting() || (Object)(object)request.Piece == (Object)null || (Object)(object)request.NetView == (Object)null || !request.NetView.IsValid() || IsUiBlockingInput()) { return false; } bool flag = ((Character)request.Player).InPlaceMode(); if (request.Context != MoveContext.Build) { if (!flag) { return !HasEquippedBuildTool(request.Player); } return false; } return flag; } private static void CancelPendingRequest(Player player, bool showMessage, string message) { //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) PendingMoveRequest pendingRequest = _pendingRequest; if (pendingRequest != null && (!((Object)(object)player != (Object)null) || !((Object)(object)pendingRequest.Player != (Object)(object)player))) { _pendingRequest = null; ZDO val = (((Object)(object)pendingRequest.NetView != (Object)null && pendingRequest.NetView.IsValid()) ? pendingRequest.NetView.GetZDO() : null); if (val != null) { CancelledLockRequests[pendingRequest.LockToken] = new CancelledLockRequest { ZdoId = val.m_uid, PlayerId = pendingRequest.PlayerId, LockToken = pendingRequest.LockToken, ExpectedOwnerPeerId = pendingRequest.ExpectedOwnerPeerId, CancelledAt = Time.realtimeSinceStartup }; } try { ReleaseMoveLock(pendingRequest.NetView, pendingRequest.PlayerId, pendingRequest.LockToken, pendingRequest.ExpectedOwnerPeerId); } catch { } if (showMessage) { Message(pendingRequest.Player, "Move cancelled"); } else if (!string.IsNullOrEmpty(message)) { Message(pendingRequest.Player, message); } } } private static void CleanupCancelledLockRequests() { if (CancelledLockRequests.Count == 0) { _nextCancelledRequestCleanupAt = 0f; return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup < _nextCancelledRequestCleanupAt) { return; } _nextCancelledRequestCleanupAt = realtimeSinceStartup + 5f; ExpiredRequestTokens.Clear(); foreach (KeyValuePair cancelledLockRequest in CancelledLockRequests) { if (realtimeSinceStartup - cancelledLockRequest.Value.CancelledAt > 310f) { ExpiredRequestTokens.Add(cancelledLockRequest.Key); } } for (int i = 0; i < ExpiredRequestTokens.Count; i++) { CancelledLockRequests.Remove(ExpiredRequestTokens[i]); } ExpiredRequestTokens.Clear(); } private static long CreateRequestToken() { long num = DateTime.UtcNow.Ticks ^ ZDOMan.GetSessionID() ^ ++_requestTokenCounter; if (num != 0L) { return num; } return ++_requestTokenCounter; } private static double GetNetworkTimeSeconds() { if (!((Object)(object)ZNet.instance != (Object)null)) { return Time.realtimeSinceStartupAsDouble; } return ZNet.instance.GetTimeSeconds(); } private static long SecondsToMillis(double seconds) { return (long)(seconds * 1000.0); } private static void UpdateActiveMovePlacement(Player player) { if (_state == null || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)_state.Player) { return; } if ((Object)(object)GetBuildPieces(player) != (Object)(object)GetRelocatePieceTable(_state)) { Cancel(player, showMessage: true); return; } RotateMoveGhost(player); if ((ZInput.GetButtonDown("Attack") || ZInput.GetButtonDown("JoyPlace")) && !Hud.InRadial()) { TryFinishMove(player); } } private static void RotateMoveGhost(Player player) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_010d: Invalid comparison between Unknown and I4 GameObject placementGhost = GetPlacementGhost(player); Piece val = (((Object)(object)placementGhost != (Object)null) ? placementGhost.GetComponent() : null); if ((Object)(object)player == (Object)null || PlaceRotationField == null || ScrollCurrentAmountField == null || RotatePieceTimerField == null || (Object)(object)val == (Object)null || !val.m_canRotate || !placementGhost.activeInHierarchy) { return; } int num = ((PlaceRotationField.GetValue(player) is int num2) ? num2 : 0); float num3 = ((ScrollCurrentAmountField.GetValue(player) is float num4) ? num4 : 0f); num3 += ZInput.GetMouseScrollWheel(); if (num3 > player.m_scrollAmountThreshold) { num3 = 0f; num++; } else if (num3 < 0f - player.m_scrollAmountThreshold) { num3 = 0f; num--; } float num5 = 0f; bool flag = false; if (ZInput.IsGamepadActive()) { InputLayout inputLayout = ZInput.InputLayout; if ((int)inputLayout != 0) { if (inputLayout - 1 <= 1) { bool button = ZInput.GetButton("JoyRotate"); bool button2 = ZInput.GetButton("JoyRotateRight"); flag = button || button2; num5 = (button ? 0.5f : (button2 ? (-0.5f) : 0f)); } } else { num5 = ZInput.GetJoyRightStickX(true); flag = ZInput.GetButton("JoyRotate") && Mathf.Abs(num5) > 0.5f; } } float num6 = ((RotatePieceTimerField.GetValue(player) is float num7) ? num7 : 0f); if (flag) { if (num6 == 0f || num6 > 0.25f) { num += ((num5 < 0f) ? 1 : (-1)); if (num6 > 0.25f) { num6 = 0.17f; } } num6 += Time.deltaTime; } else { num6 = 0f; } PlaceRotationField.SetValue(player, num); ScrollCurrentAmountField.SetValue(player, num3); RotatePieceTimerField.SetValue(player, num6); } private static void StartMove(Player player, MoveContext context, MoveActivationMode activationMode) { bool flag = ((Character)player).InPlaceMode(); if ((context == MoveContext.Build && !flag) || (context == MoveContext.World && (flag || HasEquippedBuildTool(player)))) { return; } Piece val = ((context == MoveContext.World) ? FindWorldHoveringPiece(player) : player.GetHoveringPiece()); if ((Object)(object)val == (Object)null) { Message(player, "Hover a build piece to move it"); } else if (ValidateMoveTarget(player, val)) { ZNetView component = ((Component)val).GetComponent(); long lockToken = CreateRequestToken(); if (TryAcquireOrRequestMoveLock(player, val, context, activationMode, component, lockToken)) { BeginMoveWithLockedPiece(player, val, context, activationMode, component, lockToken, component.GetZDO().GetOwner()); } } } private static void BeginMoveWithLockedPiece(Player player, Piece piece, MoveContext context, MoveActivationMode activationMode, ZNetView netView, long lockToken, long lockOwnerPeerId) { //IL_002e: 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_0125: 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_0120: 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_0154: 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_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) long num = (((Object)(object)player != (Object)null) ? player.GetPlayerID() : 0); long lockPeerId = (((Object)(object)player != (Object)null) ? ((Character)player).GetOwner() : 0); List playerBuildAreasAt = GetPlayerBuildAreasAt(((Component)piece).transform.position); if (playerBuildAreasAt.Count == 0) { ReleaseMoveLock(netView, num, lockToken, lockOwnerPeerId); Message(player, "$msg_nobuildzone"); return; } PieceTable buildPieces = GetBuildPieces(player); GameObject tableObject = null; if (!BeginRelocationPlacement(player, piece, buildPieces, out tableObject)) { RestoreBuildState(player, buildPieces, null); ReleaseMoveLock(netView, num, lockToken, lockOwnerPeerId); Message(player, "$msg_invalidplacement"); return; } SetupPlacementGhostMethod?.Invoke(player, Array.Empty()); if ((Object)(object)GetPlacementGhost(player) == (Object)null) { RestoreBuildState(player, buildPieces, tableObject); ReleaseMoveLock(netView, num, lockToken, lockOwnerPeerId); Message(player, "$msg_invalidplacement"); return; } Bed componentInChildren = ((Component)piece).GetComponentInChildren(true); bool flag = (Object)(object)componentInChildren != (Object)null && componentInChildren.IsCurrent(); Vector3 bedSpawnLocalPoint = ((flag && (Object)(object)componentInChildren.m_spawnPoint != (Object)null) ? ((Component)piece).transform.InverseTransformPoint(componentInChildren.m_spawnPoint.position) : Vector3.zero); Vector3 val; if (flag) { Game instance = Game.instance; if (((instance != null) ? instance.GetPlayerProfile() : null) != null) { val = Game.instance.GetPlayerProfile().GetCustomSpawnPoint(); goto IL_0154; } } val = Vector3.zero; goto IL_0154; IL_0154: Vector3 bedOriginalProfileSpawnPoint = val; _state = new MoveState { Player = player, Piece = piece, NetView = netView, PrefabName = GetCanonicalPiecePrefabName(piece), Context = context, ActivationMode = activationMode, RelocateTableObject = tableObject, OriginalBuildPieces = buildPieces, ActivePieceTable = GetBuildPieces(player), OriginalPosition = ((Component)piece).transform.position, OriginalBuildAreas = playerBuildAreasAt, LockPlayerId = num, LockPeerId = lockPeerId, LockToken = lockToken, LockOwnerPeerId = lockOwnerPeerId, UpdateBedSpawnPoint = flag, BedSpawnLocalPoint = bedSpawnLocalPoint, BedOriginalProfileSpawnPoint = bedOriginalProfileSpawnPoint, LastLockRefreshTime = Time.realtimeSinceStartup }; Message(player, "Move mode: place the ghost to move " + Localization.instance.Localize(piece.m_name)); UpdateMoveGhostValidity(player); } private static bool BeginRelocationPlacement(Player player, Piece piece, PieceTable originalBuildPieces, out GameObject tableObject) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected I4, but got Unknown tableObject = null; if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { return false; } tableObject = new GameObject("MoveBuildPieces_TemporaryPieceTable"); Object.DontDestroyOnLoad((Object)(object)tableObject); tableObject.AddComponent(); PieceTable val = tableObject.AddComponent(); GameObject piecePrefab = GetPiecePrefab(piece); Piece val2 = (((Object)(object)piecePrefab != (Object)null) ? piecePrefab.GetComponent() : null); if ((Object)(object)val2 == (Object)null) { Debug.LogWarning((object)("[MoveBuildPieces] Failed to resolve a Piece prefab for relocation: " + Utils.GetPrefabName(((Component)piece).gameObject))); Object.Destroy((Object)(object)tableObject); tableObject = null; return false; } val.m_pieces = new List { piecePrefab }; val.m_categories = new List { (PieceCategory)0 }; val.m_categoryLabels = new List { "Move" }; SetSinglePieceAvailableList(val, val2); SetBuildPieces(player, val); GameObject selectedPrefab = val.GetSelectedPrefab(); string prefabName = Utils.GetPrefabName(((Component)piece).gameObject); string prefabName2 = Utils.GetPrefabName(piecePrefab); if ((Object)(object)selectedPrefab != (Object)null && Utils.GetPrefabName(selectedPrefab) == prefabName2) { return true; } Debug.LogWarning((object)string.Format("[MoveBuildPieces] Isolated relocation selection failed: sourcePrefab={0}, canonicalPrefab={1}, sourceCategory={2}, selectedPrefab={3}", prefabName, prefabName2, (int)piece.m_category, ((Object)(object)selectedPrefab != (Object)null) ? Utils.GetPrefabName(selectedPrefab) : "")); RestoreBuildState(player, originalBuildPieces, tableObject); return false; } internal static bool IsTemporaryPieceTable(PieceTable table) { if ((Object)(object)table != (Object)null) { return (Object)(object)((Component)table).GetComponent() != (Object)null; } return false; } private static void SetSinglePieceAvailableList(PieceTable table, Piece piece) { if (!((Object)(object)table == (Object)null) && !((Object)(object)piece == (Object)null)) { List> list = new List>(); for (int i = 0; i < 8; i++) { list.Add(new List()); } list[0].Add(piece); PieceTableAvailablePiecesField?.SetValue(table, list); PieceTableSelectedCategoryField?.SetValue(table, (object)(PieceCategory)0); table.m_selectedPiece = (Vector2Int[])(object)new Vector2Int[8]; table.m_lastSelectedPiece = (Vector2Int[])(object)new Vector2Int[8]; } } private static PieceTable GetRelocatePieceTable(MoveState state) { if (!((Object)(object)state?.RelocateTableObject != (Object)null)) { return null; } return state.RelocateTableObject.GetComponent(); } private static GameObject GetPiecePrefab(Piece piece) { if ((Object)(object)piece == (Object)null) { return null; } ZNetView component = ((Component)piece).GetComponent(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); GameObject val2 = ((val != null && (Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(val.GetPrefab()) : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.GetComponent() != (Object)null) { return val2; } string prefabName = Utils.GetPrefabName(((Component)piece).gameObject); val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefabName) : null); if (!((Object)(object)val2 != (Object)null) || !((Object)(object)val2.GetComponent() != (Object)null)) { return ((Component)piece).gameObject; } return val2; } private static string GetCanonicalPiecePrefabName(Piece piece) { GameObject piecePrefab = GetPiecePrefab(piece); if (!((Object)(object)piecePrefab != (Object)null)) { return Utils.GetPrefabName(((Component)piece).gameObject); } return Utils.GetPrefabName(piecePrefab); } private static Piece FindWorldHoveringPiece(Player player) { //IL_00b6: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { return null; } int num = ((RemoveRayMaskField?.GetValue(player) is int num2) ? num2 : LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" })); object? obj = EyeField?.GetValue(player); Transform val = (Transform)((obj is Transform) ? obj : null); float num3 = ((MaxPlaceDistanceField?.GetValue(player) is float num4) ? num4 : 5f); Transform transform = ((Component)GameCamera.instance).transform; RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(transform.position, transform.forward, ref val2, 50f, num)) { return null; } if (Vector3.Distance(((Object)(object)val != (Object)null) ? val.position : ((Component)player).transform.position, ((RaycastHit)(ref val2)).point) >= num3) { return null; } if (!((Object)(object)((RaycastHit)(ref val2)).collider != (Object)null)) { return null; } return ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent(); } private static PieceTable GetBuildPieces(Player player) { object? obj = BuildPiecesField?.GetValue(player); return (PieceTable)((obj is PieceTable) ? obj : null); } private static void SetBuildPieces(Player player, PieceTable pieceTable) { BuildPiecesField?.SetValue(player, pieceTable); } private static void RestoreBuildState(Player player, PieceTable originalBuildPieces, GameObject relocateTableObject) { if ((Object)(object)player != (Object)null) { GameObject placementGhost = GetPlacementGhost(player); if ((Object)(object)placementGhost != (Object)null) { Object.Destroy((Object)(object)placementGhost); PlacementGhostField?.SetValue(player, null); } PieceTable val = originalBuildPieces ?? GetEquippedBuildToolPieceTable(player); SetBuildPieces(player, val); if ((Object)(object)val != (Object)null) { UpdateAvailablePiecesListMethod?.Invoke(player, Array.Empty()); } else { SetupPlacementGhostMethod?.Invoke(player, Array.Empty()); } } if ((Object)(object)relocateTableObject != (Object)null) { Object.Destroy((Object)(object)relocateTableObject); } } private static bool HasEquippedBuildTool(Player player) { return (Object)(object)GetEquippedBuildToolPieceTable(player) != (Object)null; } private static PieceTable GetEquippedBuildToolPieceTable(Player player) { if (player == null) { return null; } return ((Humanoid)player).RightItem?.m_shared?.m_buildPieces; } private static bool ValidateMoveTarget(Player player, Piece piece) { //IL_00b8: 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_00f6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || (Object)(object)player == (Object)null) { return false; } if (!piece.m_canBeRemoved) { Message(player, "$msg_cantremovenow"); return false; } ZNetView component = ((Component)piece).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Message(player, "$msg_invalidplacement"); return false; } long creator = piece.GetCreator(); long authoritativePieceCreator = GetAuthoritativePieceCreator(piece); if (creator != authoritativePieceCreator) { Debug.LogWarning((object)("[MoveBuildPieces] Piece creator cache mismatch; using authoritative ZDO data. " + DescribePieceNetworkState(piece, component, authoritativePieceCreator))); } if (authoritativePieceCreator == 0L) { Message(player, "Only player-built removable pieces can be moved"); Debug.LogWarning((object)("[MoveBuildPieces] Refused creatorless piece. " + DescribePieceNetworkState(piece, component, authoritativePieceCreator))); return false; } if (!HasLearnedMovePiece(player, piece)) { Message(player, "$msg_missingrequirement"); return false; } if (Location.IsInsideNoBuildLocation(((Component)piece).transform.position)) { Message(player, "$msg_nobuildzone"); return false; } if (!IsInsidePlayerBuildArea(((Component)piece).transform.position)) { Message(player, "$msg_nobuildzone"); return false; } if (!PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, true, false)) { Message(player, "$msg_privatezone"); return false; } if (!piece.CanBeRemoved()) { Message(player, "$msg_cantremovenow"); return false; } if (MoveBuildPiecesPlugin.BlockTerrainModifiers && HasTerrainMutation(piece)) { Message(player, "Pieces that modify terrain are blocked"); return false; } if (MoveBuildPiecesPlugin.BlockDynamicObjects && HasBlockedDynamicComponent(piece)) { Message(player, "Dynamic pieces are blocked"); return false; } if (HasNestedNetworkObject(piece)) { Message(player, "Pieces with nested network objects cannot be moved safely"); return false; } if (IsContainerInUse(piece)) { Message(player, "$msg_inuse"); return false; } if (HasAttachedPlayer(piece)) { Message(player, "$msg_inuse"); return false; } if (!CanMoveClaimedBed(player.GetPlayerID(), piece)) { Message(player, "Only the player who claimed this bed can move it"); return false; } return true; } private static bool IsAuthoritativePlayerBuiltPiece(Piece piece) { return GetAuthoritativePieceCreator(piece) != 0; } private static long GetAuthoritativePieceCreator(Piece piece) { if ((Object)(object)piece == (Object)null) { return 0L; } ZNetView component = ((Component)piece).GetComponent(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val == null) { return 0L; } return val.GetLong(ZDOVars.s_creator, 0L); } private static string DescribePieceNetworkState(Piece piece, ZNetView netView, long zdoCreator) { ZDO val = (((Object)(object)netView != (Object)null && netView.IsValid()) ? netView.GetZDO() : null); string text = (((Object)(object)piece != (Object)null) ? Utils.GetPrefabName(((Component)piece).gameObject) : ""); long num = (((Object)(object)piece != (Object)null) ? piece.GetCreator() : 0); long num2 = ((val != null) ? val.GetOwner() : 0); string text2 = ((val != null) ? ((object)Unsafe.As(ref val.m_uid)/*cast due to .constrained prefix*/).ToString() : ""); bool flag = (Object)(object)piece != (Object)null && piece.m_canBeRemoved; return $"prefab={text}, removable={flag}, cachedCreator={num}, zdoCreator={zdoCreator}, zdo={text2}, owner={num2}"; } private static bool CanGrantMoveLock(Player player, Piece piece, out string message) { //IL_0041: 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_0047: 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_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) message = "$msg_invalidplacement"; if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null || player.GetPlayerID() == 0L || !piece.m_canBeRemoved || !IsAuthoritativePlayerBuiltPiece(piece) || !piece.CanBeRemoved()) { return false; } Vector3 position = ((Component)piece).transform.position; if (!IsFinite(position) || Location.IsInsideNoBuildLocation(position) || !IsInsidePlayerBuildArea(position)) { return false; } if (!HasPlayerPrivateAreaAccess(position, player.GetPlayerID(), 0f, wardCheck: false) || !IsPlayerNearPiece(player, piece)) { message = "$msg_privatezone"; return false; } if (MoveBuildPiecesPlugin.BlockTerrainModifiers && HasTerrainMutation(piece)) { message = "Pieces that modify terrain are blocked"; return false; } if (MoveBuildPiecesPlugin.BlockDynamicObjects && HasBlockedDynamicComponent(piece)) { message = "Dynamic pieces are blocked"; return false; } if (HasNestedNetworkObject(piece) || HasAttachedPlayer(piece)) { message = "This piece contains world state that cannot be relocated safely"; return false; } if (IsContainerInUse(piece) || !CanMoveClaimedBed(player.GetPlayerID(), piece)) { message = "$msg_inuse"; return false; } message = ""; return true; } private static bool CanMoveClaimedBed(long playerId, Piece piece) { Bed obj = (((Object)(object)piece != (Object)null) ? ((Component)piece).GetComponentInChildren(true) : null); ZNetView val = (((Object)(object)piece != (Object)null) ? ((Component)piece).GetComponent() : null); if ((Object)(object)obj == (Object)null || (Object)(object)val == (Object)null || !val.IsValid()) { return true; } long num = val.GetZDO().GetLong(ZDOVars.s_owner, 0L); if (num != 0L) { return num == playerId; } return true; } private static bool IsPlayerNearPiece(Player player, Piece piece) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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) if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { return false; } object? obj = EyeField?.GetValue(player); Transform val = (Transform)((obj is Transform) ? obj : null); Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : ((Component)player).transform.position); float allowedMoveDistance = GetAllowedMoveDistance(player, piece); float num = Vector3.Distance(val2, ((Component)piece).transform.position); Collider[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (Collider val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null) && val3.enabled && !val3.isTrigger && ((Component)val3).gameObject.activeInHierarchy && TryGetProximityPoint(val3, val2, out var closestPoint)) { num = Mathf.Min(num, Vector3.Distance(val2, closestPoint)); } } return num <= allowedMoveDistance; } private static bool IsPlayerNearTarget(Player player, Piece piece, Vector3 targetPosition) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { return false; } object? obj = EyeField?.GetValue(player); Transform val = (Transform)((obj is Transform) ? obj : null); Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : ((Component)player).transform.position); float num = Mathf.Clamp(GetRingRadius(((Component)piece).gameObject), 0f, 8f); return Vector3.Distance(val2, targetPosition) <= GetAllowedMoveDistance(player, piece) + num; } private static float GetAllowedMoveDistance(Player player, Piece piece) { float num = ((MaxPlaceDistanceField?.GetValue(player) is float num2) ? num2 : 5f); return Mathf.Max(1f, num + (float)Mathf.Max(0, piece.m_extraPlacementDistance)); } private static bool HasPlayerPrivateAreaAccess(Vector3 point, long playerId, float radius, bool wardCheck) { //IL_0054: 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) if (playerId == 0L || !(PrivateAreasField?.GetValue(null) is List list)) { return false; } bool flag = false; bool flag2 = false; bool flag4 = default(bool); for (int i = 0; i < list.Count; i++) { PrivateArea val = list[i]; if ((Object)(object)val == (Object)null || !IsPrivateAreaEnabled(val) || Utils.DistanceXZ(((Component)val).transform.position, point) >= val.m_radius + radius) { continue; } Piece component = ((Component)val).GetComponent(); bool flag3 = (Object)(object)component != (Object)null && component.GetCreator() == playerId; if (!flag3 && PrivateAreaIsPermittedMethod != null) { try { object obj = PrivateAreaIsPermittedMethod.Invoke(val, new object[1] { playerId }); int num; if (obj is bool) { flag4 = (bool)obj; num = 1; } else { num = 0; } flag3 = (byte)((uint)num & (flag4 ? 1u : 0u)) != 0; } catch { return false; } } if (wardCheck && !flag3) { return false; } flag = flag || flag3; flag2 = flag2 || !flag3; } if (!(wardCheck || flag)) { return !flag2; } return true; } private static bool IsPrivateAreaEnabled(PrivateArea area) { if ((Object)(object)area == (Object)null || PrivateAreaIsEnabledMethod == null) { return true; } try { object obj = PrivateAreaIsEnabledMethod.Invoke(area, Array.Empty()); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return num == 0 || flag; } catch { return true; } } private static bool HasTerrainMutation(Piece piece) { if (!((Object)(object)((Component)piece).GetComponentInChildren(true) != (Object)null)) { return (Object)(object)((Component)piece).GetComponentInChildren(true) != (Object)null; } return true; } private static bool HasBlockedDynamicComponent(Piece piece) { if ((Object)(object)((Component)piece).GetComponentInChildren(true) != (Object)null || (Object)(object)((Component)piece).GetComponentInChildren(true) != (Object)null || (Object)(object)((Component)piece).GetComponentInChildren(true) != (Object)null || (Object)(object)((Component)piece).GetComponentInChildren(true) != (Object)null) { return true; } Rigidbody[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (Rigidbody val in componentsInChildren) { if ((Object)(object)val != (Object)null && !val.isKinematic) { return true; } } return false; } private static bool HasNestedNetworkObject(Piece piece) { ZNetView val = (((Object)(object)piece != (Object)null) ? ((Component)piece).GetComponent() : null); if ((Object)(object)piece == (Object)null) { return false; } ZNetView[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (ZNetView val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)val && val2.IsValid()) { return true; } } return false; } private static bool IsContainerInUse(Piece piece) { Container[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (Container val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.IsInUse()) { return true; } } return false; } private static bool HasAttachedPlayer(Piece piece) { if ((Object)(object)piece == (Object)null) { return false; } List allPlayers = Player.GetAllPlayers(); for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; Transform val2 = (((Object)(object)val != (Object)null && ((Character)val).IsAttached()) ? val.GetAttachPoint() : null); if ((Object)(object)val2 != (Object)null && ((Object)(object)val2 == (Object)(object)((Component)piece).transform || val2.IsChildOf(((Component)piece).transform))) { return true; } } return false; } private static bool IsInsidePlayerBuildArea(Vector3 point) { //IL_0000: 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) if (IsFinite(point)) { return (Object)(object)EffectArea.IsPointInsideArea(point, (Type)4, 0.05f) != (Object)null; } return false; } private static List GetPlayerBuildAreasAt(Vector3 point) { //IL_0006: 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) List list = new List(); if (!IsFinite(point)) { return list; } List allAreas = EffectArea.GetAllAreas(); for (int i = 0; i < allAreas.Count; i++) { EffectArea val = allAreas[i]; if (IsPointInsidePlayerBuildArea(val, point)) { list.Add(val); } } return list; } private static bool IsInsideOriginalBuildArea(MoveState state, Vector3 point) { //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) if (state?.OriginalBuildAreas == null || !IsFinite(point)) { return false; } for (int i = 0; i < state.OriginalBuildAreas.Count; i++) { if (IsPointInsidePlayerBuildArea(state.OriginalBuildAreas[i], point)) { return true; } } return false; } private static bool IsPointInsidePlayerBuildArea(EffectArea area, Vector3 point) { //IL_001f: 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_006a: 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_0075: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)area == (Object)null || !((Behaviour)area).enabled || !((Component)area).gameObject.activeInHierarchy || (area.m_type & 4) == 0) { return false; } Piece componentInParent = ((Component)area).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && Player.IsPlacementGhost(((Component)componentInParent).gameObject)) { return false; } object? obj = EffectAreaColliderField?.GetValue(area); if (TryGetProximityPoint((Collider)(((obj is Collider) ? obj : null) ?? ((Component)area).GetComponent()), point, out var closestPoint)) { return Vector3.Distance(closestPoint, point) <= 0.1f; } return false; } private static bool HasLearnedMovePiece(Player player, Piece piece) { if (!MoveBuildPiecesPlugin.RequireKnownPiece) { return true; } if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { return false; } if (IsKnownPieceName(player, piece.m_name)) { return true; } Piece component = GetPiecePrefab(piece).GetComponent(); if ((Object)(object)component != (Object)null) { return IsKnownPieceName(player, component.m_name); } return false; } private static bool IsKnownPieceName(Player player, string pieceName) { if (!string.IsNullOrWhiteSpace(pieceName)) { return player.IsRecipeKnown(pieceName); } return false; } private static bool TryGetProximityPoint(Collider collider, Vector3 point, out Vector3 closestPoint) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_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_0071: Unknown result type (might be due to invalid IL or missing references) closestPoint = point; if ((Object)(object)collider == (Object)null || !collider.enabled || !((Component)collider).gameObject.activeInHierarchy || !IsFinite(point)) { return false; } if (SupportsPhysicsClosestPoint(collider)) { closestPoint = collider.ClosestPoint(point); return IsFinite(closestPoint); } Bounds bounds = collider.bounds; if (!IsUsefulBounds(bounds, hasBounds: true)) { return false; } closestPoint = ((Bounds)(ref bounds)).ClosestPoint(point); return IsFinite(closestPoint); } private static bool SupportsPhysicsClosestPoint(Collider collider) { if (collider is BoxCollider || collider is SphereCollider || collider is CapsuleCollider) { return true; } MeshCollider val = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if (val != null) { return val.convex; } return false; } private static bool RequestMovePiece(MoveState state, Vector3 targetPosition, Quaternion targetRotation, out bool completedImmediately) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) completedImmediately = false; ZNetView netView = state.NetView; if (!HasVerifiedServerProtocol() || !NetworkMovesEnabled || (Object)(object)netView == (Object)null || !netView.IsValid() || (Object)(object)state.Piece == (Object)null || !IsFinite(targetPosition) || !IsValidRotation(targetRotation)) { return false; } if (netView.IsOwner()) { if (!ApplyOwnerMove(netView, state.Piece, state.Player, state.OriginalPosition, targetPosition, targetRotation, state.LockPeerId, state.LockPlayerId, state.LockToken)) { return false; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ClearMoveLock(netView, state.LockPeerId, state.LockPlayerId, state.LockToken); completedImmediately = true; return true; } state.MoveRequestOwnerPeerId = ZDOMan.GetSessionID(); state.MoveRequestStartedAt = Time.realtimeSinceStartup; state.FirstMoveRequestStartedAt = state.MoveRequestStartedAt; state.MoveRequestAttempts = 1; state.WaitingForMoveResult = true; RequestServerMoveVerification(state, force: true); return true; } if (!netView.HasOwner()) { return false; } state.MoveRequestOwnerPeerId = netView.GetZDO().GetOwner(); if (state.MoveRequestOwnerPeerId == 0L) { return false; } state.MoveRequestStartedAt = Time.realtimeSinceStartup; if (state.FirstMoveRequestStartedAt <= 0f) { state.FirstMoveRequestStartedAt = state.MoveRequestStartedAt; } state.MoveRequestAttempts++; state.WaitingForMoveResult = true; InvokePieceRpc(netView, state.MoveRequestOwnerPeerId, "MoveBuildPiecesV4_Move", state.LockPlayerId, state.LockToken, targetPosition, targetRotation); return true; } private static bool TryResolveCommittedMove(MoveState state) { //IL_007c: 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_008c: 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_00be: 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_00db: 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) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return false; } if (!IsCommittedMove(((Object)(object)state?.NetView != (Object)null && state.NetView.IsValid()) ? state.NetView.GetZDO() : null, state?.LockPeerId ?? 0, state?.LockPlayerId ?? 0, state?.LockToken ?? 0, state?.PendingTargetPosition ?? Vector3.zero, state?.PendingTargetRotation ?? Quaternion.identity)) { return false; } ReleaseMoveLock(state.NetView, state.LockPlayerId, state.LockToken, state.LockOwnerPeerId); ApplyVisualMoveLocally(state.NetView, state.PendingTargetPosition, state.PendingTargetRotation); FinishSuccessfulMove(state.Player, state.Piece, state.PendingTargetPosition, state.PendingTargetRotation); return true; } private static bool HasVerifiedServerProtocol() { if ((Object)(object)ZNet.instance != (Object)null) { if (!ZNet.instance.IsServer()) { return IsServerCapabilityCurrent(); } return true; } return false; } private static bool IsServerCapabilityCurrent() { if (_serverCapabilityConfirmed && _lastServerPolicyAckAt > 0f) { return Time.realtimeSinceStartup - _lastServerPolicyAckAt <= 12f; } return false; } internal static bool ResolveRequireKnownPiece(bool localValue) { if (!UseServerPolicy()) { return localValue; } return _serverPolicyRequireKnownPiece; } internal static bool ResolveBlockTerrainModifiers(bool localValue) { if (!UseServerPolicy()) { return localValue; } return _serverPolicyBlockTerrainModifiers; } internal static bool ResolveBlockDynamicObjects(bool localValue) { if (!UseServerPolicy()) { return localValue; } return _serverPolicyBlockDynamicObjects; } internal static float ResolveMoveLockTimeout(float localValue) { if (!UseServerPolicy()) { return localValue; } return _serverPolicyMoveLockTimeoutSeconds; } private static bool UseServerPolicy() { if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { return IsServerCapabilityCurrent(); } return false; } private static void RequestServerMoveVerification(MoveState state, bool force = false) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (state != null && state.WaitingForMoveResult && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && IsServerCapabilityCurrent() && _serverRpc != null && _serverRpc.IsConnected() && (force || !(Time.realtimeSinceStartup - state.LastServerVerifyRequestAt < 0.5f))) { ZDO val = (((Object)(object)state.NetView != (Object)null && state.NetView.IsValid()) ? state.NetView.GetZDO() : null); if (val != null) { state.LastServerVerifyRequestAt = Time.realtimeSinceStartup; ZPackage val2 = new ZPackage(); val2.Write(val.m_uid); val2.Write(state.LockPlayerId); val2.Write(state.LockToken); val2.Write(state.PendingTargetPosition); val2.Write(state.PendingTargetRotation); _serverRpc.Invoke("MoveBuildPiecesV4_ServerVerifyMove", new object[1] { val2 }); } } } private static bool TryRetryMoveAfterOwnerChange(MoveState state) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)state?.NetView == (Object)null || !state.NetView.IsValid() || state.MoveRequestAttempts >= 3 || Time.realtimeSinceStartup - state.MoveRequestStartedAt < 1.5f) { return false; } ZDO zDO = state.NetView.GetZDO(); long num = ((zDO != null) ? zDO.GetOwner() : 0); if (num == 0L || num == state.MoveRequestOwnerPeerId) { return false; } state.MoveRequestOwnerPeerId = num; state.MoveRequestStartedAt = Time.realtimeSinceStartup; state.MoveRequestAttempts++; state.MoveFailureReceivedAt = 0f; state.MoveFailureMessage = null; InvokePieceRpc(state.NetView, num, "MoveBuildPiecesV4_Move", state.LockPlayerId, state.LockToken, state.PendingTargetPosition, state.PendingTargetRotation); return true; } private static void ApplyMoveRpc(ZNetView netView, long sender, long playerId, long lockToken, Vector3 targetPosition, Quaternion targetRotation) { //IL_0033: 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_0082: 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_0087: 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_00aa: 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_00b1: Unknown result type (might be due to invalid IL or missing references) if (!NetworkMovesEnabled || !HasVerifiedServerProtocol() || (Object)(object)netView == (Object)null || !netView.IsValid() || !netView.IsOwner()) { return; } ZDO zDO = netView.GetZDO(); if (IsCommittedMove(zDO, sender, playerId, lockToken, targetPosition, targetRotation)) { SendMoveResult(netView, sender, success: true, "", lockToken); return; } Piece component = ((Component)netView).GetComponent(); if (!TryGetAuthenticatedPlayer(sender, playerId, out var player) || !HasMatchingMoveLock(zDO, sender, playerId, lockToken) || !CanApplyOwnerMove(component, player, ((Object)(object)component != (Object)null) ? ((Component)component).transform.position : Vector3.zero, targetPosition, targetRotation)) { SendMoveResult(netView, sender, success: false, "$msg_invalidplacement", lockToken); return; } bool flag = ApplyOwnerMove(netView, component, player, ((Component)component).transform.position, targetPosition, targetRotation, sender, playerId, lockToken); SendMoveResult(netView, sender, flag, flag ? "" : "$msg_invalidplacement", lockToken); } private static void SendMoveResult(ZNetView netView, long sender, bool success, string message, long lockToken) { if ((Object)(object)netView != (Object)null && netView.IsValid() && sender != 0L && lockToken != 0L) { InvokePieceRpc(netView, sender, "MoveBuildPiecesV4_MoveResult", success, message ?? "", lockToken); } } private static void ApplyMoveResultRpc(ZNetView netView, long sender, bool success, string message, long lockToken) { if (_state == null || (Object)(object)_state.NetView != (Object)(object)netView || !_state.WaitingForMoveResult || _state.LockToken != lockToken || _state.MoveRequestOwnerPeerId != sender) { return; } Player player = _state.Player; if (!success) { if (!TryResolveCommittedMove(_state)) { _state.MoveFailureMessage = (string.IsNullOrEmpty(message) ? "$msg_invalidplacement" : message); _state.MoveFailureReceivedAt = Time.realtimeSinceStartup; } } else { Message(player, "Waiting for server confirmation"); } } private static bool CanApplyOwnerMove(Piece piece, Player player, Vector3 sourcePosition, Vector3 targetPosition, Quaternion targetRotation) { //IL_002a: 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_003a: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_00b4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || (Object)(object)player == (Object)null || !piece.m_canBeRemoved || !IsAuthoritativePlayerBuiltPiece(piece) || !piece.CanBeRemoved() || !IsFinite(sourcePosition) || !IsFinite(targetPosition) || !IsValidRotation(targetRotation)) { return false; } if (Location.IsInsideNoBuildLocation(sourcePosition) || Location.IsInsideNoBuildLocation(targetPosition) || !IsInsidePlayerBuildArea(sourcePosition) || !IsInsidePlayerBuildArea(targetPosition)) { return false; } PrivateArea componentInChildren = ((Component)piece).GetComponentInChildren(true); float radius = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.m_radius : 0f); bool wardCheck = (Object)(object)componentInChildren != (Object)null; if (!HasPlayerPrivateAreaAccess(sourcePosition, player.GetPlayerID(), 0f, wardCheck: false) || !HasPlayerPrivateAreaAccess(targetPosition, player.GetPlayerID(), radius, wardCheck) || !IsPlayerNearTarget(player, piece, targetPosition)) { return false; } if (MoveBuildPiecesPlugin.BlockTerrainModifiers && HasTerrainMutation(piece)) { return false; } if (MoveBuildPiecesPlugin.BlockDynamicObjects && HasBlockedDynamicComponent(piece)) { return false; } if (!HasNestedNetworkObject(piece) && !IsContainerInUse(piece) && !HasAttachedPlayer(piece)) { return CanMoveClaimedBed(player.GetPlayerID(), piece); } return false; } private static bool ApplyOwnerMove(ZNetView netView, Piece piece, Player player, Vector3 originalPosition, Vector3 targetPosition, Quaternion targetRotation, long senderPeerId, long playerId, long lockToken) { //IL_0268: 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_0049: 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_004c: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0082: 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) //IL_0171: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: 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_0244: 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) if (!HasVerifiedServerProtocol() || !NetworkMovesEnabled || (Object)(object)netView == (Object)null || !netView.IsValid() || !netView.IsOwner() || (Object)(object)piece == (Object)null) { return false; } ZDO zDO = netView.GetZDO(); if (!HasMatchingMoveLock(zDO, senderPeerId, playerId, lockToken) || !CanApplyOwnerMove(piece, player, originalPosition, targetPosition, targetRotation)) { return false; } Transform transform = ((Component)piece).transform; OwnerMoveSnapshot ownerMoveSnapshot; try { ownerMoveSnapshot = new OwnerMoveSnapshot { TransformPosition = transform.position, TransformRotation = transform.rotation, ZdoPosition = zDO.GetPosition(), ZdoRotation = zDO.GetRotation(), LastMoveToken = zDO.GetLong(LastMoveTokenHash, 0L), LastMovePeer = zDO.GetLong(LastMovePeerHash, 0L), LastMovePlayer = zDO.GetLong(LastMovePlayerHash, 0L), LockOwner = zDO.GetLong(LockOwnerHash, 0L), LockPeer = zDO.GetLong(LockPeerHash, 0L), LockToken = zDO.GetLong(LockTokenHash, 0L), LockUntil = zDO.GetLong(LockUntilHash, 0L), LockName = zDO.GetString(LockNameHash, ""), RigidbodyStates = CaptureRigidbodyStates(piece), ComponentFields = CaptureRelocationFieldValues(piece) }; } catch (Exception ex) { Debug.LogWarning((object)("[MoveBuildPieces] Failed to capture the owner move transaction: " + ex.GetBaseException().Message)); return false; } bool flag = false; try { ClearSupportCachesNear(ownerMoveSnapshot.TransformPosition, broadcast: true); transform.SetPositionAndRotation(targetPosition, targetRotation); SetRigidbodiesStill(piece, targetPosition, targetRotation); Physics.SyncTransforms(); if (!RefreshWearNTearAfterMove(piece) || !HasStructuralSupportAfterMove(piece)) { RollbackOwnerMove(netView, piece, zDO, ownerMoveSnapshot, targetPosition); return false; } zDO.SetPosition(targetPosition); zDO.SetRotation(targetRotation); zDO.Set(LastMoveTokenHash, lockToken); zDO.Set(LastMovePeerHash, senderPeerId); zDO.Set(LastMovePlayerHash, playerId); ResetMovedComponentReferences(piece, ownerMoveSnapshot.TransformPosition); flag = true; ZSyncTransform component = ((Component)netView).GetComponent(); if ((Object)(object)component != (Object)null) { transform.hasChanged = true; component.SyncNow(); } InvokePieceRpc(netView, ZRoutedRpc.Everybody, "MoveBuildPiecesV4_ApplyVisual", lockToken, targetPosition, targetRotation); ClearSupportCachesNear(targetPosition, broadcast: true); return true; } catch (Exception ex2) { if (!flag) { RollbackOwnerMove(netView, piece, zDO, ownerMoveSnapshot, targetPosition); } else { try { ClearSupportCachesNear(targetPosition, broadcast: true); } catch { } } Debug.LogWarning((object)("[MoveBuildPieces] Owner move transaction failed: " + ex2.GetBaseException().Message)); return flag; } } private static void RollbackOwnerMove(ZNetView netView, Piece piece, ZDO zdo, OwnerMoveSnapshot snapshot, Vector3 attemptedPosition) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)netView != (Object)null && netView.IsValid() && netView.IsOwner() && zdo != null) { zdo.SetPosition(snapshot.ZdoPosition); zdo.SetRotation(snapshot.ZdoRotation); zdo.Set(LastMoveTokenHash, snapshot.LastMoveToken); zdo.Set(LastMovePeerHash, snapshot.LastMovePeer); zdo.Set(LastMovePlayerHash, snapshot.LastMovePlayer); zdo.Set(LockOwnerHash, snapshot.LockOwner); zdo.Set(LockPeerHash, snapshot.LockPeer); zdo.Set(LockTokenHash, snapshot.LockToken); zdo.Set(LockUntilHash, snapshot.LockUntil); zdo.Set(LockNameHash, snapshot.LockName ?? ""); ZDOMan instance = ZDOMan.instance; if (instance != null) { instance.ForceSendZDO(zdo.m_uid); } } } catch { } try { ((Component)piece).transform.SetPositionAndRotation(snapshot.TransformPosition, snapshot.TransformRotation); SetRigidbodiesStill(piece, snapshot.TransformPosition, snapshot.TransformRotation); Physics.SyncTransforms(); } catch { } try { ResetMovedComponentReferences(piece, attemptedPosition); } catch { } try { RefreshWearNTearAfterMove(piece); } catch { } try { HasStructuralSupportAfterMove(piece); } catch { } try { RestoreRelocationFieldValues(snapshot.ComponentFields); RestoreRigidbodyStates(snapshot.RigidbodyStates); Physics.SyncTransforms(); } catch { } try { ClearSupportCachesNear(snapshot.TransformPosition, broadcast: true); } catch { } try { ClearSupportCachesNear(attemptedPosition, broadcast: true); } catch { } } private static void ApplyVisualMoveRpc(ZNetView netView, long sender, long lockToken, Vector3 targetPosition, Quaternion targetRotation) { //IL_0025: 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_005b: 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_009b: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (HasVerifiedServerProtocol() && NetworkMovesEnabled && !((Object)(object)netView == (Object)null) && netView.IsValid() && sender != 0L && lockToken != 0L && IsFinite(targetPosition) && IsValidRotation(targetRotation)) { ZDO zDO = netView.GetZDO(); if (zDO != null && zDO.GetOwner() == sender && zDO.GetLong(LastMoveTokenHash, 0L) == lockToken && Vector3.Distance(zDO.GetPosition(), targetPosition) <= 0.05f && Quaternion.Angle(zDO.GetRotation(), targetRotation) <= 0.5f && (!netView.IsOwner() || sender != ZDOMan.GetSessionID())) { ApplyVisualMoveLocally(netView, targetPosition, targetRotation); } } } private static bool HasMatchingMoveLock(ZDO zdo, long senderPeerId, long playerId, long lockToken) { if (zdo != null && senderPeerId != 0L && playerId != 0L && lockToken != 0L && zdo.GetLong(LockOwnerHash, 0L) == playerId && zdo.GetLong(LockPeerHash, 0L) == senderPeerId && zdo.GetLong(LockTokenHash, 0L) == lockToken) { return zdo.GetLong(LockUntilHash, 0L) > SecondsToMillis(GetNetworkTimeSeconds()); } return false; } private static bool IsCommittedMove(ZDO zdo, long senderPeerId, long playerId, long lockToken, Vector3 targetPosition, Quaternion targetRotation) { //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_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) if (zdo != null && senderPeerId != 0L && playerId != 0L && lockToken != 0L && zdo.GetLong(LastMoveTokenHash, 0L) == lockToken && zdo.GetLong(LastMovePeerHash, 0L) == senderPeerId && zdo.GetLong(LastMovePlayerHash, 0L) == playerId && Vector3.Distance(zdo.GetPosition(), targetPosition) <= 0.05f) { return Quaternion.Angle(zdo.GetRotation(), targetRotation) <= 0.5f; } return false; } private static void ApplyVisualMoveLocally(ZNetView netView, Vector3 targetPosition, Quaternion targetRotation) { //IL_001c: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Piece val = (((Object)(object)netView != (Object)null) ? ((Component)netView).GetComponent() : null); if (!((Object)(object)val == (Object)null) && IsFinite(targetPosition) && IsValidRotation(targetRotation)) { Vector3 position = ((Component)val).transform.position; ClearSupportCachesNear(position, broadcast: false); ((Component)val).transform.SetPositionAndRotation(targetPosition, targetRotation); SetRigidbodiesStill(val, targetPosition, targetRotation); Physics.SyncTransforms(); RefreshWearNTearAfterMove(val); ResetMovedComponentReferences(val, position); ClearSupportCachesNear(targetPosition, broadcast: false); } } private static bool RefreshWearNTearAfterMove(Piece piece) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null) { return false; } WearNTear[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { return true; } WearNTear[] array = componentsInChildren; foreach (WearNTear val in array) { if ((Object)(object)val == (Object)null) { continue; } try { ClearLocalSupportCacheMethod?.Invoke(val, Array.Empty()); if (WearNTearConnectedHeightmapField != null && HeightmapSupportCacheEvent != null && ClearLocalSupportCacheMethod != null) { object? value = WearNTearConnectedHeightmapField.GetValue(val); Heightmap val2 = (Heightmap)((value is Heightmap) ? value : null); Heightmap val3 = Heightmap.FindHeightmap(((Component)val).transform.position); if ((Object)(object)val2 != (Object)(object)val3) { Action handler = (Action)Delegate.CreateDelegate(typeof(Action), val, ClearLocalSupportCacheMethod); if ((Object)(object)val2 != (Object)null) { HeightmapSupportCacheEvent.RemoveEventHandler(val2, handler); } if ((Object)(object)val3 != (Object)null) { HeightmapSupportCacheEvent.AddEventHandler(val3, handler); } WearNTearConnectedHeightmapField.SetValue(val, val3); } } WearNTearCollidersField?.SetValue(val, null); WearNTearBoundsField?.SetValue(val, null); WearNTearClearCachedSupportField?.SetValue(val, true); WearNTearRoofField?.SetValue(val, null); WearNTearAshRoofField?.SetValue(val, null); WearNTearBiomeField?.SetValue(val, (object)(Biome)0); WearNTearHeightmapField?.SetValue(val, null); WearNTearGroundDistanceField?.SetValue(val, 0f); WearNTearInAshlandsField?.SetValue(val, false); WearNTearLavaValueField?.SetValue(val, 0f); WearNTearLavaTimerField?.SetValue(val, 0f); WearNTearAshTimerField?.SetValue(val, 0f); WearNTearRainTimerField?.SetValue(val, 0f); WearNTearUpdateCoverTimerField?.SetValue(val, 4f); WearNTearHaveRoofField?.SetValue(val, true); WearNTearHaveAshRoofField?.SetValue(val, true); WearNTearShieldChangeIdField?.SetValue(val, -1); WearNTearPreviousWaterVolumeField?.SetValue(val, null); } catch { return false; } } return true; } private static void ResetMovedComponentReferences(Piece piece, Vector3 previousPosition) { //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null) { return; } SapCollector[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (SapCollector val in componentsInChildren) { if ((Object)(object)val != (Object)null) { SapCollectorRootField?.SetValue(val, null); SapCollectorConnectedObjectField?.SetValue(val, null); } } ShieldGenerator[] componentsInChildren2 = ((Component)piece).GetComponentsInChildren(true); foreach (ShieldGenerator val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { ShieldGeneratorRadiusSentField?.SetValue(val2, float.NegativeInfinity); } } Fireplace[] componentsInChildren3 = ((Component)piece).GetComponentsInChildren(true); foreach (Fireplace val3 in componentsInChildren3) { if ((Object)(object)val3 != (Object)null) { FireplaceBiomeField?.SetValue(val3, (object)(Biome)0); } } CinderSpawner[] componentsInChildren4 = ((Component)piece).GetComponentsInChildren(true); foreach (CinderSpawner val4 in componentsInChildren4) { if ((Object)(object)val4 != (Object)null) { CinderSpawnerBiomeField?.SetValue(val4, (object)(Biome)0); } } ZNetView component = ((Component)piece).GetComponent(); StaticRotation[] componentsInChildren5 = ((Component)piece).GetComponentsInChildren(true); foreach (StaticRotation val5 in componentsInChildren5) { if ((Object)(object)val5 == (Object)null) { continue; } Quaternion rotation = ((Component)val5).transform.rotation; float y = ((Quaternion)(ref rotation)).eulerAngles.y; StaticRotationValueField?.SetValue(val5, y); if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner()) { ZDO zDO = component.GetZDO(); if (zDO != null) { zDO.Set(ZDOVars.s_tiltrot, y); } } } RefreshCraftingStationCaches(piece, previousPosition); RefreshEffectAreaCaches(piece); RefreshPrivateAreaCaches(piece); } private static void RefreshCraftingStationCaches(Piece piece, Vector3 previousPosition) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece == (Object)null || !(CraftingStationsField?.GetValue(null) is List list)) { return; } CraftingStation componentInChildren = ((Component)piece).GetComponentInChildren(true); StationExtension componentInChildren2 = ((Component)piece).GetComponentInChildren(true); for (int i = 0; i < list.Count; i++) { CraftingStation val = list[i]; if ((Object)(object)val == (Object)null) { continue; } bool flag = (Object)(object)val == (Object)(object)componentInChildren; if (!flag && (Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.m_craftingStation != (Object)null && val.m_name == componentInChildren2.m_craftingStation.m_name) { float maxStationDistance = componentInChildren2.m_maxStationDistance; flag = Vector3.Distance(((Component)val).transform.position, previousPosition) < maxStationDistance || Vector3.Distance(((Component)val).transform.position, ((Component)componentInChildren2).transform.position) < maxStationDistance; } if (flag) { try { CraftingStationExtensionTimerField?.SetValue(val, 2f); val.GetStationBuildRange(); } catch { } } } if (!(StationExtensionsField?.GetValue(null) is List list2)) { return; } for (int j = 0; j < list2.Count; j++) { StationExtension val2 = list2[j]; if (!((Object)(object)val2 == (Object)null)) { bool flag2 = (Object)(object)val2 == (Object)(object)componentInChildren2; if (!flag2 && (Object)(object)componentInChildren != (Object)null && (Object)(object)val2.m_craftingStation != (Object)null && val2.m_craftingStation.m_name == componentInChildren.m_name) { flag2 = Vector3.Distance(((Component)val2).transform.position, previousPosition) < val2.m_maxStationDistance || Vector3.Distance(((Component)val2).transform.position, ((Component)componentInChildren).transform.position) < val2.m_maxStationDistance; } if (flag2) { val2.StopConnectionEffect(); } } } } private static void RefreshEffectAreaCaches(Piece piece) { //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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) EffectArea[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (EffectArea val in componentsInChildren) { Collider val2 = (Collider)(((Object)(object)val != (Object)null) ? (((object)/*isinst with value type is only supported in some contexts*/) ?? ((object)((Component)val).GetComponent())) : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { Bounds bounds = val2.bounds; if ((val.m_type & 0x20) != 0) { ReplaceEffectAreaBounds(val, bounds, EffectAreaNoMonsterAreaField, EffectAreaNoMonsterAreasField); ((Bounds)(ref bounds)).Expand(new Vector3(15f, 15f, 15f)); ReplaceEffectAreaBounds(val, bounds, EffectAreaNoMonsterCloseAreaField, EffectAreaNoMonsterCloseAreasField); } if ((val.m_type & 8) != 0) { Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds2)).Expand(new Vector3(0.25f, 0.25f, 0.25f)); ReplaceEffectAreaBounds(val, bounds2, EffectAreaBurnCloseAreaField, EffectAreaBurningAreasField); } } } } private static void ReplaceEffectAreaBounds(EffectArea area, Bounds bounds, FieldInfo instanceField, FieldInfo listField) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)area == (Object)null || instanceField == null || !(listField?.GetValue(null) is List> list)) { return; } KeyValuePair keyValuePair = new KeyValuePair(bounds, area); instanceField.SetValue(area, keyValuePair); for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i].Value == (Object)(object)area) { list[i] = keyValuePair; return; } } if (((Behaviour)area).isActiveAndEnabled) { list.Add(keyValuePair); } } private static void RefreshPrivateAreaCaches(Piece piece) { if ((Object)(object)((Component)piece).GetComponentInChildren(true) == (Object)null || !(PrivateAreasField?.GetValue(null) is List list)) { return; } for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i] != (Object)null) { PrivateAreaConnectionUpdateTimeField?.SetValue(list[i], -1000f); } } } private static bool HasStructuralSupportAfterMove(Piece piece) { if ((Object)(object)piece == (Object)null) { return false; } bool flag = false; WearNTear[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (WearNTear val in componentsInChildren) { if ((Object)(object)val == (Object)null || !val.m_noSupportWear) { continue; } flag = true; if (UpdateSupportMethod == null || HaveSupportMethod == null) { return false; } try { UpdateSupportMethod.Invoke(val, Array.Empty()); object obj = HaveSupportMethod.Invoke(val, Array.Empty()); if (obj is bool && !(bool)obj) { return false; } } catch { return false; } } if (flag) { if (UpdateSupportMethod != null) { return HaveSupportMethod != null; } return false; } return true; } private static List CaptureRigidbodyStates(Piece piece) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) List list = new List(); if ((Object)(object)piece == (Object)null) { return list; } Rigidbody[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (Rigidbody val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Vector3 linearVelocity = Vector3.zero; try { PropertyInfo rigidbodyLinearVelocityProperty = RigidbodyLinearVelocityProperty; if ((object)rigidbodyLinearVelocityProperty != null && rigidbodyLinearVelocityProperty.CanRead && RigidbodyLinearVelocityProperty.GetValue(val, null) is Vector3 val2) { linearVelocity = val2; } } catch { } list.Add(new RigidbodySnapshot { Body = val, Position = val.position, Rotation = val.rotation, LinearVelocity = linearVelocity, AngularVelocity = val.angularVelocity }); } return list; } private static void RestoreRigidbodyStates(List snapshots) { //IL_002b: 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_004d: 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) if (snapshots == null) { return; } for (int i = 0; i < snapshots.Count; i++) { RigidbodySnapshot rigidbodySnapshot = snapshots[i]; if (!((Object)(object)rigidbodySnapshot?.Body == (Object)null)) { rigidbodySnapshot.Body.position = rigidbodySnapshot.Position; rigidbodySnapshot.Body.rotation = rigidbodySnapshot.Rotation; SetLinearVelocity(rigidbodySnapshot.Body, rigidbodySnapshot.LinearVelocity); rigidbodySnapshot.Body.angularVelocity = rigidbodySnapshot.AngularVelocity; } } } private static List CaptureRelocationFieldValues(Piece piece) { List list = new List(); if ((Object)(object)piece == (Object)null) { return list; } WearNTear[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (WearNTear target in componentsInChildren) { for (int j = 0; j < WearNTearRelocationFields.Length; j++) { CaptureFieldValue(list, target, WearNTearRelocationFields[j]); } } SapCollector[] componentsInChildren2 = ((Component)piece).GetComponentsInChildren(true); foreach (SapCollector target2 in componentsInChildren2) { CaptureFieldValue(list, target2, SapCollectorRootField); CaptureFieldValue(list, target2, SapCollectorConnectedObjectField); } ShieldGenerator[] componentsInChildren3 = ((Component)piece).GetComponentsInChildren(true); foreach (ShieldGenerator target3 in componentsInChildren3) { CaptureFieldValue(list, target3, ShieldGeneratorRadiusSentField); } Fireplace[] componentsInChildren4 = ((Component)piece).GetComponentsInChildren(true); foreach (Fireplace target4 in componentsInChildren4) { CaptureFieldValue(list, target4, FireplaceBiomeField); } CinderSpawner[] componentsInChildren5 = ((Component)piece).GetComponentsInChildren(true); foreach (CinderSpawner target5 in componentsInChildren5) { CaptureFieldValue(list, target5, CinderSpawnerBiomeField); } StaticRotation[] componentsInChildren6 = ((Component)piece).GetComponentsInChildren(true); foreach (StaticRotation target6 in componentsInChildren6) { CaptureFieldValue(list, target6, StaticRotationValueField); } return list; } private static void CaptureFieldValue(List snapshots, object target, FieldInfo field) { if (snapshots == null || target == null || field == null) { return; } try { snapshots.Add(new FieldValueSnapshot { Target = target, Field = field, Value = field.GetValue(target) }); } catch { } } private static void RestoreRelocationFieldValues(List snapshots) { if (snapshots == null) { return; } for (int i = 0; i < snapshots.Count; i++) { FieldValueSnapshot fieldValueSnapshot = snapshots[i]; if (fieldValueSnapshot != null && fieldValueSnapshot.Target != null && !(fieldValueSnapshot.Field == null)) { try { fieldValueSnapshot.Field.SetValue(fieldValueSnapshot.Target, fieldValueSnapshot.Value); } catch { } } } } private static void SetRigidbodiesStill(Piece piece, Vector3 targetPosition, Quaternion targetRotation) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0062: Unknown result type (might be due to invalid IL or missing references) Rigidbody component = ((Component)piece).GetComponent(); if ((Object)(object)component != (Object)null) { component.position = targetPosition; component.rotation = targetRotation; SetLinearVelocity(component, Vector3.zero); component.angularVelocity = Vector3.zero; } Rigidbody[] componentsInChildren = ((Component)piece).GetComponentsInChildren(true); foreach (Rigidbody val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)component)) { SetLinearVelocity(val, Vector3.zero); val.angularVelocity = Vector3.zero; } } } private static void SetLinearVelocity(Rigidbody body, Vector3 velocity) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)body != (Object)null) { PropertyInfo rigidbodyLinearVelocityProperty = RigidbodyLinearVelocityProperty; if ((object)rigidbodyLinearVelocityProperty != null && rigidbodyLinearVelocityProperty.CanWrite) { RigidbodyLinearVelocityProperty.SetValue(body, velocity, null); } } } private static void ClearSupportCachesNear(Vector3 position, bool broadcast) { //IL_000d: 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) if (ClearLocalSupportCacheMethod == null || !IsFinite(position)) { return; } if (_supportLayerMask == 0) { _supportLayerMask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" }); } SupportPieces.Clear(); int num; while (true) { num = Physics.OverlapSphereNonAlloc(position, 8f, _supportColliderBuffer, _supportLayerMask, (QueryTriggerInteraction)2); if (num < _supportColliderBuffer.Length || _supportColliderBuffer.Length >= 2048) { break; } Array.Resize(ref _supportColliderBuffer, Math.Min(_supportColliderBuffer.Length * 2, 2048)); } for (int i = 0; i < num; i++) { Collider val = _supportColliderBuffer[i]; WearNTear val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent() : null); if (!((Object)(object)val2 != (Object)null) || !SupportPieces.Add(val2)) { continue; } try { ClearLocalSupportCacheMethod.Invoke(val2, Array.Empty()); } catch { continue; } ZNetView component = ((Component)val2).GetComponent(); if (broadcast && (Object)(object)component != (Object)null && component.IsValid() && !component.IsOwner() && component.HasOwner()) { long owner = component.GetZDO().GetOwner(); if (owner != 0L) { component.InvokeRPC(owner, "RPC_ClearCachedSupport", Array.Empty()); } } } } private static void UpdateMoveGhostValidity(Player player) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) GameObject placementGhost = GetPlacementGhost(player); if (_state == null || (Object)(object)placementGhost == (Object)null || (Object)(object)_state.Piece == (Object)null) { Cancel(player, showMessage: false); return; } Piece component = placementGhost.GetComponent(); if (!((Object)(object)component != (Object)null)) { return; } if ((int)GetPlacementStatus(player) == 0 && IsInsideOriginalBuildArea(_state, placementGhost.transform.position)) { component.SetInvalidPlacementHeightlight(false); if ((Object)(object)_state.HighlightedGhost != (Object)(object)placementGhost || !_state.GhostHighlighted) { ApplyMoveGhostHighlight(placementGhost); _state.HighlightedGhost = placementGhost; _state.GhostHighlighted = true; } } else { component.SetInvalidPlacementHeightlight(true); _state.GhostHighlighted = false; } } private static void UpdateLineAndGhost(Player player) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) GameObject placementGhost = GetPlacementGhost(player); if (_state == null || (Object)(object)placementGhost == (Object)null || (Object)(object)_state.Piece == (Object)null) { Cancel(player, showMessage: false); return; } Vector3 position = placementGhost.transform.position; Quaternion rotation = placementGhost.transform.rotation; bool activeInHierarchy = placementGhost.activeInHierarchy; if (!_state.VisualGeometryCached || Vector3.Distance(_state.LastGhostPosition, position) > 0.001f || Quaternion.Angle(_state.LastGhostRotation, rotation) > 0.01f || _state.LastGhostVisible != activeInHierarchy) { EnsureLine(); if (!_state.OriginGeometryCached) { _state.OriginGroundPoint = ProjectToGround(((Component)_state.Piece).transform.position); GetLinkGeometry(((Component)_state.Piece).gameObject, _state.OriginGroundPoint, out _state.OriginLinkPoint, out _state.OriginRingRadius); _state.OriginGeometryCached = true; } Vector3 val = ProjectToGround(position); GetLinkGeometry(placementGhost, val, out var linkPoint, out var ringRadius); UpdateLinkObject(_state.OriginGroundPoint, val, _state.OriginLinkPoint, linkPoint, _state.OriginRingRadius, ringRadius, activeInHierarchy); _state.LastGhostPosition = position; _state.LastGhostRotation = rotation; _state.LastGhostVisible = activeInHierarchy; _state.VisualGeometryCached = true; } UpdateMoveGhostValidity(player); } private static void UpdateLinkObject(Vector3 groundStart, Vector3 groundEnd, Vector3 linkStart, Vector3 linkEnd, float originRingRadius, float ghostRingRadius, bool visible) { //IL_0035: 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_0054: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00bc: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_lineObject == (Object)null) && !((Object)(object)_dashLine == (Object)null) && !((Object)(object)_originRing == (Object)null) && !((Object)(object)_ghostRing == (Object)null)) { if (!IsFinite(linkStart) || !IsFinite(linkEnd) || Vector3.Distance(linkStart, linkEnd) <= 0.05f) { linkStart = groundStart + Vector3.up * 1.25f; linkEnd = groundEnd + Vector3.up * 1.25f; } float num = Vector3.Distance(linkStart, linkEnd); bool num2 = visible && num > 0.05f; SetLineVisible(num2); if (num2) { DrawRing(_originRing, groundStart, originRingRadius); DrawRing(_ghostRing, groundEnd, ghostRingRadius); DrawDash(linkStart, linkEnd, num); } } } private static void ApplyMoveGhostHighlight(GameObject ghost) { //IL_003f: 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_0061: 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) Renderer[] componentsInChildren = ghost.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if (!((Object)(object)val2 == (Object)null)) { SetMaterialColor(val2, "_Color", GhostColor); SetMaterialColor(val2, "_BaseColor", GhostColor); SetMaterialColor(val2, "_TintColor", GhostColor); SetMaterialColor(val2, "_EmissionColor", GhostEmissionColor); val2.EnableKeyword("_EMISSION"); } } } } private static void SetMaterialColor(Material material, string property, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty(property)) { material.SetColor(property, color); } } private static Vector3 ProjectToGround(Vector3 worldPosition) { //IL_0000: 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_000f: 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_0022: Unknown result type (might be due to invalid IL or missing references) if (TryFindFloorY(worldPosition, 4f, out var floorY)) { return new Vector3(worldPosition.x, floorY + 0.03f, worldPosition.z); } return worldPosition; } private static void GetLinkGeometry(GameObject gameObject, Vector3 fallbackGroundPoint, out Vector3 linkPoint, out float ringRadius) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_006c: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) Bounds bounds; bool flag = TryGetObjectBounds(gameObject, out bounds); ringRadius = (flag ? GetRingRadius(bounds) : 0.6f); if (flag) { Vector3 center = ((Bounds)(ref bounds)).center; float num = Mathf.Max(((Bounds)(ref bounds)).max.y + 0.15f, fallbackGroundPoint.y + 0.35f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(center.x, num, center.z); if (IsFinite(val)) { linkPoint = val; return; } } Piece component = gameObject.GetComponent(); if ((Object)(object)component != (Object)null && TryGetSnapPointBounds(component, out bounds)) { Vector3 center2 = ((Bounds)(ref bounds)).center; float num2 = Mathf.Max(((Bounds)(ref bounds)).max.y + 0.15f, fallbackGroundPoint.y + 0.35f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(center2.x, num2, center2.z); if (IsFinite(val2)) { linkPoint = val2; return; } } linkPoint = fallbackGroundPoint + Vector3.up * 1.25f; } private static bool TryGetObjectBounds(GameObject gameObject, out Bounds bounds) { //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_0035: Unknown result type (might be due to invalid IL or missing references) bool hasBounds = TryCollectColliderBounds(gameObject, out bounds); if (!IsUsefulBounds(bounds, hasBounds)) { hasBounds = TryCollectRendererBounds(gameObject, out bounds); } if (!IsUsefulBounds(bounds, hasBounds)) { hasBounds = TryCollectMeshBounds(gameObject, out bounds); } return IsUsefulBounds(bounds, hasBounds); } private static float GetRingRadius(GameObject gameObject) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!TryGetObjectBounds(gameObject, out var bounds)) { return 0.6f; } return GetRingRadius(bounds); } private static float GetRingRadius(Bounds bounds) { //IL_0002: 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_001b: 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) float num = Mathf.Sqrt(((Bounds)(ref bounds)).extents.x * ((Bounds)(ref bounds)).extents.x + ((Bounds)(ref bounds)).extents.z * ((Bounds)(ref bounds)).extents.z); if (IsFinite(num) && num > 0f) { return Mathf.Clamp(num + 0.25f, 0.6f, 8f); } return 0.6f; } private static bool TryCollectColliderBounds(GameObject gameObject, out Bounds bounds) { //IL_0003: 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) bool hasBounds = false; bounds = default(Bounds); BoundsColliderBuffer.Clear(); gameObject.GetComponentsInChildren(false, BoundsColliderBuffer); foreach (Collider item in BoundsColliderBuffer) { if (!((Object)(object)item == (Object)null) && item.enabled && !item.isTrigger && ((Component)item).gameObject.activeInHierarchy) { AddBounds(ref bounds, ref hasBounds, item.bounds); } } BoundsColliderBuffer.Clear(); return hasBounds; } private static bool TryCollectRendererBounds(GameObject gameObject, out Bounds bounds) { //IL_0003: 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) bool hasBounds = false; bounds = default(Bounds); BoundsRendererBuffer.Clear(); gameObject.GetComponentsInChildren(false, BoundsRendererBuffer); foreach (Renderer item in BoundsRendererBuffer) { if (!((Object)(object)item == (Object)null) && item.enabled && ((Component)item).gameObject.activeInHierarchy && !(((object)item).GetType().Name == "ParticleSystemRenderer")) { AddBounds(ref bounds, ref hasBounds, item.bounds); } } BoundsRendererBuffer.Clear(); return hasBounds; } private static bool TryCollectMeshBounds(GameObject gameObject, out Bounds bounds) { //IL_0003: 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_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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00b9: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) bool hasBounds = false; bounds = default(Bounds); BoundsMeshFilterBuffer.Clear(); gameObject.GetComponentsInChildren(false, BoundsMeshFilterBuffer); foreach (MeshFilter item in BoundsMeshFilterBuffer) { Mesh val = (((Object)(object)item != (Object)null && ((Component)item).gameObject.activeInHierarchy) ? item.sharedMesh : null); if (!((Object)(object)val == (Object)null)) { Bounds bounds2 = val.bounds; Vector3 val2 = ((Component)item).transform.TransformPoint(((Bounds)(ref bounds2)).center); Vector3 extents = ((Bounds)(ref bounds2)).extents; Vector3 val3 = Abs(((Component)item).transform.TransformVector(new Vector3(extents.x, 0f, 0f))) + Abs(((Component)item).transform.TransformVector(new Vector3(0f, extents.y, 0f))) + Abs(((Component)item).transform.TransformVector(new Vector3(0f, 0f, extents.z))); AddBounds(ref bounds, ref hasBounds, new Bounds(val2, val3 * 2f)); } } BoundsMeshFilterBuffer.Clear(); return hasBounds; } private static bool TryGetSnapPointBounds(Piece piece, out Bounds bounds) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) BoundsSnapPointBuffer.Clear(); piece.GetSnapPoints(BoundsSnapPointBuffer); bool hasBounds = false; bounds = default(Bounds); Bounds candidate = default(Bounds); foreach (Transform item in BoundsSnapPointBuffer) { if (!((Object)(object)item == (Object)null)) { ((Bounds)(ref candidate))..ctor(item.position, Vector3.one * 0.05f); AddBounds(ref bounds, ref hasBounds, candidate); } } BoundsSnapPointBuffer.Clear(); return hasBounds; } private static void AddBounds(ref Bounds bounds, ref bool hasBounds, Bounds candidate) { //IL_0002: 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_001e: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!IsFinite(((Bounds)(ref candidate)).center) || !IsFinite(((Bounds)(ref candidate)).size)) { return; } Vector3 size = ((Bounds)(ref candidate)).size; if (!(((Vector3)(ref size)).sqrMagnitude < 0.0025000002f)) { if (!hasBounds) { bounds = candidate; hasBounds = true; } else { ((Bounds)(ref bounds)).Encapsulate(candidate); } } } private static bool IsUsefulBounds(Bounds bounds, bool hasBounds) { //IL_0005: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (hasBounds && IsFinite(((Bounds)(ref bounds)).center) && IsFinite(((Bounds)(ref bounds)).size)) { Vector3 size = ((Bounds)(ref bounds)).size; return ((Vector3)(ref size)).sqrMagnitude >= 0.0025000002f; } return false; } private static Vector3 Abs(Vector3 vector) { //IL_0000: 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_0016: 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) return new Vector3(Mathf.Abs(vector.x), Mathf.Abs(vector.y), Mathf.Abs(vector.z)); } private static bool IsFinite(Vector3 vector) { //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 (IsFinite(vector.x) && IsFinite(vector.y)) { return IsFinite(vector.z); } return false; } private static bool IsValidRotation(Quaternion rotation) { //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_0036: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (!IsFinite(rotation.x) || !IsFinite(rotation.y) || !IsFinite(rotation.z) || !IsFinite(rotation.w)) { return false; } float num = rotation.x * rotation.x + rotation.y * rotation.y + rotation.z * rotation.z + rotation.w * rotation.w; if (num > 0.0001f) { return Mathf.Abs(num - 1f) <= 0.02f; } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool TryFindFloorY(Vector3 worldPosition, float searchHeight, out float floorY) { //IL_0001: 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_0050: 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_0064: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) floorY = worldPosition.y; if (_floorMask == 0) { _floorMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "water" }); } int num = Physics.RaycastNonAlloc(worldPosition + Vector3.up * 0.25f, Vector3.down, FloorHits, searchHeight, _floorMask, (QueryTriggerInteraction)1); bool flag = false; float num2 = float.NegativeInfinity; for (int i = 0; i < num; i++) { RaycastHit val = FloorHits[i]; if (!(((RaycastHit)(ref val)).normal.y < 0.7f) && !(((RaycastHit)(ref val)).point.y > worldPosition.y + 0.2f) && !(((RaycastHit)(ref val)).point.y <= num2)) { num2 = ((RaycastHit)(ref val)).point.y; flag = true; } } if (flag) { floorY = num2; } return flag; } private static void DrawRing(LineRenderer ring, Vector3 center, float radius) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) if (ring.positionCount != 28) { ring.positionCount = 28; } for (int i = 0; i < 28; i++) { float num = (float)i / 28f * (float)Math.PI * 2f; Vector3 val = center + (Vector3.right * Mathf.Cos(num) + Vector3.forward * Mathf.Sin(num)) * radius; ring.SetPosition(i, val); } } private static void DrawDash(Vector3 from, Vector3 to, float length) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) _dashLine.positionCount = 2; _dashLine.SetPosition(0, from); _dashLine.SetPosition(1, to); Material sharedMaterial = ((Renderer)_dashLine).sharedMaterial; if (!((Object)(object)sharedMaterial == (Object)null)) { EnsureDashTexture(); sharedMaterial.mainTexture = (Texture)(object)_dashTexture; sharedMaterial.mainTextureScale = new Vector2(Mathf.Max(0.01f, length / 0.35f), 1f); sharedMaterial.mainTextureOffset = new Vector2((0f - Time.time) * 1.6f, 0f); } } private static void EnsureDashTexture() { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0058: 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_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_dashTexture != (Object)null)) { _dashTexture = new Texture2D(10, 1, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1 }; Color[] array = (Color[])(object)new Color[10]; for (int i = 0; i < 10; i++) { array[i] = (Color)((i < 6) ? Color.white : new Color(1f, 1f, 1f, 0f)); } _dashTexture.SetPixels(array); _dashTexture.Apply(); } } private static bool ShouldCancelForUiOrState(Player player) { if (_state == null) { return false; } if (!MoveBuildPiecesPlugin.IsEnabled || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)_state.Player || !((Character)player).InPlaceMode() || ((Character)player).IsDead() || ((Character)player).IsTeleporting()) { return true; } if ((Object)(object)_state.NetView == (Object)null || !_state.NetView.IsValid() || (Object)(object)_state.Piece == (Object)null) { return true; } if (!_state.WaitingForMoveResult && !IsMoveSelectionIntact(_state, player)) { return true; } if (IsUiBlockingInput() || Hud.IsPieceSelectionVisible()) { return true; } return ZInput.GetKeyDown((KeyCode)27, true); } private static bool IsMoveSelectionIntact(MoveState state, Player player) { if (state == null || (Object)(object)player == (Object)null || string.IsNullOrEmpty(state.PrefabName) || (Object)(object)GetBuildPieces(player) != (Object)(object)state.ActivePieceTable) { return false; } GameObject val = (((Object)(object)state.ActivePieceTable != (Object)null) ? state.ActivePieceTable.GetSelectedPrefab() : null); if ((Object)(object)val == (Object)null || Utils.GetPrefabName(val) != state.PrefabName) { return false; } GameObject placementGhost = GetPlacementGhost(player); if ((Object)(object)placementGhost != (Object)null) { return Utils.GetPrefabName(placementGhost) == state.PrefabName; } return false; } private static bool IsUiBlockingInput() { if (!Menu.IsVisible() && !InventoryGui.IsVisible() && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.IsOpen()) { if ((Object)(object)Chat.instance != (Object)null) { return Chat.instance.HasFocus(); } return false; } return true; } private static void Cancel(Player player, bool showMessage, bool releaseLock = true) { MoveState state = _state; _state = null; if (state != null && showMessage) { Message(player, "Move cancelled"); } try { if (state != null) { RestoreBuildState(player ?? state.Player, state.OriginalBuildPieces, state.RelocateTableObject); } } catch (Exception ex) { Debug.LogWarning((object)("[MoveBuildPieces] Failed to restore the build selection: " + ex.GetBaseException().Message)); } if (state != null && releaseLock) { try { ReleaseMoveLock(state.NetView, state.LockPlayerId, state.LockToken, state.LockOwnerPeerId); } catch { } } SetLineVisible(visible: false); } private static GameObject GetPlacementGhost(Player player) { object? obj = PlacementGhostField?.GetValue(player); return (GameObject)((obj is GameObject) ? obj : null); } private static PlacementStatus GetPlacementStatus(Player player) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) object obj = PlacementStatusField?.GetValue(player); if (obj is PlacementStatus) { return (PlacementStatus)obj; } return (PlacementStatus)1; } private static string GetPlacementFailureMessage(PlacementStatus status) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected I4, but got Unknown return (status - 2) switch { 1 => "$msg_nobuildzone", 0 => "$msg_blocked", 2 => "$msg_privatezone", 3 => "$msg_needspace", 4 => "$msg_noteleportarea", 5 => "$msg_extensionmissingstation", 6 => "$msg_wrongbiome", 7 => "$msg_needcultivated", 8 => "$msg_needdirt", 9 => "$msg_notindungeon", _ => "$msg_invalidplacement", }; } private static void EnsureLine() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_lineObject != (Object)null)) { _lineObject = new GameObject("MoveBuildPieces_LinkVisuals"); Object.DontDestroyOnLoad((Object)(object)_lineObject); _dashLine = CreateLineRenderer("MoveBuildPieces_Dash", loop: false, tiled: true); _originRing = CreateLineRenderer("MoveBuildPieces_OriginRing", loop: true, tiled: false); _ghostRing = CreateLineRenderer("MoveBuildPieces_GhostRing", loop: true, tiled: false); SetLineVisible(visible: false); } } private static LineRenderer CreateLineRenderer(string name, bool loop, bool tiled) { //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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00f4: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(_lineObject.transform, false); LineRenderer val2 = val.AddComponent(); val2.useWorldSpace = true; val2.loop = loop; val2.numCapVertices = 4; val2.numCornerVertices = 2; val2.textureMode = (LineTextureMode)(tiled ? 1 : 0); val2.alignment = (LineAlignment)0; val2.positionCount = 0; val2.widthMultiplier = 0.075f; val2.startColor = (loop ? RingColor : LinkColor); val2.endColor = (loop ? RingColor : LinkColor); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; Shader val3 = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard"); if ((Object)(object)val3 != (Object)null) { ((Renderer)val2).sharedMaterial = new Material(val3) { name = name + "_Material", renderQueue = 3100 }; } ((Renderer)val2).enabled = false; return val2; } private static void SetLineVisible(bool visible) { if ((Object)(object)_dashLine != (Object)null) { ((Renderer)_dashLine).enabled = visible; } if ((Object)(object)_originRing != (Object)null) { ((Renderer)_originRing).enabled = visible; } if ((Object)(object)_ghostRing != (Object)null) { ((Renderer)_ghostRing).enabled = visible; } } private static void DestroyLine() { HashSet hashSet = new HashSet(); if ((Object)(object)_dashLine != (Object)null && (Object)(object)((Renderer)_dashLine).sharedMaterial != (Object)null) { hashSet.Add(((Renderer)_dashLine).sharedMaterial); } if ((Object)(object)_originRing != (Object)null && (Object)(object)((Renderer)_originRing).sharedMaterial != (Object)null) { hashSet.Add(((Renderer)_originRing).sharedMaterial); } if ((Object)(object)_ghostRing != (Object)null && (Object)(object)((Renderer)_ghostRing).sharedMaterial != (Object)null) { hashSet.Add(((Renderer)_ghostRing).sharedMaterial); } if ((Object)(object)_lineObject != (Object)null) { Object.Destroy((Object)(object)_lineObject); } foreach (Material item in hashSet) { Object.Destroy((Object)(object)item); } if ((Object)(object)_dashTexture != (Object)null) { Object.Destroy((Object)(object)_dashTexture); } _lineObject = null; _dashLine = null; _originRing = null; _ghostRing = null; _dashTexture = null; } private static void Message(Player player, string text) { if ((Object)(object)player != (Object)null) { ((Character)player).Message((MessageType)2, text, 0, (Sprite)null); } } }