Search in sources :

Example 86 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class MixinBlockLiquid method onSetBlockState.

// Capture Lava and Water mixing forming CobbleStone or Obsidian
@Inject(method = "checkForMixing", cancellable = true, locals = LocalCapture.CAPTURE_FAILSOFT, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;)Z"))
private void onSetBlockState(World worldIn, BlockPos pos, IBlockState state, CallbackInfoReturnable<Boolean> cir, boolean flag, Integer integer) {
    IBlockState newState = integer == 0 ? Blocks.OBSIDIAN.getDefaultState() : Blocks.COBBLESTONE.getDefaultState();
    ChangeBlockEvent.Modify event = SpongeCommonEventFactory.callChangeBlockEventModifyLiquidMix(worldIn, pos, newState, null);
    Transaction<BlockSnapshot> transaction = event.getTransactions().get(0);
    if (event.isCancelled() || !transaction.isValid()) {
        cir.setReturnValue(false);
        return;
    }
    boolean success = worldIn.setBlockState(pos, BlockUtil.toNative(transaction.getFinal().getState()));
    if (!success) {
        cir.setReturnValue(false);
    }
}
Also used : ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) IBlockState(net.minecraft.block.state.IBlockState) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 87 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class MixinEntityLightningBolt method onLivingTimeExpired.

@Inject(method = "onUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/effect/EntityLightningBolt;setDead()V"))
public void onLivingTimeExpired(CallbackInfo ci) {
    if (this.isDead || this.world.isRemote) {
        return;
    }
    Sponge.getCauseStackManager().pushCause(this);
    LightningEvent.Strike strike = SpongeEventFactory.createLightningEventStrike(Sponge.getCauseStackManager().getCurrentCause(), this.struckEntities, this.struckBlocks);
    Sponge.getEventManager().post(strike);
    if (!strike.isCancelled()) {
        for (Transaction<BlockSnapshot> bt : strike.getTransactions()) {
            if (bt.isValid()) {
                BlockSnapshot bs = bt.getFinal();
                this.world.setBlockState(((IMixinLocation) (Object) bs.getLocation().get()).getBlockPos(), ((IBlockState) bs.getState()));
            }
        }
        for (Entity e : strike.getEntities()) {
            ((net.minecraft.entity.Entity) e).onStruckByLightning((EntityLightningBolt) (Object) this);
        }
        SpongeImpl.postEvent(SpongeEventFactory.createLightningEventPost(Sponge.getCauseStackManager().getCurrentCause()));
    }
    Sponge.getCauseStackManager().popCause();
}
Also used : Entity(org.spongepowered.api.entity.Entity) IBlockState(net.minecraft.block.state.IBlockState) LightningEvent(org.spongepowered.api.event.action.LightningEvent) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 88 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class EntityTickPhaseState method unwind.

