Search in sources :

Example 6 with IMixinEntityPlayerMP

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP in project SpongeCommon by SpongePowered.

the class DropItemWithHotkeyState method unwind.

@Override
public void unwind(InventoryPacketContext context) {
    final EntityPlayerMP player = context.getPacketPlayer();
    // final ItemStack usedStack = context.getItemUsed();
    // final ItemStackSnapshot usedSnapshot = ItemStackUtil.snapshotOf(usedStack);
    final Entity spongePlayer = EntityUtil.fromNative(player);
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(spongePlayer);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
        context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blocks -> TrackingUtil.processBlockCaptures(blocks, this, context));
        context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
            final ArrayList<Entity> entities = new ArrayList<>();
            for (EntityItem item : items) {
                entities.add(EntityUtil.fromNative(item));
            }
            int usedButton = 0;
            if (context.getPacket() instanceof CPacketPlayerDigging) {
                final CPacketPlayerDigging packetIn = context.getPacket();
                usedButton = packetIn.getAction() == CPacketPlayerDigging.Action.DROP_ITEM ? PacketPhase.PACKET_BUTTON_PRIMARY_ID : 1;
            } else {
                final CPacketClickWindow packetIn = context.getPacket();
                usedButton = packetIn.getUsedButton();
            }
            Transaction<ItemStackSnapshot> cursorTrans = new Transaction<>(ItemStackSnapshot.NONE, ItemStackSnapshot.NONE);
            final IMixinContainer mixinContainer = ContainerUtil.toMixin(player.openContainer);
            List<SlotTransaction> slotTrans = mixinContainer.getCapturedTransactions();
            ClickInventoryEvent.Drop dropItemEvent = ((DropItemWithHotkeyState) this).createInventoryEvent(player, ContainerUtil.fromNative(player.openContainer), cursorTrans, Lists.newArrayList(slotTrans), entities, usedButton);
            SpongeImpl.postEvent(dropItemEvent);
            if (dropItemEvent.isCancelled() || PacketPhaseUtil.allTransactionsInvalid(dropItemEvent.getTransactions())) {
                ((IMixinEntityPlayerMP) player).restorePacketItem(EnumHand.MAIN_HAND);
                PacketPhaseUtil.handleSlotRestore(player, player.openContainer, dropItemEvent.getTransactions(), true);
            } else {
                processSpawnedEntities(player, dropItemEvent);
            }
            slotTrans.clear();
            mixinContainer.setCaptureInventory(false);
        });
        context.getCapturedEntityDropSupplier().acceptIfNotEmpty(itemMapping -> {
        });
        final IMixinContainer mixinContainer = ContainerUtil.toMixin(player.openContainer);
        mixinContainer.setCaptureInventory(false);
        mixinContainer.getCapturedTransactions().clear();
    }
}
Also used : CPacketPlayerDigging(net.minecraft.network.play.client.CPacketPlayerDigging) Entity(org.spongepowered.api.entity.Entity) CPacketClickWindow(net.minecraft.network.play.client.CPacketClickWindow) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) ArrayList(java.util.ArrayList) ClickInventoryEvent(org.spongepowered.api.event.item.inventory.ClickInventoryEvent) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) CauseStackManager(org.spongepowered.api.event.CauseStackManager) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) EntityItem(net.minecraft.entity.item.EntityItem)

Example 7 with IMixinEntityPlayerMP

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP 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;
}
Also used : Player(org.spongepowered.api.entity.living.player.Player) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) EntityPlayer(net.minecraft.entity.player.EntityPlayer) CPacketPlayer(net.minecraft.network.play.client.CPacketPlayer) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Vector3d(com.flowpowered.math.vector.Vector3d) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) World(org.spongepowered.api.world.World) Location(org.spongepowered.api.world.Location) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 8 with IMixinEntityPlayerMP

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callDestructEntityEventDeath.

