From 87a6c5859b2fd5ac812d89ca71a25c766299d19e Mon Sep 17 00:00:00 2001 From: Aapo Katila Date: Sat, 1 Nov 2025 17:36:39 +0200 Subject: [PATCH 1/3] Remove obsolete performTeleport overwrite --- .../server/commands/TeleportCommandMixin.java | 184 +----------------- 1 file changed, 9 insertions(+), 175 deletions(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java index ba17630718b..6f301e25588 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java @@ -24,197 +24,31 @@ */ package org.spongepowered.common.mixin.core.server.commands; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.core.BlockPos; -import net.minecraft.server.commands.LookAt; import net.minecraft.server.commands.TeleportCommand; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntitySpawnReason; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.PathfinderMob; -import net.minecraft.world.entity.PositionMoveRotation; import net.minecraft.world.entity.Relative; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.phys.Vec3; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.Sponge; import org.spongepowered.api.event.CauseStackManager; import org.spongepowered.api.event.EventContextKeys; -import org.spongepowered.api.event.SpongeEventFactory; import org.spongepowered.api.event.cause.entity.MovementTypes; -import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; -import org.spongepowered.api.event.entity.MoveEntityEvent; -import org.spongepowered.api.event.entity.RotateEntityEvent; -import org.spongepowered.api.world.server.ServerWorld; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.event.ShouldFire; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.hooks.PlatformHooks; -import org.spongepowered.common.util.VecHelper; -import org.spongepowered.math.vector.Vector3d; import java.util.Set; @Mixin(TeleportCommand.class) public abstract class TeleportCommandMixin { - /** - * @author Zidane - * @reason Have the teleport command respect our events - */ - @Overwrite - // TODO check if this is still correct - check if we can get rid of the overwrite - private static void performTeleport(CommandSourceStack source, Entity entityIn, ServerLevel worldIn, double x, double y, double z, - Set relativeList, float yaw, float pitch, @Nullable LookAt facing) { + @Redirect(method = "performTeleport", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;teleportTo(Lnet/minecraft/server/level/ServerLevel;DDDLjava/util/Set;FFZ)Z")) + private static boolean vanilla$createCauseFrameForPerformTeleport( + final Entity instance, final ServerLevel level, final double x, final double y, + final double z, final Set relativeMovements, final float yRot, final float xRot, final boolean setCamera) { + try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { + frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - double actualX = x; - double actualY = y; - double actualZ = z; - double actualYaw = yaw; - double actualPitch = pitch; - - if (!(entityIn instanceof ServerPlayer)) { - actualYaw = Mth.wrapDegrees(yaw); - actualPitch = Mth.wrapDegrees(pitch); - actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F); - } - - if (worldIn == entityIn.level()) { - try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { - frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - - // TODO Should honor the relative list before the event.. - - if (ShouldFire.MOVE_ENTITY_EVENT) { - final MoveEntityEvent posEvent = SpongeEventFactory.createMoveEntityEvent(frame.currentCause(), - (org.spongepowered.api.entity.Entity) entityIn, VecHelper.toVector3d(entityIn.position()), - new Vector3d(x, y, z), new Vector3d(x, y, z)); - - if (SpongeCommon.post(posEvent)) { - return; - } - - actualX = posEvent.destinationPosition().x(); - actualY = posEvent.destinationPosition().y(); - actualZ = posEvent.destinationPosition().z(); - } - - if (ShouldFire.ROTATE_ENTITY_EVENT) { - final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), - (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(actualPitch, actualYaw, 0), - new Vector3d(pitch, yaw, 0)); - - SpongeCommon.post(rotateEvent); - actualYaw = rotateEvent.isCancelled() ? entityIn.getYRot() : rotateEvent.toRotation().y(); - actualPitch = rotateEvent.isCancelled() ? entityIn.getXRot() : rotateEvent.toRotation().x(); - } - - if (entityIn instanceof ServerPlayer sp) { - - ChunkPos chunkpos = new ChunkPos(new BlockPos((int) actualX, (int) actualY, (int) actualZ)); - worldIn.getChunkSource().addRegionTicket(TicketType.FORCED, chunkpos, 1, chunkpos); - - entityIn.stopRiding(); - - if (sp.isSleeping()) { - sp.stopSleepInBed(true, true); - } - - sp.connection.teleport( - new PositionMoveRotation(new Vec3( actualX, actualY, actualZ), Vec3.ZERO, (float) actualYaw, (float) actualPitch), relativeList); - } else { - entityIn.moveTo(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch); - } - - entityIn.setYHeadRot((float) actualYaw); - } - } else { - if (entityIn instanceof ServerPlayer sp) { - // To ensure mod code is caught, handling the world change for players happens in teleport - // Teleport will create a frame but we want to ensure it'll be the command movement type - // TODO check if this is still correct - PhaseTracker.getInstance().addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - sp.teleportTo(worldIn, x, y, z, relativeList, yaw, pitch, true); - PhaseTracker.getInstance().removeContext(EventContextKeys.MOVEMENT_TYPE); - } else { - try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { - frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - - final ServerLevel fromWorld = (ServerLevel) entityIn.getCommandSenderWorld(); - - final ChangeEntityWorldEvent.Pre preEvent = PlatformHooks.INSTANCE.getEventHooks().callChangeEntityWorldEventPre(entityIn, - worldIn); - if (SpongeCommon.post(preEvent)) { - return; - } - - final ChangeEntityWorldEvent.Reposition posEvent = - SpongeEventFactory.createChangeEntityWorldEventReposition(frame.currentCause(), - (org.spongepowered.api.entity.Entity) entityIn, - (org.spongepowered.api.world.server.ServerWorld) entityIn.getCommandSenderWorld(), - VecHelper.toVector3d(entityIn.position()), new Vector3d(x, y, z), preEvent.originalDestinationWorld(), - new Vector3d(x, y, z), preEvent.destinationWorld()); - - if (SpongeCommon.post(posEvent)) { - return; - } - - entityIn.unRide(); - final Entity result = entityIn.getType().create(worldIn, EntitySpawnReason.DIMENSION_TRAVEL); - if (result == null) { - return; - } - - if (ShouldFire.ROTATE_ENTITY_EVENT) { - final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), - (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(entityIn.getXRot(), entityIn.getYRot(), 0), - new Vector3d(actualPitch, actualYaw, 0)); - - if (!SpongeCommon.post(rotateEvent)) { - actualYaw = Mth.wrapDegrees(rotateEvent.toRotation().y()); - actualPitch = Mth.wrapDegrees(rotateEvent.toRotation().x()); - actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F); - } else { - actualYaw = entityIn.getYRot(); - actualPitch = entityIn.getXRot(); - } - } - - result.restoreFrom(entityIn); - result.moveTo(posEvent.destinationPosition().x(), posEvent.destinationPosition().y(), - posEvent.destinationPosition().z(), (float) actualYaw, (float) actualPitch); - result.setYHeadRot((float) actualYaw); - worldIn.addDuringTeleport(result); - entityIn.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); - - Sponge.eventManager().post(SpongeEventFactory.createChangeEntityWorldEventPost( - PhaseTracker.getInstance().currentCause(), - (org.spongepowered.api.entity.Entity) result, - (ServerWorld) fromWorld, - preEvent.originalDestinationWorld(), - preEvent.destinationWorld() - )); - } - } - } - - if (facing != null) { - facing.perform(source, entityIn); - } - - if (!(entityIn instanceof LivingEntity) || !((LivingEntity)entityIn).isFallFlying()) { - entityIn.setDeltaMovement(entityIn.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); - entityIn.setOnGround(true); - } - - if (entityIn instanceof PathfinderMob) { - ((PathfinderMob)entityIn).getNavigation().stop(); + return instance.teleportTo(level, x, y, z, relativeMovements, yRot, xRot, setCamera); } } } From 82f7cc153ea5673732de554806a444620d477d02 Mon Sep 17 00:00:00 2001 From: Aapo Katila Date: Sat, 8 Nov 2025 17:30:54 +0200 Subject: [PATCH 2/3] Improve mod compatibility --- .../core/server/commands/TeleportCommandMixin.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java index 6f301e25588..fbef02a8dcf 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java @@ -24,6 +24,8 @@ */ package org.spongepowered.common.mixin.core.server.commands; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.server.commands.TeleportCommand; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; @@ -33,7 +35,6 @@ import org.spongepowered.api.event.cause.entity.MovementTypes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.common.event.tracking.PhaseTracker; import java.util.Set; @@ -41,14 +42,12 @@ @Mixin(TeleportCommand.class) public abstract class TeleportCommandMixin { - @Redirect(method = "performTeleport", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;teleportTo(Lnet/minecraft/server/level/ServerLevel;DDDLjava/util/Set;FFZ)Z")) - private static boolean vanilla$createCauseFrameForPerformTeleport( - final Entity instance, final ServerLevel level, final double x, final double y, - final double z, final Set relativeMovements, final float yRot, final float xRot, final boolean setCamera) { + @WrapOperation(method = "performTeleport", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;teleportTo(Lnet/minecraft/server/level/ServerLevel;DDDLjava/util/Set;FFZ)Z")) + private static boolean impl$createCauseFrameForPerformTeleport( + final Entity instance, final ServerLevel $$0, final double $$1, final double $$2, final double $$3, final Set $$4, final float $$5, final float $$6, final boolean $$7, final Operation original) { try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - - return instance.teleportTo(level, x, y, z, relativeMovements, yRot, xRot, setCamera); + return original.call(instance, $$0, $$1, $$2, $$3, $$4, $$5, $$6, $$7); } } } From b66b9510b26be7cd7714b8699049ad008f46850f Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Thu, 27 Nov 2025 21:50:25 +0100 Subject: [PATCH 3/3] Parameter names --- .../mixin/core/server/commands/TeleportCommandMixin.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java index fbef02a8dcf..a565130de08 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/TeleportCommandMixin.java @@ -44,10 +44,11 @@ public abstract class TeleportCommandMixin { @WrapOperation(method = "performTeleport", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;teleportTo(Lnet/minecraft/server/level/ServerLevel;DDDLjava/util/Set;FFZ)Z")) private static boolean impl$createCauseFrameForPerformTeleport( - final Entity instance, final ServerLevel $$0, final double $$1, final double $$2, final double $$3, final Set $$4, final float $$5, final float $$6, final boolean $$7, final Operation original) { + final Entity instance, final ServerLevel level, final double x, final double y, final double z, + final Set relativeMovements, final float yRot, final float xRot, final boolean setCamera, final Operation original) { try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - return original.call(instance, $$0, $$1, $$2, $$3, $$4, $$5, $$6, $$7); + return original.call(instance, level, x, y, z, relativeMovements, yRot, xRot, setCamera); } } }