Search in sources :

Example 1 with ServerboundInteractPacket

use of com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket in project Geyser by GeyserMC.

the class BedrockInteractTranslator method translate.

@Override
public void translate(GeyserSession session, InteractPacket packet) {
    Entity entity;
    if (packet.getRuntimeEntityId() == session.getPlayerEntity().getGeyserId()) {
        // Player is not in entity cache
        entity = session.getPlayerEntity();
    } else {
        entity = session.getEntityCache().getEntityByGeyserId(packet.getRuntimeEntityId());
    }
    if (entity == null)
        return;
    switch(packet.getAction()) {
        case INTERACT:
            if (session.getPlayerInventory().getItemInHand().getJavaId() == session.getItemMappings().getStoredItems().shield().getJavaId()) {
                break;
            }
            ServerboundInteractPacket interactPacket = new ServerboundInteractPacket(entity.getEntityId(), InteractAction.INTERACT, Hand.MAIN_HAND, session.isSneaking());
            session.sendDownstreamPacket(interactPacket);
            break;
        case DAMAGE:
            ServerboundInteractPacket attackPacket = new ServerboundInteractPacket(entity.getEntityId(), InteractAction.ATTACK, Hand.MAIN_HAND, session.isSneaking());
            session.sendDownstreamPacket(attackPacket);
            break;
        case LEAVE_VEHICLE:
            ServerboundPlayerCommandPacket sneakPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SNEAKING);
            session.sendDownstreamPacket(sneakPacket);
            break;
        case MOUSEOVER:
            // Handle the buttons for mobile - "Mount", etc; and the suggestions for console - "ZL: Mount", etc
            if (packet.getRuntimeEntityId() != 0) {
                Entity interactEntity = session.getEntityCache().getEntityByGeyserId(packet.getRuntimeEntityId());
                session.setMouseoverEntity(interactEntity);
                if (interactEntity == null) {
                    return;
                }
                interactEntity.updateInteractiveTag();
            } else {
                if (session.getMouseoverEntity() != null) {
                    // No interactive tag should be sent
                    session.setMouseoverEntity(null);
                    session.getPlayerEntity().getDirtyMetadata().put(EntityData.INTERACTIVE_TAG, "");
                    session.getPlayerEntity().updateBedrockMetadata();
                }
            }
            break;
        case OPEN_INVENTORY:
            if (session.getOpenInventory() == null) {
                Entity ridingEntity = session.getPlayerEntity().getVehicle();
                if (ridingEntity instanceof AbstractHorseEntity) {
                    if (ridingEntity.getFlag(EntityFlag.TAMED)) {
                        // We should request to open the horse inventory instead
                        ServerboundPlayerCommandPacket openHorseWindowPacket = new ServerboundPlayerCommandPacket(session.getPlayerEntity().getEntityId(), PlayerState.OPEN_HORSE_INVENTORY);
                        session.sendDownstreamPacket(openHorseWindowPacket);
                    }
                } else {
                    session.setOpenInventory(session.getPlayerInventory());
                    ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket();
                    containerOpenPacket.setId((byte) 0);
                    containerOpenPacket.setType(ContainerType.INVENTORY);
                    containerOpenPacket.setUniqueEntityId(-1);
                    containerOpenPacket.setBlockPosition(entity.getPosition().toInt());
                    session.sendUpstreamPacket(containerOpenPacket);
                }
            }
            break;
    }
}
Also used : AbstractHorseEntity(org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity) AbstractHorseEntity(org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity) Entity(org.geysermc.geyser.entity.type.Entity) ServerboundInteractPacket(com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket) ServerboundPlayerCommandPacket(com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket) ContainerOpenPacket(com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket)

Example 2 with ServerboundInteractPacket

use of com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket in project Geyser by GeyserMC.

the class BedrockActionTranslator method translate.

