Untitled

 avatar
unknown
java
a year ago
5.5 kB
7
Indexable
package com.trexmine.guiapi.handlers;

import com.trexmine.guiapi.gui.ClickListener;
import com.trexmine.guiapi.gui.Gui;
import com.trexmine.guiapi.gui.GuiItem;
import com.trexmine.guiapi.gui.GuiManager;
import com.trexmine.guiapi.packets.GuiPacketPlayInWindowClick;
import com.trexmine.guiapi.wrapper.WrappedPacketPlayInCloseWindow;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.RequiredArgsConstructor;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;

@RequiredArgsConstructor
public final class PacketReader extends ChannelInboundHandlerAdapter {

    private final GuiManager guiManager;
    private final Player player;

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        guiManager.dispose(player);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof GuiPacketPlayInWindowClick) {
            handleGuiWindowClick((GuiPacketPlayInWindowClick) msg);
            return;
        }
        if (msg instanceof PacketPlayInCloseWindow) {
            handleWindowClose((PacketPlayInCloseWindow) msg);
        }
        super.channelRead(ctx, msg);
    }

    private void handleGuiWindowClick(GuiPacketPlayInWindowClick clickPacket) {
        Gui gui = guiManager.getGui(player);

        short slot = clickPacket.getSlot();
        EntityPlayer handle = ((CraftPlayer) player).getHandle();

        handle.u().postToMainThread(() -> {
            Container container = handle.activeContainer;

            if (container == null) {
                return;
            }

            if (!gui.isInBounds(slot)) { // Click is not inside virtual inventory
                cancelTransaction(handle, clickPacket);
                handle.playerConnection.sendPacket(new PacketPlayOutWindowItems(container.windowId, container.a()));
                return;
            }

            ClickListener<? extends Gui> clickListener = gui.getClickListener();
            GuiItem item = gui.getItem(slot);

            ClickType clickType = toClickType(clickPacket.getButton(), clickPacket.getMode(), slot < 0);
            boolean cancelled = clickListener.onClick(player, slot, item, clickType);

            if (gui.isInBounds(slot) && (clickType.isShiftClick() || clickType.isKeyboardClick())) {
                cancelTransaction(handle, clickPacket);
                handle.playerConnection.sendPacket(new PacketPlayOutWindowItems(container.windowId, container.a()));
            }

            if (cancelled && (item != null || gui.getCursor() != null)) {
                gui.updateItems();
            } else if (item != null) {
                gui.setCursor(item);
            }
        });
    }

    private void cancelTransaction(EntityPlayer handle, GuiPacketPlayInWindowClick clickPacket) {
        PlayerConnection connection = handle.playerConnection;

        // Don't confirm inventory transaction client-side
        connection.sendPacket(new PacketPlayOutTransaction(
                clickPacket.getWindowId(),
                clickPacket.getActionNumber(),
                false
        ));
        // Unset cursor
        connection.sendPacket(new PacketPlayOutSetSlot(-1, -1, null));
    }

    private void handleWindowClose(PacketPlayInCloseWindow msg) {
        WrappedPacketPlayInCloseWindow wrappedClosePacket = new WrappedPacketPlayInCloseWindow(msg);

        if (wrappedClosePacket.getWindowId() == guiManager.getId(player)) {
            guiManager.dispose(player);
        }
    }

    private ClickType toClickType(int button, int mode, boolean clickedOutside) {
        switch (mode) {
            case 0:
                return button == 0 ? ClickType.LEFT : ClickType.RIGHT;
            case 1:
                return button == 0 ? ClickType.SHIFT_LEFT : ClickType.SHIFT_RIGHT;
            case 2:
                return ClickType.NUMBER_KEY;
            case 3:
                return ClickType.MIDDLE;
            case 4:
                if (clickedOutside) {
                    return button == 0 ? ClickType.WINDOW_BORDER_LEFT : ClickType.WINDOW_BORDER_RIGHT;
                } else {
                    return button == 0 ? ClickType.DROP : ClickType.CONTROL_DROP;
                }
            case 5:
                if (clickedOutside) {
                    switch (button) {
                        case 2: // Left mouse drag (End)
                        case 0: // Left mouse drag (Start)
                            return ClickType.LEFT;
                        case 6: // Right mouse drag (End)
                        case 4: // Right mouse drag (Start)
                            return ClickType.RIGHT;
                        default:
                            return ClickType.UNKNOWN;
                    }
                } else {
                    if (button == 1) {
                        return ClickType.LEFT; // Add slot for left-mouse drag
                    } else if (button == 5) {
                        return ClickType.RIGHT; // Add slot for right-mouse drag
                    } else {
                        return ClickType.UNKNOWN;
                    }
                }
            case 6:
                return button == 0 ? ClickType.DOUBLE_CLICK : ClickType.UNKNOWN;
            default:
                return ClickType.UNKNOWN;
        }
    }
}
Editor is loading...
Leave a Comment