Search in sources :

Example 1 with IMixinInventoryPlayer

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

the class MixinNetHandlerPlayServer method processUseEntity.

/**
 * @author blood - April 5th, 2016
 *
 * @reason Due to all the changes we now do for this packet, it is much easier
 * to read it all with an overwrite. Information detailing on why each change
 * was made can be found in comments below.
 *
 * @param packetIn The entity use packet
 */
@Overwrite
public void processUseEntity(CPacketUseEntity packetIn) {
    // All packets received by server are handled first on the Netty Thread
    if (!SpongeImpl.getServer().isCallingFromMinecraftThread()) {
        if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT) {
            // when INTERACT_AT does not return a successful result.
            return;
        } else {
            // queue packet for main thread
            PacketThreadUtil.checkThreadAndEnqueue(packetIn, (NetHandlerPlayServer) (Object) this, this.player.getServerWorld());
            return;
        }
    }
    // Sponge end
    WorldServer worldserver = this.serverController.getWorld(this.player.dimension);
    Entity entity = packetIn.getEntityFromWorld(worldserver);
    this.player.markPlayerActive();
    if (entity != null) {
        boolean flag = this.player.canEntityBeSeen(entity);
        // 6 blocks
        double d0 = 36.0D;
        if (!flag) {
            // 1.5 blocks
            d0 = 9.0D;
        }
        if (this.player.getDistanceSq(entity) < d0) {
            if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT_AT) {
                // Sponge start - Fire interact events
                EnumHand hand = packetIn.getHand();
                ItemStack itemstack = hand != null ? this.player.getHeldItem(hand) : ItemStack.EMPTY;
                Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(itemstack));
                SpongeCommonEventFactory.lastSecondaryPacketTick = this.serverController.getTickCounter();
                // Is interaction allowed with item in hand
                if (SpongeCommonEventFactory.callInteractItemEventSecondary(this.player, itemstack, hand, VecHelper.toVector3d(packetIn.getHitVec()), entity).isCancelled() || SpongeCommonEventFactory.callInteractEntityEventSecondary(this.player, entity, hand, VecHelper.toVector3d(entity.getPositionVector().add(packetIn.getHitVec()))).isCancelled()) {
                    // Restore held item in hand
                    int index = ((IMixinInventoryPlayer) this.player.inventory).getHeldItemIndex(hand);
                    Slot slot = this.player.openContainer.getSlotFromInventory(this.player.inventory, index);
                    sendPacket(new SPacketSetSlot(this.player.openContainer.windowId, slot.slotNumber, itemstack));
                    // which means that we need to force an update
                    if (itemstack.getItem() == Items.LEAD) {
                        // Detach entity again
                        sendPacket(new SPacketEntityAttach(entity, null));
                    } else {
                        // Other cases may involve a specific DataParameter of the entity
                        // We fix the client state by marking it as dirty so it will be updated on the client the next tick
                        DataParameter<?> parameter = findModifiedEntityInteractDataParameter(itemstack, entity);
                        if (parameter != null) {
                            entity.getDataManager().setDirty(parameter);
                        }
                    }
                    return;
                }
                // If INTERACT_AT is not successful, run the INTERACT logic
                if (entity.applyPlayerInteraction(this.player, packetIn.getHitVec(), hand) != EnumActionResult.SUCCESS) {
                    this.player.interactOn(entity, hand);
                }
            // Sponge end
            } else if (packetIn.getAction() == CPacketUseEntity.Action.ATTACK) {
                // Sponge start - Call interact event
                // Will be null in the packet during ATTACK
                EnumHand hand = EnumHand.MAIN_HAND;
                ItemStack itemstack = this.player.getHeldItem(hand);
                SpongeCommonEventFactory.lastPrimaryPacketTick = this.serverController.getTickCounter();
                Vector3d hitVec = null;
                if (packetIn.getHitVec() == null) {
                    final RayTraceResult result = SpongeImplHooks.rayTraceEyes(player, SpongeImplHooks.getBlockReachDistance(player));
                    hitVec = result == null ? null : VecHelper.toVector3d(result.hitVec);
                }
                if (SpongeCommonEventFactory.callInteractItemEventPrimary(this.player, itemstack, hand, hitVec, entity).isCancelled()) {
                    ((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
                    return;
                }
                if (entity instanceof EntityItem || entity instanceof EntityXPOrb || entity instanceof EntityArrow || entity == this.player) {
                    this.disconnect(new TextComponentTranslation("multiplayer.disconnect.invalid_entity_attacked"));
                    this.serverController.logWarning("Player " + this.player.getName() + " tried to attack an invalid entity");
                    return;
                }
                // Sponge start
                if (entity instanceof Player && !((World) this.player.world).getProperties().isPVPEnabled()) {
                    // PVP is disabled, ignore
                    return;
                }
                if (SpongeCommonEventFactory.callInteractEntityEventPrimary(this.player, entity, hand, hitVec).isCancelled()) {
                    ((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
                    return;
                }
                // Sponge end
                this.player.attackTargetEntityWithCurrentItem(entity);
            }
        }
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Entity(net.minecraft.entity.Entity) EntityArrow(net.minecraft.entity.projectile.EntityArrow) TextComponentTranslation(net.minecraft.util.text.TextComponentTranslation) 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) RayTraceResult(net.minecraft.util.math.RayTraceResult) WorldServer(net.minecraft.world.WorldServer) World(org.spongepowered.api.world.World) SPacketEntityAttach(net.minecraft.network.play.server.SPacketEntityAttach) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) Vector3d(com.flowpowered.math.vector.Vector3d) EnumHand(net.minecraft.util.EnumHand) SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) Slot(net.minecraft.inventory.Slot) SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) ItemStack(net.minecraft.item.ItemStack) EntityItem(net.minecraft.entity.item.EntityItem) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 2 with IMixinInventoryPlayer

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

