Search in sources :

Example 21 with ServerWorld

use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.

the class ServerPlayerMixin method impl$onReturnSleep.

@Inject(method = "startSleepInBed", at = @At(value = "RETURN"), cancellable = true)
private void impl$onReturnSleep(final BlockPos param0, final CallbackInfoReturnable<Either<Player.BedSleepingProblem, Unit>> cir) {
    final Either<Player.BedSleepingProblem, Unit> returnValue = cir.getReturnValue();
    if (returnValue.left().isPresent()) {
        switch(returnValue.left().get()) {
            case NOT_POSSIBLE_HERE:
            case TOO_FAR_AWAY:
            case NOT_POSSIBLE_NOW:
            case OBSTRUCTED:
            case NOT_SAFE:
                final Cause currentCause = Sponge.server().causeStackManager().currentCause();
                final BlockSnapshot snapshot = ((ServerWorld) this.level).createSnapshot(param0.getX(), param0.getY(), param0.getZ());
                if (Sponge.eventManager().post(SpongeEventFactory.createSleepingEventFailed(currentCause, snapshot, (Living) this))) {
                    final Either<Player.BedSleepingProblem, Unit> var5 = super.shadow$startSleepInBed(param0).ifRight((param0x) -> {
                        this.shadow$awardStat(Stats.SLEEP_IN_BED);
                        CriteriaTriggers.SLEPT_IN_BED.trigger((net.minecraft.server.level.ServerPlayer) (Object) this);
                    });
                    ((ServerLevel) this.level).updateSleepingPlayerList();
                    cir.setReturnValue(var5);
                }
                break;
            case // ignore
            OTHER_PROBLEM:
                break;
        }
    }
}
Also used : ServerWorld(org.spongepowered.api.world.server.ServerWorld) ServerLevel(net.minecraft.server.level.ServerLevel) Living(org.spongepowered.api.entity.living.Living) Cause(org.spongepowered.api.event.Cause) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Unit(net.minecraft.util.Unit) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 22 with ServerWorld

use of org.spongepowered.api.world.server.ServerWorld 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();
    }
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) ChangeEntityWorldEvent(org.spongepowered.api.event.entity.ChangeEntityWorldEvent) RotateEntityEvent(org.spongepowered.api.event.entity.RotateEntityEvent) ServerWorld(org.spongepowered.api.world.server.ServerWorld) LivingEntity(net.minecraft.world.entity.LivingEntity) Vector3d(org.spongepowered.math.vector.Vector3d) CauseStackManager(org.spongepowered.api.event.CauseStackManager) ServerPlayer(net.minecraft.server.level.ServerPlayer) ChunkPos(net.minecraft.world.level.ChunkPos) BlockPos(net.minecraft.core.BlockPos) PathfinderMob(net.minecraft.world.entity.PathfinderMob) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 23 with ServerWorld

use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method handleCollideImpactEvent.