@SuppressWarnings("unchecked")
@Override
public void unwind(EntityTickContext phaseContext) {
    final Entity tickingEntity = phaseContext.getSource(Entity.class).orElseThrow(TrackingUtil.throwWithContext("Not ticking on an Entity!", phaseContext));
    final Optional<User> creator = phaseContext.getOwner();
    final Optional<User> notifier = phaseContext.getNotifier();
    final User entityCreator = notifier.orElseGet(() -> creator.orElse(null));
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(tickingEntity);
        phaseContext.addNotifierAndOwnerToCauseStack();
        phaseContext.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> experience = new ArrayList<Entity>(entities.size());
            final List<Entity> nonExp = new ArrayList<Entity>(entities.size());
            final List<Entity> breeding = new ArrayList<Entity>(entities.size());
            final List<Entity> projectile = new ArrayList<Entity>(entities.size());
            for (Entity entity : entities) {
                if (entity instanceof EntityXPOrb) {
                    experience.add(entity);
                } else if (tickingEntity instanceof Ageable && tickingEntity.getClass() == entity.getClass()) {
                    breeding.add(entity);
                } else if (entity instanceof Projectile) {
                    projectile.add(entity);
                } else {
                    nonExp.add(entity);
                }
            }
            if (!experience.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.EXPERIENCE);
                if (EntityUtil.isEntityDead(tickingEntity)) {
                    if (tickingEntity instanceof EntityLivingBase) {
                        CombatEntry entry = ((EntityLivingBase) tickingEntity).getCombatTracker().getBestCombatEntry();
                        if (entry != null) {
                            if (entry.damageSrc != null) {
                                Sponge.getCauseStackManager().addContext(EventContextKeys.LAST_DAMAGE_SOURCE, (DamageSource) entry.damageSrc);
                            }
                        }
                    }
                }
                final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), experience);
                if (!SpongeImpl.postEvent(event)) {
                    for (Entity entity : event.getEntities()) {
                        if (entityCreator != null) {
                            EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                        }
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
                Sponge.getCauseStackManager().removeContext(EventContextKeys.LAST_DAMAGE_SOURCE);
            }
            if (!breeding.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.BREEDING);
                if (tickingEntity instanceof EntityAnimal) {
                    final EntityPlayer playerInLove = ((EntityAnimal) tickingEntity).getLoveCause();
                    if (playerInLove != null) {
                        Sponge.getCauseStackManager().addContext(EventContextKeys.PLAYER, (Player) playerInLove);
                    }
                }
                SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), breeding);
                if (!SpongeImpl.postEvent(event)) {
                    for (Entity entity : event.getEntities()) {
                        if (entityCreator != null) {
                            EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                        }
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
                Sponge.getCauseStackManager().removeContext(EventContextKeys.PLAYER);
            }
            if (!projectile.isEmpty()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PROJECTILE);
                final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), projectile);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    for (Entity entity : event.getEntities()) {
                        if (entityCreator != null) {
                            entity.setCreator(entityCreator.getUniqueId());
                        }
                        EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                    }
                }
            }
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PASSIVE);
            final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), nonExp);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                for (Entity entity : event.getEntities()) {
                    if (entityCreator != null) {
                        entity.setCreator(entityCreator.getUniqueId());
                    }
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                }
            }
        });
        phaseContext.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(entities -> {
            final ArrayList<Entity> capturedEntities = new ArrayList<>();
            for (EntityItem entity : entities) {
                capturedEntities.add(EntityUtil.fromNative(entity));
            }
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
            final DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), capturedEntities);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                for (Entity entity : event.getEntities()) {
                    if (entityCreator != null) {
                        EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                    }
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                }
            }
        });
        phaseContext.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blockSnapshots -> TrackingUtil.processBlockCaptures(blockSnapshots, this, phaseContext));
        phaseContext.getBlockItemDropSupplier().acceptIfNotEmpty(map -> {
            final List<BlockSnapshot> capturedBlocks = phaseContext.getCapturedBlocks();
            for (BlockSnapshot snapshot : capturedBlocks) {
                final BlockPos blockPos = ((IMixinLocation) (Object) snapshot.getLocation().get()).getBlockPos();
                final Collection<EntityItem> entityItems = map.get(blockPos);
                if (!entityItems.isEmpty()) {
                    Sponge.getCauseStackManager().pushCause(snapshot);
                    Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
                    final List<Entity> items = entityItems.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                    final DropItemEvent.Destruct event = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), items);
                    SpongeImpl.postEvent(event);
                    if (!event.isCancelled()) {
                        for (Entity entity : event.getEntities()) {
                            creator.ifPresent(user -> entity.setCreator(user.getUniqueId()));
                            EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
                        }
                    }
                    Sponge.getCauseStackManager().popCause();
                }
            }
        });
        phaseContext.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(drops -> {
            final List<EntityItem> items = drops.stream().map(drop -> drop.create(EntityUtil.getMinecraftWorld(tickingEntity))).collect(Collectors.toList());
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
            final List<Entity> entities = (List<Entity>) (List<?>) items;
            if (!entities.isEmpty()) {
                DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    for (Entity droppedItem : event.getEntities()) {
                        EntityUtil.getMixinWorld(droppedItem).forceSpawnEntity(droppedItem);
                    }
                }
            }
        });
        this.fireMovementEvents(EntityUtil.toNative(tickingEntity));
    }
}
Also used : SpongeImpl(org.spongepowered.common.SpongeImpl) EntityItemFrame(net.minecraft.entity.item.EntityItemFrame) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) ExplosionContext(org.spongepowered.common.event.tracking.phase.general.ExplosionContext) Vector3d(com.flowpowered.math.vector.Vector3d) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) DamageSource(org.spongepowered.api.event.cause.entity.damage.source.DamageSource) ArrayList(java.util.ArrayList) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb) CombatEntry(net.minecraft.util.CombatEntry) TrackingUtil(org.spongepowered.common.event.tracking.TrackingUtil) Ageable(org.spongepowered.api.entity.living.Ageable) EntityHanging(net.minecraft.entity.EntityHanging) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Transaction(org.spongepowered.api.data.Transaction) Nullable(javax.annotation.Nullable) EntityItem(net.minecraft.entity.item.EntityItem) User(org.spongepowered.api.entity.living.player.User) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Collection(java.util.Collection) Sponge(org.spongepowered.api.Sponge) BlockPos(net.minecraft.util.math.BlockPos) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) IProjectile(net.minecraft.entity.IProjectile) InternalSpawnTypes(org.spongepowered.common.registry.type.event.InternalSpawnTypes) Entity(org.spongepowered.api.entity.Entity) Collectors(java.util.stream.Collectors) BlockChange(org.spongepowered.common.world.BlockChange) EntityUtil(org.spongepowered.common.entity.EntityUtil) EntityAnimal(net.minecraft.entity.passive.EntityAnimal) List(java.util.List) EntityLivingBase(net.minecraft.entity.EntityLivingBase) EntityPlayer(net.minecraft.entity.player.EntityPlayer) Transform(org.spongepowered.api.entity.Transform) World(org.spongepowered.api.world.World) VecHelper(org.spongepowered.common.util.VecHelper) Optional(java.util.Optional) Player(org.spongepowered.api.entity.living.player.Player) Projectile(org.spongepowered.api.entity.projectile.Projectile) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Entity(org.spongepowered.api.entity.Entity) User(org.spongepowered.api.entity.living.player.User) ArrayList(java.util.ArrayList) CombatEntry(net.minecraft.util.CombatEntry) Ageable(org.spongepowered.api.entity.living.Ageable) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.util.math.BlockPos) ArrayList(java.util.ArrayList) List(java.util.List) EntityAnimal(net.minecraft.entity.passive.EntityAnimal) EntityItem(net.minecraft.entity.item.EntityItem) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) IProjectile(net.minecraft.entity.IProjectile) Projectile(org.spongepowered.api.entity.projectile.Projectile) EntityLivingBase(net.minecraft.entity.EntityLivingBase) EntityPlayer(net.minecraft.entity.player.EntityPlayer) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb)