@Override
public void translate(GeyserSession session, PlayerActionPacket packet) {
    SessionPlayerEntity entity = session.getPlayerEntity();
    // Send book update before any player action
    if (packet.getAction() != PlayerActionType.RESPAWN) {
        session.getBookEditCache().checkForSend();
    }
    Vector3i vector = packet.getBlockPosition();
    switch(packet.getAction()) {
        case RESPAWN:
            // Respawn process is finished and the server and client are both OK with respawning.
            EntityEventPacket eventPacket = new EntityEventPacket();
            eventPacket.setRuntimeEntityId(entity.getGeyserId());
            eventPacket.setType(EntityEventType.RESPAWN);
            eventPacket.setData(0);
            session.sendUpstreamPacket(eventPacket);
            // Resend attributes or else in rare cases the user can think they're not dead when they are, upon joining the server
            UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
            attributesPacket.setRuntimeEntityId(entity.getGeyserId());
            attributesPacket.getAttributes().addAll(entity.getAttributes().values());
            session.sendUpstreamPacket(attributesPacket);
            break;
        case START_SWIMMING:
            if (!entity.getFlag(EntityFlag.SWIMMING)) {
                ServerboundPlayerCommandPacket startSwimPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SPRINTING);
                session.sendDownstreamPacket(startSwimPacket);
                session.setSwimming(true);
            }
            break;
        case STOP_SWIMMING:
            // Prevent packet spam when Bedrock players are crawling near the edge of a block
            if (!session.getCollisionManager().mustPlayerCrawlHere()) {
                ServerboundPlayerCommandPacket stopSwimPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.STOP_SPRINTING);
                session.sendDownstreamPacket(stopSwimPacket);
                session.setSwimming(false);
            }
            break;
        case START_GLIDE:
            // Otherwise gliding will not work in creative
            ServerboundPlayerAbilitiesPacket playerAbilitiesPacket = new ServerboundPlayerAbilitiesPacket(false);
            session.sendDownstreamPacket(playerAbilitiesPacket);
        case STOP_GLIDE:
            ServerboundPlayerCommandPacket glidePacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_ELYTRA_FLYING);
            session.sendDownstreamPacket(glidePacket);
            break;
        case START_SNEAK:
            ServerboundPlayerCommandPacket startSneakPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SNEAKING);
            session.sendDownstreamPacket(startSneakPacket);
            session.startSneaking();
            break;
        case STOP_SNEAK:
            ServerboundPlayerCommandPacket stopSneakPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.STOP_SNEAKING);
            session.sendDownstreamPacket(stopSneakPacket);
            session.stopSneaking();
            break;
        case START_SPRINT:
            if (!entity.getFlag(EntityFlag.SWIMMING)) {
                ServerboundPlayerCommandPacket startSprintPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SPRINTING);
                session.sendDownstreamPacket(startSprintPacket);
                session.setSprinting(true);
            }
            break;
        case STOP_SPRINT:
            if (!entity.getFlag(EntityFlag.SWIMMING)) {
                ServerboundPlayerCommandPacket stopSprintPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.STOP_SPRINTING);
                session.sendDownstreamPacket(stopSprintPacket);
            }
            session.setSprinting(false);
            break;
        case DROP_ITEM:
            Position position = new Position(vector.getX(), vector.getY(), vector.getZ());
            ServerboundPlayerActionPacket dropItemPacket = new ServerboundPlayerActionPacket(PlayerAction.DROP_ITEM, position, Direction.VALUES[packet.getFace()]);
            session.sendDownstreamPacket(dropItemPacket);
            break;
        case STOP_SLEEP:
            ServerboundPlayerCommandPacket stopSleepingPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.LEAVE_BED);
            session.sendDownstreamPacket(stopSleepingPacket);
            break;
        case BLOCK_INTERACT:
            // Client means to interact with a block; cancel bucket interaction, if any
            if (session.getBucketScheduledFuture() != null) {
                session.getBucketScheduledFuture().cancel(true);
                session.setBucketScheduledFuture(null);
            }
            // Otherwise handled in BedrockInventoryTransactionTranslator
            break;
        case START_BREAK:
            // Start the block breaking animation
            if (session.getGameMode() != GameMode.CREATIVE) {
                int blockState = session.getGeyser().getWorldManager().getBlockAt(session, vector);
                LevelEventPacket startBreak = new LevelEventPacket();
                startBreak.setType(LevelEventType.BLOCK_START_BREAK);
                startBreak.setPosition(vector.toFloat());
                double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(blockState)) * 20;
                startBreak.setData((int) (65535 / breakTime));
                session.setBreakingBlock(blockState);
                session.sendUpstreamPacket(startBreak);
            }
            // Account for fire - the client likes to hit the block behind.
            Vector3i fireBlockPos = BlockUtils.getBlockPosition(vector, packet.getFace());
            int blockUp = session.getGeyser().getWorldManager().getBlockAt(session, fireBlockPos);
            String identifier = BlockRegistries.JAVA_IDENTIFIERS.get().get(blockUp);
            if (identifier.startsWith("minecraft:fire") || identifier.startsWith("minecraft:soul_fire")) {
                ServerboundPlayerActionPacket startBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.START_DIGGING, new Position(fireBlockPos.getX(), fireBlockPos.getY(), fireBlockPos.getZ()), Direction.VALUES[packet.getFace()]);
                session.sendDownstreamPacket(startBreakingPacket);
                if (session.getGameMode() == GameMode.CREATIVE) {
                    break;
                }
            }
            position = new Position(vector.getX(), vector.getY(), vector.getZ());
            ServerboundPlayerActionPacket startBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.START_DIGGING, position, Direction.VALUES[packet.getFace()]);
            session.sendDownstreamPacket(startBreakingPacket);
            break;
        case CONTINUE_BREAK:
            if (session.getGameMode() == GameMode.CREATIVE) {
                break;
            }
            Vector3f vectorFloat = vector.toFloat();
            LevelEventPacket continueBreakPacket = new LevelEventPacket();
            continueBreakPacket.setType(LevelEventType.PARTICLE_CRACK_BLOCK);
            continueBreakPacket.setData((session.getBlockMappings().getBedrockBlockId(session.getBreakingBlock())) | (packet.getFace() << 24));
            continueBreakPacket.setPosition(vectorFloat);
            session.sendUpstreamPacket(continueBreakPacket);
            // Update the break time in the event that player conditions changed (jumping, effects applied)
            LevelEventPacket updateBreak = new LevelEventPacket();
            updateBreak.setType(LevelEventType.BLOCK_UPDATE_BREAK);
            updateBreak.setPosition(vectorFloat);
            double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(session.getBreakingBlock())) * 20;
            updateBreak.setData((int) (65535 / breakTime));
            session.sendUpstreamPacket(updateBreak);
            break;
        case ABORT_BREAK:
            if (session.getGameMode() != GameMode.CREATIVE) {
                // As of 1.16.210: item frame items are taken out here.
                // Survival also sends START_BREAK, but by attaching our process here adventure mode also works
                Entity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, vector);
                if (itemFrameEntity != null) {
                    ServerboundInteractPacket interactPacket = new ServerboundInteractPacket(itemFrameEntity.getEntityId(), InteractAction.ATTACK, Hand.MAIN_HAND, session.isSneaking());
                    session.sendDownstreamPacket(interactPacket);
                    break;
                }
            }
            position = new Position(vector.getX(), vector.getY(), vector.getZ());
            ServerboundPlayerActionPacket abortBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.CANCEL_DIGGING, position, Direction.DOWN);
            session.sendDownstreamPacket(abortBreakingPacket);
            LevelEventPacket stopBreak = new LevelEventPacket();
            stopBreak.setType(LevelEventType.BLOCK_STOP_BREAK);
            stopBreak.setPosition(vector.toFloat());
            stopBreak.setData(0);
            session.setBreakingBlock(BlockStateValues.JAVA_AIR_ID);
            session.sendUpstreamPacket(stopBreak);
            break;
        case STOP_BREAK:
            // Handled in BedrockInventoryTransactionTranslator
            break;
        case DIMENSION_CHANGE_SUCCESS:
            // sometimes the client doesn't feel like loading
            PlayStatusPacket spawnPacket = new PlayStatusPacket();
            spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
            session.sendUpstreamPacket(spawnPacket);
            attributesPacket = new UpdateAttributesPacket();
            attributesPacket.setRuntimeEntityId(entity.getGeyserId());
            attributesPacket.getAttributes().addAll(entity.getAttributes().values());
            session.sendUpstreamPacket(attributesPacket);
            session.getEntityCache().updateBossBars();
            break;
        case JUMP:
            // Increase block break time while jumping
            entity.setOnGround(false);
            break;
    }
}
Also used : ItemFrameEntity(org.geysermc.geyser.entity.type.ItemFrameEntity) Entity(org.geysermc.geyser.entity.type.Entity) SessionPlayerEntity(org.geysermc.geyser.entity.type.player.SessionPlayerEntity) Position(com.github.steveice10.mc.protocol.data.game.entity.metadata.Position) ServerboundPlayerAbilitiesPacket(com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket) ServerboundPlayerActionPacket(com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket) Vector3f(com.nukkitx.math.vector.Vector3f) SessionPlayerEntity(org.geysermc.geyser.entity.type.player.SessionPlayerEntity) Vector3i(com.nukkitx.math.vector.Vector3i) ServerboundInteractPacket(com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket) ServerboundPlayerCommandPacket(com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket)

