use of org.spongepowered.api.event.entity.MoveEntityEvent in project SpongeCommon by SpongePowered.
the class ServerPlayerMixin method teleportTo.
/*
@Inject(method = "markPlayerActive()V", at = @At("HEAD"))
private void impl$onPlayerActive(final CallbackInfo ci) {
((ServerPlayNetHandlerBridge) this.connection).bridge$resendLatestResourcePackRequest();
}
*/
/**
* @author zidane - November 21st, 2020 - Minecraft 1.15
* @reason Ensure that the teleport hook honors our events
*/
@Overwrite
public void teleportTo(final net.minecraft.server.level.ServerLevel world, final double x, final double y, final double z, final float yaw, final float pitch) {
final net.minecraft.server.level.ServerPlayer player = (net.minecraft.server.level.ServerPlayer) (Object) this;
double actualX = x;
double actualY = y;
double actualZ = z;
double actualYaw = yaw;
double actualPitch = pitch;
final boolean hasMovementContext = PhaseTracker.getCauseStackManager().currentContext().containsKey(EventContextKeys.MOVEMENT_TYPE);
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
if (!hasMovementContext) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.PLUGIN);
}
if (world == player.level) {
@Nullable final Vector3d destination = this.impl$fireMoveEvent(PhaseTracker.SERVER, new Vector3d(x, y, z));
if (destination == null) {
return;
}
actualX = destination.x();
actualY = destination.y();
actualZ = destination.z();
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) player, new Vector3d(actualPitch, actualYaw, 0), new Vector3d(pitch, yaw, 0));
SpongeCommon.post(rotateEvent);
actualYaw = rotateEvent.isCancelled() ? player.yRot : rotateEvent.toRotation().y();
actualPitch = rotateEvent.isCancelled() ? player.xRot : rotateEvent.toRotation().x();
}
this.shadow$setCamera(player);
this.shadow$stopRiding();
if (player.isSleeping()) {
player.stopSleepInBed(true, true);
}
player.connection.teleport(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch);
player.setYHeadRot((float) actualYaw);
final ChunkPos chunkpos = new ChunkPos(new BlockPos(actualX, actualY, actualZ));
world.getChunkSource().addRegionTicket(TicketType.POST_TELEPORT, chunkpos, 1, player.getId());
} else {
final ChangeEntityWorldEvent.Pre preEvent = PlatformHooks.INSTANCE.getEventHooks().callChangeEntityWorldEventPre(player, world);
if (SpongeCommon.post(preEvent)) {
return;
}
if (ShouldFire.MOVE_ENTITY_EVENT) {
final MoveEntityEvent posEvent = SpongeEventFactory.createChangeEntityWorldEventReposition(frame.currentCause(), (org.spongepowered.api.entity.Entity) player, preEvent.originalWorld(), VecHelper.toVector3d(player.position()), new Vector3d(x, y, z), preEvent.originalDestinationWorld(), new Vector3d(x, y, z), preEvent.destinationWorld());
if (SpongeCommon.post(posEvent)) {
return;
}
actualX = posEvent.destinationPosition().x();
actualY = posEvent.destinationPosition().y();
actualZ = posEvent.destinationPosition().z();
}
this.shadow$setPos(actualX, actualY, actualZ);
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) player, new Vector3d(actualYaw, actualPitch, 0), new Vector3d(yaw, pitch, 0));
if (!SpongeCommon.post(rotateEvent)) {
actualYaw = (float) rotateEvent.toRotation().x();
actualPitch = (float) rotateEvent.toRotation().y();
}
}
this.yRot = (float) actualYaw;
this.xRot = (float) actualPitch;
EntityUtil.performPostChangePlayerWorldLogic(player, (net.minecraft.server.level.ServerLevel) preEvent.originalWorld(), (net.minecraft.server.level.ServerLevel) preEvent.originalDestinationWorld(), (net.minecraft.server.level.ServerLevel) preEvent.destinationWorld(), false);
}
}
}
use of org.spongepowered.api.event.entity.MoveEntityEvent in project SpongeCommon by SpongePowered.
the class TeleportCommandMixin method performTeleport.
/**
* @author Zidane
* @reason Have the teleport command respect our events
*/
@Overwrite
private static void performTeleport(CommandSourceStack source, Entity entityIn, ServerLevel worldIn, double x, double y, double z, Set<ClientboundPlayerPositionPacket.RelativeArgument> relativeList, float yaw, float pitch, @Nullable TeleportCommand.LookAt facing) {
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.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
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.yRot : rotateEvent.toRotation().y();
actualPitch = rotateEvent.isCancelled() ? entityIn.xRot : rotateEvent.toRotation().x();
}
if (entityIn instanceof ServerPlayer) {
ChunkPos chunkpos = new ChunkPos(new BlockPos(actualX, actualY, actualZ));
worldIn.getChunkSource().addRegionTicket(TicketType.POST_TELEPORT, chunkpos, 1, entityIn.getId());
entityIn.stopRiding();
if (((ServerPlayer) entityIn).isSleeping()) {
((ServerPlayer) entityIn).stopSleepInBed(true, true);
}
((ServerPlayer) entityIn).connection.teleport(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch, relativeList);
} else {
entityIn.moveTo(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch);
}
entityIn.setYHeadRot((float) actualYaw);
}
} else {
if (entityIn instanceof ServerPlayer) {
// 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.getCauseStackManager().addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
((ServerPlayer) entityIn).teleportTo(worldIn, x, y, z, yaw, pitch);
PhaseTracker.getCauseStackManager().removeContext(EventContextKeys.MOVEMENT_TYPE);
} else {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().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);
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.xRot, entityIn.yRot, 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.yRot;
actualPitch = entityIn.xRot;
}
}
result.restoreFrom(entityIn);
result.moveTo(posEvent.destinationPosition().x(), posEvent.destinationPosition().y(), posEvent.destinationPosition().z(), (float) actualYaw, (float) actualPitch);
result.setYHeadRot((float) actualYaw);
worldIn.addFromAnotherDimension(result);
entityIn.removed = true;
Sponge.eventManager().post(SpongeEventFactory.createChangeEntityWorldEventPost(PhaseTracker.getCauseStackManager().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();
}
}
use of org.spongepowered.api.event.entity.MoveEntityEvent in project SpongeCommon by SpongePowered.
the class ThrownEnderpearlMixin method impl$callMoveEntityEventForThrower.
@Inject(method = "onHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;teleportTo(DDD)V"), cancellable = true)
private void impl$callMoveEntityEventForThrower(final HitResult result, final CallbackInfo ci) {
if (this.shadow$getCommandSenderWorld().isClientSide || !ShouldFire.MOVE_ENTITY_EVENT) {
return;
}
final Entity entity = this.shadow$getOwner();
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.pushCause(entity);
frame.pushCause(this);
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.ENDER_PEARL);
final MoveEntityEvent event = SpongeEventFactory.createMoveEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entity, VecHelper.toVector3d(entity.position()), VecHelper.toVector3d(this.shadow$position()), VecHelper.toVector3d(this.shadow$position()));
if (SpongeCommon.post(event)) {
// Eventhough the event is made, the pearl was still created so remove it anyways
this.shadow$remove();
return;
}
// This seems odd but we move the pearl so that the pearl's logic will move the living entity later in the impact method
final Vector3d destinationPosition = event.destinationPosition();
this.shadow$setPos(destinationPosition.x(), destinationPosition.y(), destinationPosition.z());
}
}
use of org.spongepowered.api.event.entity.MoveEntityEvent in project SpongeCommon by SpongePowered.
the class MixinNetHandlerPlayServer method processVehicleMoveEvent.
/**
* @author gabizou - June 22nd, 2016
* @author blood - May 6th, 2017
* @reason Redirects the {@link Entity#getLowestRidingEntity()} call to throw our
* {@link MoveEntityEvent}. The peculiarity of this redirect is that the entity
* returned is perfectly valid to be {@link this#player} since, if the player
* is NOT riding anything, the lowest riding entity is themselves. This way, if
* the event is cancelled, the player can be returned instead of the actual riding
* entity.
*
* @param playerMP The player
* @param packetIn The packet movement
* @return The lowest riding entity
*/
@Redirect(method = "processVehicleMove", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayerMP;getLowestRidingEntity()Lnet/minecraft/entity/Entity;"))
private Entity processVehicleMoveEvent(EntityPlayerMP playerMP, CPacketVehicleMove packetIn) {
final Entity ridingEntity = this.player.getLowestRidingEntity();
if (ridingEntity == this.player || ridingEntity.getControllingPassenger() != this.player || ridingEntity != this.lowestRiddenEnt) {
return ridingEntity;
}
// Sponge Start - Movement event
org.spongepowered.api.entity.Entity spongeEntity = (org.spongepowered.api.entity.Entity) ridingEntity;
Vector3d fromrot = spongeEntity.getRotation();
Location<World> from = spongeEntity.getLocation();
Vector3d torot = new Vector3d(packetIn.getPitch(), packetIn.getYaw(), 0);
Location<World> to = new Location<>(spongeEntity.getWorld(), packetIn.getX(), packetIn.getY(), packetIn.getZ());
Transform<World> fromTransform = spongeEntity.getTransform().setLocation(from).setRotation(fromrot);
Transform<World> toTransform = spongeEntity.getTransform().setLocation(to).setRotation(torot);
MoveEntityEvent event = SpongeEventFactory.createMoveEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), fromTransform, toTransform, this.getPlayer());
SpongeImpl.postEvent(event);
if (event.isCancelled()) {
// There is no need to change the current riding entity position as it hasn't changed yet.
// Send packet to client in order to update rider position.
this.netManager.sendPacket(new SPacketMoveVehicle(ridingEntity));
return this.player;
}
return ridingEntity;
}
use of org.spongepowered.api.event.entity.MoveEntityEvent in project SpongeCommon by SpongePowered.
the class MixinNetHandlerPlayServer method throwMoveEvent.
/**
* @author gabizou - June 22nd, 2016
* @reason Sponge has to throw the movement events before we consider moving the player and there's
* no clear way to go about it with the target position being null and the last position update checks.
* @param packetIn
*/
@Redirect(method = "processPlayer", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/EntityPlayerMP;queuedEndExit:Z"))
private boolean throwMoveEvent(EntityPlayerMP playerMP, CPacketPlayer packetIn) {
if (!playerMP.queuedEndExit) {
// We don't fire an event to avoid confusing plugins.
if (!packetIn.moving && !packetIn.rotating) {
return playerMP.queuedEndExit;
}
// Sponge Start - Movement event
Player player = (Player) this.player;
IMixinEntityPlayerMP mixinPlayer = (IMixinEntityPlayerMP) this.player;
Vector3d fromrot = player.getRotation();
// If Sponge used the player's current location, the delta might never be triggered which could be exploited
Location<World> from = player.getLocation();
if (this.lastMoveLocation != null) {
from = this.lastMoveLocation;
}
Vector3d torot = new Vector3d(packetIn.pitch, packetIn.yaw, 0);
Location<World> to = new Location<>(player.getWorld(), packetIn.x, packetIn.y, packetIn.z);
// Minecraft sends a 0, 0, 0 position when rotation only update occurs, this needs to be recognized and corrected
boolean rotationOnly = !packetIn.moving && packetIn.rotating;
if (rotationOnly) {
// Correct the to location so it's not misrepresented to plugins, only when player rotates without moving
// In this case it's only a rotation update, which isn't related to the to location
from = player.getLocation();
to = from;
}
// Minecraft does the same with rotation when it's only a positional update
boolean positionOnly = packetIn.moving && !packetIn.rotating;
if (positionOnly) {
// Correct the new rotation to match the old rotation
torot = fromrot;
}
((IMixinEntityPlayerMP) this.player).setVelocityOverride(to.getPosition().sub(from.getPosition()));
double deltaSquared = to.getPosition().distanceSquared(from.getPosition());
double deltaAngleSquared = fromrot.distanceSquared(torot);
// eventually it would be nice to not have them
if (deltaSquared > ((1f / 16) * (1f / 16)) || deltaAngleSquared > (.15f * .15f)) {
Transform<World> fromTransform = player.getTransform().setLocation(from).setRotation(fromrot);
Transform<World> toTransform = player.getTransform().setLocation(to).setRotation(torot);
Sponge.getCauseStackManager().pushCause(player);
MoveEntityEvent event = SpongeEventFactory.createMoveEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), fromTransform, toTransform, player);
SpongeImpl.postEvent(event);
Sponge.getCauseStackManager().popCause();
if (event.isCancelled()) {
mixinPlayer.setLocationAndAngles(fromTransform);
this.lastMoveLocation = from;
((IMixinEntityPlayerMP) this.player).setVelocityOverride(null);
return true;
} else if (!event.getToTransform().equals(toTransform)) {
mixinPlayer.setLocationAndAngles(event.getToTransform());
this.lastMoveLocation = event.getToTransform().getLocation();
((IMixinEntityPlayerMP) this.player).setVelocityOverride(null);
return true;
} else if (!from.equals(player.getLocation()) && this.justTeleported) {
this.lastMoveLocation = player.getLocation();
// Prevent teleports during the move event from causing odd behaviors
this.justTeleported = false;
((IMixinEntityPlayerMP) this.player).setVelocityOverride(null);
return true;
} else {
this.lastMoveLocation = event.getToTransform().getLocation();
}
this.resendLatestResourcePackRequest();
}
}
return playerMP.queuedEndExit;
}
Aggregations