the class SpongeCommonEventFactory method callPlayerChangeInventoryPickupPreEvent.

public static boolean callPlayerChangeInventoryPickupPreEvent(EntityPlayer player, EntityItem itemToPickup, int pickupDelay, UUID creator) {
    ItemStack stack = itemToPickup.getItem();
    Sponge.getCauseStackManager().pushCause(player);
    ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(stack);
    ChangeInventoryEvent.Pickup.Pre event = SpongeEventFactory.createChangeInventoryEventPickupPre(Sponge.getCauseStackManager().getCurrentCause(), Optional.empty(), Collections.singletonList(snapshot), snapshot, ((Item) itemToPickup), ((Inventory) player.inventory));
    SpongeImpl.postEvent(event);
    Sponge.getCauseStackManager().popCause();
    if (event.isCancelled()) {
        return false;
    }
    if (event.getCustom().isPresent()) {
        List<ItemStackSnapshot> list = event.getCustom().get();
        if (list.isEmpty()) {
            itemToPickup.getItem().setCount(0);
            return false;
        }
        boolean fullTransfer = true;
        IMixinInventoryPlayer capture = (IMixinInventoryPlayer) player.inventory;
        capture.setCapture(true);
        for (ItemStackSnapshot item : list) {
            org.spongepowered.api.item.inventory.ItemStack itemStack = item.createStack();
            player.inventory.addItemStackToInventory(ItemStackUtil.toNative(itemStack));
            if (!itemStack.isEmpty()) {
                fullTransfer = false;
                break;
            }
        }
        capture.setCapture(false);
        if (!fullTransfer) {
            for (SlotTransaction trans : capture.getCapturedTransactions()) {
                trans.getSlot().set(trans.getOriginal().createStack());
            }
            return false;
        }
        if (!callPlayerChangeInventoryPickupEvent(player, capture)) {
            return false;
        }
        itemToPickup.getItem().setCount(0);
    }
    return true;
}
Also used : SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) EntityItem(net.minecraft.entity.item.EntityItem) Item(org.spongepowered.api.entity.Item) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ItemStack(net.minecraft.item.ItemStack) IMixinInventory(org.spongepowered.common.interfaces.IMixinInventory) OrderedInventory(org.spongepowered.api.item.inventory.type.OrderedInventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) CarriedInventory(org.spongepowered.api.item.inventory.type.CarriedInventory) Inventory(org.spongepowered.api.item.inventory.Inventory) CustomInventory(org.spongepowered.common.item.inventory.custom.CustomInventory) IInventory(net.minecraft.inventory.IInventory)

Example 3 with IMixinInventoryPlayer

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

the class MixinEntityItem method onAddItemStackToInventory.