Example 89 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class EntityUtil method handleDisplaceEntityPortalEvent.

@Nullable
public static MoveEntityEvent.Teleport.Portal handleDisplaceEntityPortalEvent(Entity entityIn, int targetDimensionId, @Nullable Teleporter teleporter) {
    SpongeImplHooks.registerPortalAgentType(teleporter);
    final MinecraftServer mcServer = SpongeImpl.getServer();
    final IMixinPlayerList mixinPlayerList = (IMixinPlayerList) mcServer.getPlayerList();
    final IMixinEntity mixinEntity = (IMixinEntity) entityIn;
    final Transform<World> fromTransform = mixinEntity.getTransform();
    final WorldServer fromWorld = ((WorldServer) entityIn.world);
    final IMixinWorldServer fromMixinWorld = (IMixinWorldServer) fromWorld;
    boolean sameDimension = entityIn.dimension == targetDimensionId;
    // handle the end
    if (targetDimensionId == 1 && fromWorld.provider instanceof WorldProviderEnd) {
        targetDimensionId = 0;
    }
    WorldServer toWorld = mcServer.getWorld(targetDimensionId);
    // not being loaded then short-circuit to prevent unnecessary logic from running
    if (!sameDimension && fromWorld == toWorld) {
        return null;
    }
    if (teleporter == null) {
        teleporter = toWorld.getDefaultTeleporter();
    }
    final Map<String, String> portalAgents = fromMixinWorld.getActiveConfig().getConfig().getWorld().getPortalAgents();
    String worldName = "";
    String teleporterClassName = teleporter.getClass().getName();
    // check for new destination in config
    if (teleporterClassName.equals("net.minecraft.world.Teleporter")) {
        worldName = portalAgents.get("minecraft:default_" + toWorld.provider.getDimensionType().getName().toLowerCase(Locale.ENGLISH));
        if (worldName == null && toWorld.provider instanceof WorldProviderHell) {
            worldName = portalAgents.get("minecraft:default_nether");
        }
    } else {
        // custom
        worldName = portalAgents.get("minecraft:" + teleporter.getClass().getSimpleName());
    }
    if (worldName != null && !worldName.equals("")) {
        for (WorldProperties worldProperties : Sponge.getServer().getAllWorldProperties()) {
            if (worldProperties.getWorldName().equalsIgnoreCase(worldName)) {
                Optional<World> spongeWorld = Sponge.getServer().loadWorld(worldProperties);
                if (spongeWorld.isPresent()) {
                    toWorld = (WorldServer) spongeWorld.get();
                    teleporter = toWorld.getDefaultTeleporter();
                    if (fromWorld.provider.isNether() || toWorld.provider.isNether()) {
                        ((IMixinTeleporter) teleporter).setNetherPortalType(true);
                    } else {
                        ((IMixinTeleporter) teleporter).setNetherPortalType(false);
                    }
                }
            }
        }
    }
    adjustEntityPostionForTeleport(mixinPlayerList, entityIn, fromWorld, toWorld);
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
        TeleportingContext context = EntityPhase.State.CHANGING_DIMENSION.createPhaseContext().setTargetWorld(toWorld).buildAndSwitch()) {
        Sponge.getCauseStackManager().pushCause(teleporter);
        Sponge.getCauseStackManager().pushCause(mixinEntity);
        Sponge.getCauseStackManager().addContext(EventContextKeys.TELEPORT_TYPE, TeleportTypes.PORTAL);
        if (entityIn.isEntityAlive() && !(fromWorld.provider instanceof WorldProviderEnd)) {
            fromWorld.profiler.startSection("placing");
            // Note: We must always use placeInPortal to support mods.
            if (!((IMixinTeleporter) teleporter).isVanilla() || entityIn.getLastPortalVec() != null) {
                teleporter.placeInPortal(entityIn, entityIn.rotationYaw);
            }
            fromWorld.profiler.endSection();
        }
        // Complete phases, just because we need to. The phases don't actually do anything, because the processing resides here.
        // Grab the exit location of entity after being placed into portal
        final Transform<World> portalExitTransform = mixinEntity.getTransform().setExtent((World) toWorld);
        // Use setLocationAndAngles to avoid firing MoveEntityEvent to plugins
        mixinEntity.setLocationAndAngles(fromTransform);
        final MoveEntityEvent.Teleport.Portal event = SpongeEventFactory.createMoveEntityEventTeleportPortal(Sponge.getCauseStackManager().getCurrentCause(), fromTransform, portalExitTransform, (PortalAgent) teleporter, mixinEntity, true);
        SpongeImpl.postEvent(event);
        final Vector3i chunkPosition = mixinEntity.getLocation().getChunkPosition();
        final IMixinTeleporter toMixinTeleporter = (IMixinTeleporter) teleporter;
        final List<BlockSnapshot> capturedBlocks = context.getCapturedBlocks();
        final Transform<World> toTransform = event.getToTransform();
        if (event.isCancelled()) {
            // We need to make sure to only restore the location if
            if (!portalExitTransform.getExtent().getUniqueId().equals(mixinEntity.getLocation().getExtent().getUniqueId())) {
                // update cache
                ((IMixinTeleporter) teleporter).removePortalPositionFromCache(ChunkPos.asLong(chunkPosition.getX(), chunkPosition.getZ()));
                if (!capturedBlocks.isEmpty()) {
                    for (BlockSnapshot original : Lists.reverse(capturedBlocks)) {
                        original.restore(true, BlockChangeFlags.NONE);
                    }
                    capturedBlocks.clear();
                }
                mixinEntity.setLocationAndAngles(fromTransform);
            } else {
                // Call setTransform to let plugins know mods changed the position
                // Guarantees plugins such as Nucleus can track changed locations properly
                mixinEntity.setTransform(mixinEntity.getTransform());
            }
            return event;
        }
        if (!portalExitTransform.equals(toTransform)) {
            // if plugin set to same world, just set the transform
            if (fromWorld == toTransform.getExtent()) {
                // force cancel so we know to skip remaining logic
                event.setCancelled(true);
                // update cache
                toMixinTeleporter.removePortalPositionFromCache(ChunkPos.asLong(chunkPosition.getX(), chunkPosition.getZ()));
                // Undo created portal
                if (!capturedBlocks.isEmpty()) {
                    for (BlockSnapshot original : Lists.reverse(capturedBlocks)) {
                        original.restore(true, BlockChangeFlags.NONE);
                    }
                }
                capturedBlocks.clear();
                mixinEntity.setLocationAndAngles(toTransform);
                return event;
            }
        } else {
            if (toWorld.provider instanceof WorldProviderEnd) {
                BlockPos blockpos = entityIn.world.getTopSolidOrLiquidBlock(toWorld.getSpawnPoint());
                entityIn.moveToBlockPosAndAngles(blockpos, entityIn.rotationYaw, entityIn.rotationPitch);
            }
        }
        if (!capturedBlocks.isEmpty() && !TrackingUtil.processBlockCaptures(capturedBlocks, EntityPhase.State.CHANGING_DIMENSION, context)) {
            toMixinTeleporter.removePortalPositionFromCache(ChunkPos.asLong(chunkPosition.getX(), chunkPosition.getZ()));
        }
        if (!event.getKeepsVelocity()) {
            entityIn.motionX = 0;
            entityIn.motionY = 0;
            entityIn.motionZ = 0;
        }
        return event;
    }
}
Also used : IMixinPlayerList(org.spongepowered.common.interfaces.IMixinPlayerList) WorldProviderEnd(net.minecraft.world.WorldProviderEnd) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) IMixinTeleporter(org.spongepowered.common.interfaces.world.IMixinTeleporter) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) WorldServer(net.minecraft.world.WorldServer) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) World(org.spongepowered.api.world.World) MinecraftServer(net.minecraft.server.MinecraftServer) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Vector3i(com.flowpowered.math.vector.Vector3i) WorldProviderHell(net.minecraft.world.WorldProviderHell) TeleportingContext(org.spongepowered.common.event.tracking.phase.entity.TeleportingContext) BlockPos(net.minecraft.util.math.BlockPos) WorldProperties(org.spongepowered.api.world.storage.WorldProperties) Nullable(javax.annotation.Nullable)