Example 3 with ServerboundInteractPacket

use of com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket in project Geyser by GeyserMC.

the class BedrockItemFrameDropItemTranslator method translate.

@Override
public void translate(GeyserSession session, ItemFrameDropItemPacket packet) {
    Entity entity = ItemFrameEntity.getItemFrameEntity(session, packet.getBlockPosition());
    if (entity != null) {
        ServerboundInteractPacket interactPacket = new ServerboundInteractPacket(entity.getEntityId(), InteractAction.ATTACK, Hand.MAIN_HAND, session.isSneaking());
        session.sendDownstreamPacket(interactPacket);
    }
}
Also used : ItemFrameEntity(org.geysermc.geyser.entity.type.ItemFrameEntity) Entity(org.geysermc.geyser.entity.type.Entity) ServerboundInteractPacket(com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket)

Aggregations

ServerboundInteractPacket (com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket)3 Entity (org.geysermc.geyser.entity.type.Entity)3 ServerboundPlayerCommandPacket (com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket)2 ItemFrameEntity (org.geysermc.geyser.entity.type.ItemFrameEntity)2 Position (com.github.steveice10.mc.protocol.data.game.entity.metadata.Position)1 ServerboundPlayerAbilitiesPacket (com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket)1 ServerboundPlayerActionPacket (com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket)1 Vector3f (com.nukkitx.math.vector.Vector3f)1 Vector3i (com.nukkitx.math.vector.Vector3i)1 ContainerOpenPacket (com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket)1 AbstractHorseEntity (org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity)1 SessionPlayerEntity (org.geysermc.geyser.entity.type.player.SessionPlayerEntity)1