@Redirect(method = "onCollideWithPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/InventoryPlayer;addItemStackToInventory(Lnet/minecraft/item/ItemStack;)Z"))
public boolean onAddItemStackToInventory(InventoryPlayer inventory, ItemStack itemStack, EntityPlayer player) {
    IMixinInventoryPlayer inv = (IMixinInventoryPlayer) inventory;
    inv.setCapture(true);
    boolean added = inventory.addItemStackToInventory(itemStack);
    inv.setCapture(false);
    inv.getCapturedTransactions();
    if (!SpongeCommonEventFactory.callPlayerChangeInventoryPickupEvent(player, inv)) {
        return false;
    }
    return added;
}
Also used : IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 4 with IMixinInventoryPlayer

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

the class SpongeCommandManager method process.

@Override
public CommandResult process(CommandSource source, String commandLine) {
    final String[] argSplit = commandLine.split(" ", 2);
    Sponge.getCauseStackManager().pushCause(source);
    final SendCommandEvent event = SpongeEventFactory.createSendCommandEvent(Sponge.getCauseStackManager().getCurrentCause(), argSplit.length > 1 ? argSplit[1] : "", argSplit[0], CommandResult.empty());
    Sponge.getGame().getEventManager().post(event);
    Sponge.getCauseStackManager().popCause();
    if (event.isCancelled()) {
        return event.getResult();
    }
    // Only the first part of argSplit is used at the moment, do the other in the future if needed.
    argSplit[0] = event.getCommand();
    commandLine = event.getCommand();
    if (!event.getArguments().isEmpty()) {
        commandLine = commandLine + ' ' + event.getArguments();
    }
    try {
        try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
            // Since we know we are in the main thread, this is safe to do without a thread check
            CommandPhaseContext context = GeneralPhase.State.COMMAND.createPhaseContext().source(source).addCaptures().addEntityDropCaptures().buildAndSwitch()) {
            if (source instanceof EntityPlayer) {
                // Enable player inventory capture
                ((IMixinInventoryPlayer) ((EntityPlayer) source).inventory).setCapture(true);
            }
            Sponge.getCauseStackManager().pushCause(source);
            final CommandResult result = this.dispatcher.process(source, commandLine);
            return result;
        } catch (InvocationCommandException ex) {
            if (ex.getCause() != null) {
                throw ex.getCause();
            }
        } catch (CommandPermissionException ex) {
            Text text = ex.getText();
            if (text != null) {
                source.sendMessage(error(text));
            }
        } catch (CommandException ex) {
            Text text = ex.getText();
            if (text != null) {
                source.sendMessage(error(text));
            }
            if (ex.shouldIncludeUsage()) {
                final Optional<CommandMapping> mapping = this.dispatcher.get(argSplit[0], source);
                if (mapping.isPresent()) {
                    Text usage;
                    if (ex instanceof ArgumentParseException.WithUsage) {
                        usage = ((ArgumentParseException.WithUsage) ex).getUsage();
                    } else {
                        usage = mapping.get().getCallable().getUsage(source);
                    }
                    source.sendMessage(error(t("Usage: /%s %s", argSplit[0], usage)));
                }
            }
        }
    } catch (Throwable thr) {
        Text.Builder excBuilder;
        if (thr instanceof TextMessageException) {
            Text text = ((TextMessageException) thr).getText();
            excBuilder = text == null ? Text.builder("null") : Text.builder();
        } else {
            excBuilder = Text.builder(String.valueOf(thr.getMessage()));
        }
        if (source.hasPermission("sponge.debug.hover-stacktrace")) {
            final StringWriter writer = new StringWriter();
            thr.printStackTrace(new PrintWriter(writer));
            excBuilder.onHover(TextActions.showText(Text.of(writer.toString().replace("\t", "    ").replace("\r\n", "\n").replace("\r", // I mean I guess somebody could be running this on like OS 9?
            "\n"))));
        }
        source.sendMessage(error(t("Error occurred while executing command: %s", excBuilder.build())));
        this.logger.error(TextSerializers.PLAIN.serialize(t("Error occurred while executing command '%s' for source %s: %s", commandLine, source.toString(), String.valueOf(thr.getMessage()))), thr);
    }
    return CommandResult.empty();
}
Also used : CommandPermissionException(org.spongepowered.api.command.CommandPermissionException) Optional(java.util.Optional) ArgumentParseException(org.spongepowered.api.command.args.ArgumentParseException) Text(org.spongepowered.api.text.Text) InvocationCommandException(org.spongepowered.api.command.InvocationCommandException) CommandException(org.spongepowered.api.command.CommandException) CommandResult(org.spongepowered.api.command.CommandResult) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) InvocationCommandException(org.spongepowered.api.command.InvocationCommandException) StringWriter(java.io.StringWriter) CommandPhaseContext(org.spongepowered.common.event.tracking.phase.general.CommandPhaseContext) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) SendCommandEvent(org.spongepowered.api.event.command.SendCommandEvent) EntityPlayer(net.minecraft.entity.player.EntityPlayer) TextMessageException(org.spongepowered.api.util.TextMessageException) PrintWriter(java.io.PrintWriter)