Example 90 with BlockSnapshot

use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.

the class PacketUtil method firePreEvents.

private static boolean firePreEvents(Packet<?> packetIn, EntityPlayerMP playerMP) {
    if (packetIn instanceof CPacketAnimation) {
        CPacketAnimation packet = (CPacketAnimation) packetIn;
        SpongeCommonEventFactory.lastAnimationPacketTick = SpongeImpl.getServer().getTickCounter();
        SpongeCommonEventFactory.lastAnimationPlayer = new WeakReference<>(playerMP);
        HandType handType = packet.getHand() == EnumHand.MAIN_HAND ? HandTypes.MAIN_HAND : HandTypes.OFF_HAND;
        final ItemStack heldItem = playerMP.getHeldItem(packet.getHand());
        Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(heldItem));
        AnimateHandEvent event = SpongeEventFactory.createAnimateHandEvent(Sponge.getCauseStackManager().getCurrentCause(), handType, (Humanoid) playerMP);
        if (SpongeImpl.postEvent(event)) {
            return true;
        }
        return false;
    } else if (packetIn instanceof CPacketPlayerDigging) {
        SpongeCommonEventFactory.lastPrimaryPacketTick = SpongeImpl.getServer().getTickCounter();
        CPacketPlayerDigging packet = (CPacketPlayerDigging) packetIn;
        ItemStack stack = playerMP.getHeldItemMainhand();
        Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(stack));
        switch(packet.getAction()) {
            case DROP_ITEM:
            case DROP_ALL_ITEMS:
                if (!stack.isEmpty() && !playerMP.isSpectator()) {
                    ((IMixinEntityPlayerMP) playerMP).setPacketItem(stack.copy());
                }
                return false;
            case START_DESTROY_BLOCK:
            case ABORT_DESTROY_BLOCK:
            case STOP_DESTROY_BLOCK:
                final BlockPos pos = packet.getPosition();
                final Vector3d interactionPoint = VecHelper.toVector3d(pos);
                final BlockSnapshot blockSnapshot = new Location<>((World) playerMP.world, interactionPoint).createSnapshot();
                final RayTraceResult result = SpongeImplHooks.rayTraceEyes(playerMP, SpongeImplHooks.getBlockReachDistance(playerMP));
                if (SpongeCommonEventFactory.callInteractItemEventPrimary(playerMP, stack, EnumHand.MAIN_HAND, result == null ? null : VecHelper.toVector3d(result.hitVec), blockSnapshot).isCancelled()) {
                    ((IMixinEntityPlayerMP) playerMP).sendBlockChange(pos, playerMP.world.getBlockState(pos));
                    return true;
                }
                double d0 = playerMP.posX - ((double) pos.getX() + 0.5D);
                double d1 = playerMP.posY - ((double) pos.getY() + 0.5D) + 1.5D;
                double d2 = playerMP.posZ - ((double) pos.getZ() + 0.5D);
                double d3 = d0 * d0 + d1 * d1 + d2 * d2;
                double dist = SpongeImplHooks.getBlockReachDistance(playerMP) + 1;
                dist *= dist;
                if (d3 > dist) {
                    return true;
                } else if (pos.getY() >= SpongeImpl.getServer().getBuildLimit()) {
                    return true;
                }
                if (packet.getAction() == CPacketPlayerDigging.Action.START_DESTROY_BLOCK) {
                    if (SpongeCommonEventFactory.callInteractBlockEventPrimary(playerMP, blockSnapshot, EnumHand.MAIN_HAND, packet.getFacing(), result == null ? null : VecHelper.toVector3d(result.hitVec)).isCancelled()) {
                        ((IMixinEntityPlayerMP) playerMP).sendBlockChange(pos, playerMP.world.getBlockState(pos));
                        return true;
                    }
                }
                return false;
            default:
                break;
        }
    } else if (packetIn instanceof CPacketPlayerTryUseItem) {
        CPacketPlayerTryUseItem packet = (CPacketPlayerTryUseItem) packetIn;
        SpongeCommonEventFactory.lastSecondaryPacketTick = SpongeImpl.getServer().getTickCounter();
        long packetDiff = System.currentTimeMillis() - lastTryBlockPacketTimeStamp;
        // If the time between packets is small enough, use the last result.
        if (packetDiff < 100) {
            // Use previous result and avoid firing a second event
            return lastTryBlockPacketItemResult;
        }
        final ItemStack heldItem = playerMP.getHeldItem(packet.getHand());
        Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(heldItem));
        final RayTraceResult result = SpongeImplHooks.rayTraceEyes(playerMP, SpongeImplHooks.getBlockReachDistance(playerMP));
        final boolean isCancelled = SpongeCommonEventFactory.callInteractItemEventSecondary(playerMP, heldItem, packet.getHand(), result == null ? null : VecHelper.toVector3d(result.hitVec), BlockSnapshot.NONE).isCancelled();
        SpongeCommonEventFactory.callInteractBlockEventSecondary(playerMP, heldItem, result == null ? null : VecHelper.toVector3d(result.hitVec), BlockSnapshot.NONE, Direction.NONE, packet.getHand());
        if (isCancelled) {
            // Multiple slots may have been changed on the client. Right
            // clicking armor is one example - the client changes it
            // without the server telling it to.
            playerMP.sendAllContents(playerMP.openContainer, playerMP.openContainer.getInventory());
            return true;
        }
    } else if (packetIn instanceof CPacketPlayerTryUseItemOnBlock) {
        CPacketPlayerTryUseItemOnBlock packet = (CPacketPlayerTryUseItemOnBlock) packetIn;
        lastTryBlockPacketTimeStamp = System.currentTimeMillis();
        SpongeCommonEventFactory.lastSecondaryPacketTick = SpongeImpl.getServer().getTickCounter();
        Vector3d interactionPoint = VecHelper.toVector3d(packet.getPos());
        final RayTraceResult result = SpongeImplHooks.rayTraceEyes(playerMP, SpongeImplHooks.getBlockReachDistance(playerMP));
        BlockSnapshot blockSnapshot = new Location<>((World) playerMP.world, interactionPoint).createSnapshot();
        final ItemStack heldItem = playerMP.getHeldItem(packet.getHand());
        Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(heldItem));
        boolean isCancelled = SpongeCommonEventFactory.callInteractItemEventSecondary(playerMP, heldItem, packet.getHand(), result == null ? null : VecHelper.toVector3d(result.hitVec), blockSnapshot).isCancelled();
        lastTryBlockPacketItemResult = isCancelled;
        if (isCancelled) {
            // update client
            BlockPos pos = packet.getPos();
            playerMP.connection.sendPacket(new SPacketBlockChange(playerMP.world, pos));
            playerMP.connection.sendPacket(new SPacketBlockChange(playerMP.world, pos.offset(packet.getDirection())));
            // See above
            playerMP.sendAllContents(playerMP.openContainer, playerMP.openContainer.getInventory());
            return true;
        }
    }
    return false;
}
Also used : CPacketPlayerDigging(net.minecraft.network.play.client.CPacketPlayerDigging) HandType(org.spongepowered.api.data.type.HandType) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) RayTraceResult(net.minecraft.util.math.RayTraceResult) AnimateHandEvent(org.spongepowered.api.event.entity.living.humanoid.AnimateHandEvent) CPacketAnimation(net.minecraft.network.play.client.CPacketAnimation) CPacketPlayerTryUseItemOnBlock(net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock) SPacketBlockChange(net.minecraft.network.play.server.SPacketBlockChange) CPacketPlayerTryUseItem(net.minecraft.network.play.client.CPacketPlayerTryUseItem) Vector3d(com.flowpowered.math.vector.Vector3d) BlockPos(net.minecraft.util.math.BlockPos) ItemStack(net.minecraft.item.ItemStack) Location(org.spongepowered.api.world.Location)

Aggregations

BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)150 World (org.spongepowered.api.world.World)67 Listener (org.spongepowered.api.event.Listener)66 Location (org.spongepowered.api.world.Location)26 BlockState (org.spongepowered.api.block.BlockState)22 Entity (org.spongepowered.api.entity.Entity)21 BlockPos (net.minecraft.util.math.BlockPos)20 CauseStackManager (org.spongepowered.api.event.CauseStackManager)19 Region (br.net.fabiozumbi12.RedProtect.Sponge.Region)18 IBlockState (net.minecraft.block.state.IBlockState)18 Transaction (org.spongepowered.api.data.Transaction)18 BlockType (org.spongepowered.api.block.BlockType)15 Player (org.spongepowered.api.entity.living.player.Player)15 Direction (org.spongepowered.api.util.Direction)15 ChangeBlockEvent (org.spongepowered.api.event.block.ChangeBlockEvent)14 SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)14 Vector3d (com.flowpowered.math.vector.Vector3d)13 ArrayList (java.util.ArrayList)13 User (org.spongepowered.api.entity.living.player.User)11 ItemStack (org.spongepowered.api.item.inventory.ItemStack)11