public static boolean handleCollideImpactEvent(final net.minecraft.world.entity.Entity projectile, @Nullable final ProjectileSource projectileSource, final HitResult movingObjectPosition) {
    final HitResult.Type movingObjectType = movingObjectPosition.getType();
    try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
        frame.pushCause(projectile);
        frame.addContext(EventContextKeys.PROJECTILE_SOURCE, projectileSource == null ? UnknownProjectileSource.UNKNOWN : projectileSource);
        final Optional<UUID> creator = PhaseTracker.getInstance().getPhaseContext().getCreator();
        creator.ifPresent(user -> frame.addContext(EventContextKeys.CREATOR, user));
        final ServerLocation impactPoint = ServerLocation.of((ServerWorld) projectile.level, VecHelper.toVector3d(movingObjectPosition.getLocation()));
        boolean cancelled = false;
        if (movingObjectType == HitResult.Type.BLOCK) {
            final BlockHitResult blockMovingObjectPosition = (BlockHitResult) movingObjectPosition;
            final BlockPos blockPos = blockMovingObjectPosition.getBlockPos();
            if (blockPos.getY() <= 0) {
                return false;
            }
            final BlockSnapshot targetBlock = ((ServerWorld) projectile.level).createSnapshot(blockPos.getX(), blockPos.getY(), blockPos.getZ());
            final Direction side = DirectionFacingProvider.INSTANCE.getKey(blockMovingObjectPosition.getDirection()).get();
            final CollideBlockEvent.Impact event = SpongeEventFactory.createCollideBlockEventImpact(frame.currentCause(), impactPoint, targetBlock.state(), targetBlock.location().get(), side);
            cancelled = SpongeCommon.post(event);
            // Track impact block if event is not cancelled
            if (!cancelled && creator.isPresent()) {
                final BlockPos targetPos = VecHelper.toBlockPos(impactPoint.blockPosition());
                final LevelChunkBridge spongeChunk = (LevelChunkBridge) projectile.level.getChunkAt(targetPos);
                spongeChunk.bridge$addTrackedBlockPosition((Block) targetBlock.state().type(), targetPos, creator.get(), PlayerTracker.Type.NOTIFIER);
            }
        } else if (movingObjectType == HitResult.Type.ENTITY) {
            // entity
            final EntityHitResult entityMovingObjectPosition = (EntityHitResult) movingObjectPosition;
            final ArrayList<Entity> entityList = new ArrayList<>();
            entityList.add((Entity) entityMovingObjectPosition.getEntity());
            final CollideEntityEvent.Impact event = SpongeEventFactory.createCollideEntityEventImpact(frame.currentCause(), entityList, impactPoint);
            cancelled = SpongeCommon.post(event);
        }
        return cancelled;
    }
}
Also used : JukeboxBlockEntity(net.minecraft.world.level.block.entity.JukeboxBlockEntity) Entity(org.spongepowered.api.entity.Entity) LivingEntity(net.minecraft.world.entity.LivingEntity) ServerLocation(org.spongepowered.api.world.server.ServerLocation) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) ArrayList(java.util.ArrayList) Direction(org.spongepowered.api.util.Direction) CollideBlockEvent(org.spongepowered.api.event.block.CollideBlockEvent) EntityHitResult(net.minecraft.world.phys.EntityHitResult) BlockHitResult(net.minecraft.world.phys.BlockHitResult) EntityHitResult(net.minecraft.world.phys.EntityHitResult) HitResult(net.minecraft.world.phys.HitResult) ServerWorld(org.spongepowered.api.world.server.ServerWorld) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) UUID(java.util.UUID) BlockHitResult(net.minecraft.world.phys.BlockHitResult)

Example 24 with ServerWorld

use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.

the class BlockTransactionType method consumeEventsAndMarker.

@Override
protected void consumeEventsAndMarker(PhaseContext<@NonNull ?> context, final Collection<? extends ChangeBlockEvent.All> changeBlockEvents) {
    final Multimap<ResourceKey, ChangeBlockEvent.All> eventsByWorld = LinkedListMultimap.create();
    changeBlockEvents.forEach(event -> eventsByWorld.put(event.world().key(), event));
    eventsByWorld.asMap().forEach((key, events) -> {
        final Optional<ServerWorld> serverWorld = ((SpongeServer) SpongeCommon.server()).worldManager().world(key);
        if (!serverWorld.isPresent()) {
            return;
        }
        final ListMultimap<BlockPos, SpongeBlockSnapshot> positions = LinkedListMultimap.create();
        // Gather transactions that were valid
        events.stream().filter(event -> !event.isCancelled()).flatMap(event -> event.transactions().stream()).filter(BlockTransaction::isValid).forEach(transactions -> {
            // Then "put" the most recent transactions such that we have a complete rebuild of
            // each position according to what originally existed and then
            // the ultimate final block on that position
            final SpongeBlockSnapshot original = (SpongeBlockSnapshot) transactions.original();
            positions.put(original.getBlockPos(), original);
            positions.put(original.getBlockPos(), (SpongeBlockSnapshot) transactions.finalReplacement());
        });
        // just return.
        if (positions.isEmpty()) {
            return;
        }
        final ImmutableList<BlockTransactionReceipt> transactions = positions.asMap().values().stream().map(spongeBlockSnapshots -> {
            final List<SpongeBlockSnapshot> snapshots = new ArrayList<>(spongeBlockSnapshots);
            if (snapshots.isEmpty() || snapshots.size() < 2) {
                // Error case
                return Optional.<BlockTransactionReceipt>empty();
            }
            final SpongeBlockSnapshot original = snapshots.get(0);
            final SpongeBlockSnapshot result = snapshots.get(snapshots.size() - 1);
            final Operation operation = context.getBlockOperation(original, result);
            final BlockTransactionReceipt eventTransaction = new BlockTransactionReceipt(original, result, operation);
            context.postBlockTransactionApplication(original.blockChange, eventTransaction);
            return Optional.of(eventTransaction);
        }).filter(Optional::isPresent).map(Optional::get).collect(ImmutableList.toImmutableList());
        final Cause cause = PhaseTracker.getInstance().currentCause();
        SpongeCommon.post(SpongeEventFactory.createChangeBlockEventPost(cause, transactions, serverWorld.get()));
    });
}
Also used : LinkedListMultimap(com.google.common.collect.LinkedListMultimap) NonNull(org.checkerframework.checker.nullness.qual.NonNull) ServerWorld(org.spongepowered.api.world.server.ServerWorld) ListMultimap(com.google.common.collect.ListMultimap) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) SpongeServer(org.spongepowered.common.SpongeServer) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Collection(java.util.Collection) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) SpongeCommon(org.spongepowered.common.SpongeCommon) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) Multimap(com.google.common.collect.Multimap) Cause(org.spongepowered.api.event.Cause) ArrayList(java.util.ArrayList) BlockTransactionReceipt(org.spongepowered.api.block.transaction.BlockTransactionReceipt) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) BlockPos(net.minecraft.core.BlockPos) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction) ResourceKey(org.spongepowered.api.ResourceKey) Optional(java.util.Optional) Operation(org.spongepowered.api.block.transaction.Operation) BlockTransactionReceipt(org.spongepowered.api.block.transaction.BlockTransactionReceipt) Optional(java.util.Optional) Operation(org.spongepowered.api.block.transaction.Operation) ResourceKey(org.spongepowered.api.ResourceKey) ServerWorld(org.spongepowered.api.world.server.ServerWorld) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) Cause(org.spongepowered.api.event.Cause) BlockPos(net.minecraft.core.BlockPos) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 25 with ServerWorld