public static DestructEntityEvent.Death callDestructEntityEventDeath(EntityLivingBase entity, DamageSource source) {
    final MessageEvent.MessageFormatter formatter = new MessageEvent.MessageFormatter();
    MessageChannel originalChannel;
    MessageChannel channel;
    Text originalMessage;
    Optional<User> sourceCreator = Optional.empty();
    boolean messageCancelled = false;
    if (entity instanceof EntityPlayerMP) {
        originalChannel = channel = ((IMixinEntityPlayerMP) entity).getDeathMessageChannel();
    } else {
        originalChannel = MessageChannel.TO_NONE;
        channel = MessageChannel.TO_NONE;
    }
    if (source instanceof EntityDamageSource) {
        EntityDamageSource damageSource = (EntityDamageSource) source;
        IMixinEntity spongeEntity = (IMixinEntity) damageSource.getImmediateSource();
        if (spongeEntity != null) {
            sourceCreator = spongeEntity.getCreatorUser();
        }
    }
    originalMessage = SpongeTexts.toText(entity.getCombatTracker().getDeathMessage());
    formatter.getBody().add(new MessageEvent.DefaultBodyApplier(originalMessage));
    final boolean isMainThread = Sponge.isServerAvailable() && Sponge.getServer().isMainThread();
    // checks need to be made here since entities can die on the client world.
    try (final StackFrame frame = isMainThread ? Sponge.getCauseStackManager().pushCauseFrame() : null) {
        if (isMainThread) {
            Sponge.getCauseStackManager().pushCause(source);
            if (sourceCreator.isPresent()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, sourceCreator.get());
            }
        }
        final Cause cause = isMainThread ? Sponge.getCauseStackManager().getCurrentCause() : Cause.of(EventContext.empty(), source);
        DestructEntityEvent.Death event = SpongeEventFactory.createDestructEntityEventDeath(cause, originalChannel, Optional.of(channel), formatter, (Living) entity, entity.world.getGameRules().getBoolean("keepInventory"), messageCancelled);
        SpongeImpl.postEvent(event);
        Text message = event.getMessage();
        if (!event.isMessageCancelled() && !message.isEmpty()) {
            event.getChannel().ifPresent(eventChannel -> eventChannel.send(entity, event.getMessage()));
        }
        return event;
    }
}
Also used : User(org.spongepowered.api.entity.living.player.User) MessageEvent(org.spongepowered.api.event.message.MessageEvent) Text(org.spongepowered.api.text.Text) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) EntityDamageSource(net.minecraft.util.EntityDamageSource) MessageChannel(org.spongepowered.api.text.channel.MessageChannel) DestructEntityEvent(org.spongepowered.api.event.entity.DestructEntityEvent) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) Cause(org.spongepowered.api.event.cause.Cause) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP)

Example 9 with IMixinEntityPlayerMP

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP in project SpongeCommon by SpongePowered.

the class EntityUtil method transferPlayerToDimension.