Example 5 with IMixinInventoryPlayer

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

the class MixinEntityPlayer method onSetItemStackToSlot.

@Inject(method = "setItemStackToSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/NonNullList;set(ILjava/lang/Object;)Ljava/lang/Object;"))
private void onSetItemStackToSlot(EntityEquipmentSlot slotIn, ItemStack stack, CallbackInfo ci) {
    if (((IMixinInventoryPlayer) this.inventory).capturesTransactions()) {
        if (slotIn == EntityEquipmentSlot.MAINHAND) {
            ItemStack orig = this.inventory.mainInventory.get(this.inventory.currentItem);
            Slot slot = ((PlayerInventory) this.inventory).getMain().getHotbar().getSlot(SlotIndex.of(this.inventory.currentItem)).get();
            ((IMixinInventoryPlayer) this.inventory).getCapturedTransactions().add(new SlotTransaction(slot, ItemStackUtil.snapshotOf(orig), ItemStackUtil.snapshotOf(stack)));
        } else if (slotIn == EntityEquipmentSlot.OFFHAND) {
            ItemStack orig = this.inventory.offHandInventory.get(0);
            Slot slot = ((PlayerInventory) this.inventory).getOffhand();
            ((IMixinInventoryPlayer) this.inventory).getCapturedTransactions().add(new SlotTransaction(slot, ItemStackUtil.snapshotOf(orig), ItemStackUtil.snapshotOf(stack)));
        } else if (slotIn.getSlotType() == EntityEquipmentSlot.Type.ARMOR) {
            ItemStack orig = this.inventory.armorInventory.get(slotIn.getIndex());
            Slot slot = ((PlayerInventory) this.inventory).getEquipment().getSlot(SlotIndex.of(slotIn.getIndex())).get();
            ((IMixinInventoryPlayer) this.inventory).getCapturedTransactions().add(new SlotTransaction(slot, ItemStackUtil.snapshotOf(orig), ItemStackUtil.snapshotOf(stack)));
        }
    }
}
Also used : IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) EntityEquipmentSlot(net.minecraft.inventory.EntityEquipmentSlot) Slot(org.spongepowered.api.item.inventory.Slot) PlayerInventory(org.spongepowered.api.item.inventory.entity.PlayerInventory) ItemStack(net.minecraft.item.ItemStack) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Inject(org.spongepowered.asm.mixin.injection.Inject)

Aggregations

IMixinInventoryPlayer (org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer)7 SlotTransaction (org.spongepowered.api.item.inventory.transaction.SlotTransaction)4 EntityPlayer (net.minecraft.entity.player.EntityPlayer)3 ItemStack (net.minecraft.item.ItemStack)3 Inventory (org.spongepowered.api.item.inventory.Inventory)3 EntityItem (net.minecraft.entity.item.EntityItem)2 WorldServer (net.minecraft.world.WorldServer)2 Entity (org.spongepowered.api.entity.Entity)2 Player (org.spongepowered.api.entity.living.player.Player)2 CauseStackManager (org.spongepowered.api.event.CauseStackManager)2 StackFrame (org.spongepowered.api.event.CauseStackManager.StackFrame)2 ChangeInventoryEvent (org.spongepowered.api.event.item.inventory.ChangeInventoryEvent)2 Vector3d (com.flowpowered.math.vector.Vector3d)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Map (java.util.Map)1 Optional (java.util.Optional)1 UUID (java.util.UUID)1