use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.

the class SpongeContextCalculator method accumulateContexts.

@Override
public void accumulateContexts(final Cause causes, final Consumer<Context> accumulator) {
    final ServerLocation /* @Nullable */
    location = causes.context().get(EventContextKeys.LOCATION).orElse(null);
    if (location != null) {
        final ServerWorld world = location.worldIfAvailable().orElse(null);
        if (world != null) {
            accumulator.accept(world.context());
            accumulator.accept(world.worldType().context());
        }
    }
    causes.first(RemoteConnection.class).ifPresent(connection -> {
        // TODO(zml): Wrong way to get a connection, add API?
        this.remoteIpCache.get(connection).forEach(accumulator);
        this.localIpCache.get(connection).forEach(accumulator);
        accumulator.accept(new Context(Context.LOCAL_PORT_KEY, String.valueOf(connection.virtualHost().getPort())));
        accumulator.accept(new Context(Context.LOCAL_HOST_KEY, connection.virtualHost().getHostName()));
    });
}
Also used : ServerWorld(org.spongepowered.api.world.server.ServerWorld) Context(org.spongepowered.api.service.context.Context) ServerLocation(org.spongepowered.api.world.server.ServerLocation) RemoteConnection(org.spongepowered.api.network.RemoteConnection)

Aggregations

ServerWorld (org.spongepowered.api.world.server.ServerWorld)43 Vector3d (org.spongepowered.math.vector.Vector3d)13 BlockPos (net.minecraft.core.BlockPos)12 Cause (org.spongepowered.api.event.Cause)12 BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)11 CauseStackManager (org.spongepowered.api.event.CauseStackManager)11 ServerLocation (org.spongepowered.api.world.server.ServerLocation)11 Inject (org.spongepowered.asm.mixin.injection.Inject)10 ArrayList (java.util.ArrayList)9 NonNull (org.checkerframework.checker.nullness.qual.NonNull)9 ResourceKey (org.spongepowered.api.ResourceKey)8 List (java.util.List)7 Optional (java.util.Optional)7 ServerLevel (net.minecraft.server.level.ServerLevel)7 Entity (net.minecraft.world.entity.Entity)7 Living (org.spongepowered.api.entity.living.Living)7 SpongeCommon (org.spongepowered.common.SpongeCommon)7 Component (net.kyori.adventure.text.Component)6 LivingEntity (net.minecraft.world.entity.LivingEntity)6 ItemStack (net.minecraft.world.item.ItemStack)6