// Used by PlayerList#transferPlayerToDimension and EntityPlayerMP#changeDimension.
// This method should NOT fire a teleport event as that should always be handled by the caller.
public static void transferPlayerToDimension(MoveEntityEvent.Teleport.Portal event, EntityPlayerMP playerIn) {
    WorldServer fromWorld = (WorldServer) event.getFromTransform().getExtent();
    WorldServer toWorld = (WorldServer) event.getToTransform().getExtent();
    playerIn.dimension = WorldManager.getClientDimensionId(playerIn, toWorld);
    toWorld.getChunkProvider().loadChunk(event.getToTransform().getLocation().getChunkPosition().getX(), event.getToTransform().getLocation().getChunkPosition().getZ());
    // Support vanilla clients teleporting to custom dimensions
    final int dimensionId = playerIn.dimension;
    // Send dimension registration
    if (((IMixinEntityPlayerMP) playerIn).usesCustomClient()) {
        WorldManager.sendDimensionRegistration(playerIn, toWorld.provider);
    } else {
        // Force vanilla client to refresh its chunk cache if same dimension type
        if (fromWorld != toWorld && fromWorld.provider.getDimensionType() == toWorld.provider.getDimensionType()) {
            playerIn.connection.sendPacket(new SPacketRespawn((dimensionId >= 0 ? -1 : 0), toWorld.getDifficulty(), toWorld.getWorldInfo().getTerrainType(), playerIn.interactionManager.getGameType()));
        }
    }
    playerIn.connection.sendPacket(new SPacketRespawn(dimensionId, toWorld.getDifficulty(), toWorld.getWorldInfo().getTerrainType(), playerIn.interactionManager.getGameType()));
    fromWorld.removeEntityDangerously(playerIn);
    playerIn.isDead = false;
    // we do not need to call transferEntityToWorld as we already have the correct transform and created the portal in handleDisplaceEntityPortalEvent
    ((IMixinEntity) playerIn).setLocationAndAngles(event.getToTransform());
    playerIn.setWorld(toWorld);
    toWorld.spawnEntity(playerIn);
    toWorld.updateEntityWithOptionalForce(playerIn, false);
    SpongeImpl.getServer().getPlayerList().preparePlayer(playerIn, fromWorld);
    playerIn.connection.setPlayerLocation(playerIn.posX, playerIn.posY, playerIn.posZ, playerIn.rotationYaw, playerIn.rotationPitch);
    playerIn.interactionManager.setWorld(toWorld);
    SpongeImpl.getServer().getPlayerList().updateTimeAndWeatherForPlayer(playerIn, toWorld);
    SpongeImpl.getServer().getPlayerList().syncPlayerInventory(playerIn);
    // Update reducedDebugInfo game rule
    playerIn.connection.sendPacket(new SPacketEntityStatus(playerIn, toWorld.getGameRules().getBoolean(DefaultGameRules.REDUCED_DEBUG_INFO) ? (byte) 22 : 23));
    for (PotionEffect potioneffect : playerIn.getActivePotionEffects()) {
        playerIn.connection.sendPacket(new SPacketEntityEffect(playerIn.getEntityId(), potioneffect));
    }
    ((IMixinEntityPlayerMP) playerIn).refreshXpHealthAndFood();
    SpongeImplHooks.handlePostChangeDimensionEvent(playerIn, fromWorld, toWorld);
}
Also used : PotionEffect(net.minecraft.potion.PotionEffect) WorldServer(net.minecraft.world.WorldServer) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) SPacketRespawn(net.minecraft.network.play.server.SPacketRespawn) SPacketEntityStatus(net.minecraft.network.play.server.SPacketEntityStatus) SPacketEntityEffect(net.minecraft.network.play.server.SPacketEntityEffect)

Example 10 with IMixinEntityPlayerMP

use of org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP in project SpongeCommon by SpongePowered.

the class HealthScalingProcessor method set.

@Override
protected boolean set(EntityPlayerMP dataHolder, Double value) {
    if (value < 1D) {
        return false;
    }
    if (value > Float.MAX_VALUE) {
        return false;
    }
    final IMixinEntityPlayerMP mixinPlayer = (IMixinEntityPlayerMP) dataHolder;
    if (value == 20D) {
        mixinPlayer.setHealthScale(20);
        mixinPlayer.setHealthScaled(true);
        return true;
    }
    mixinPlayer.setHealthScale(value);
    return true;
}
Also used : IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP)

Aggregations

IMixinEntityPlayerMP (org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP)12 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)5 SPacketEntityEffect (net.minecraft.network.play.server.SPacketEntityEffect)4 PotionEffect (net.minecraft.potion.PotionEffect)4 WorldServer (net.minecraft.world.WorldServer)4 IMixinEntity (org.spongepowered.common.interfaces.entity.IMixinEntity)4 EntityPlayer (net.minecraft.entity.player.EntityPlayer)3 SPacketRespawn (net.minecraft.network.play.server.SPacketRespawn)3 Player (org.spongepowered.api.entity.living.player.Player)3 World (org.spongepowered.api.world.World)3 IMixinWorldServer (org.spongepowered.common.interfaces.world.IMixinWorldServer)3 Vector3d (com.flowpowered.math.vector.Vector3d)2 Entity (net.minecraft.entity.Entity)2 NetHandlerPlayServer (net.minecraft.network.NetHandlerPlayServer)2 CPacketPlayer (net.minecraft.network.play.client.CPacketPlayer)2 SPacketEntityStatus (net.minecraft.network.play.server.SPacketEntityStatus)2 SPacketSpawnPosition (net.minecraft.network.play.server.SPacketSpawnPosition)2 MinecraftServer (net.minecraft.server.MinecraftServer)2 BlockPos (net.minecraft.util.math.BlockPos)2 CauseStackManager (org.spongepowered.api.event.CauseStackManager)2