Search in sources :

Example 1 with Packet

use of org.spongepowered.api.network.channel.packet.Packet in project SpongeCommon by SpongePowered.

the class SpongePacketChannel method handleResponsePacket.

private void handleResponsePacket(final EngineConnection connection, final int transactionId, @Nullable final ChannelBuf payload, final int dynamicOpcode) {
    final TransactionStore store = ConnectionUtil.getTransactionStore(connection);
    final TransactionStore.Entry stored = store.remove(transactionId);
    if (stored == null) {
        return;
    }
    final TransactionData<RequestPacket<Packet>, Packet> transactionData = (TransactionData<RequestPacket<Packet>, Packet>) stored.getData();
    final TransactionResult result = payload == null ? TransactionResult.failure(new NoResponseException()) : TransactionResult.success(payload);
    this.handleTransactionResponse(connection, transactionData, result, dynamicOpcode);
}
Also used : TransactionStore(org.spongepowered.common.network.channel.TransactionStore) RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) Packet(org.spongepowered.api.network.channel.packet.Packet) TransactionResult(org.spongepowered.common.network.channel.TransactionResult) RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) NoResponseException(org.spongepowered.api.network.channel.NoResponseException)

Example 2 with Packet

use of org.spongepowered.api.network.channel.packet.Packet in project SpongeCommon by SpongePowered.

the class SpongePacketChannel method sendResponsePacketTo.

private <P extends RequestPacket<R>, R extends Packet> void sendResponsePacketTo(final EngineConnection connection, @Nullable final SpongeTransactionalPacketBinding<P, R> requestBinding, @Nullable final R packet, final int transactionId) {
    final boolean isLoginPhase = ConnectionUtil.isLoginPhase(connection);
    final EngineConnectionSide<?> side = connection.side();
    final ChannelBuf payload = this.manager().getBufferAllocator().buffer();
    final Supplier<net.minecraft.network.protocol.Packet<?>> mcPacketSupplier;
    if (packet == null || requestBinding instanceof SpongeFixedTransactionalPacketBinding) {
        final int type = packet == null ? SpongePacketChannel.TYPE_NO_RESPONSE : SpongePacketChannel.TYPE_RESPONSE;
        if (isLoginPhase) {
            if (side == EngineConnectionSide.CLIENT) {
                payload.writeVarLong(SpongePacketChannel.packTypeAndValue(type, 0));
                mcPacketSupplier = () -> PacketUtil.createLoginPayloadResponse(payload, transactionId);
            } else {
                payload.writeVarLong(SpongePacketChannel.packTypeAndValue(type, transactionId));
                mcPacketSupplier = () -> PacketUtil.createLoginPayloadRequest(this.key(), payload, Constants.Channels.LOGIN_PAYLOAD_TRANSACTION_ID);
            }
        } else {
            payload.writeVarLong(SpongePacketChannel.packTypeAndValue(type, transactionId));
            mcPacketSupplier = () -> PacketUtil.createPlayPayload(this.key(), payload, side);
        }
    } else {
        // Dynamic opcode
        final int opcode = this.requireBinding(packet.getClass()).opcode();
        if (isLoginPhase) {
            if (side == EngineConnectionSide.CLIENT) {
                payload.writeVarLong(SpongePacketChannel.packTypeAndValue(SpongePacketChannel.TYPE_DYNAMIC_RESPONSE, opcode));
                mcPacketSupplier = () -> PacketUtil.createLoginPayloadResponse(payload, transactionId);
            } else {
                payload.writeVarLong(SpongePacketChannel.packTypeAndValue(SpongePacketChannel.TYPE_DYNAMIC_RESPONSE, transactionId));
                payload.writeVarInt(opcode);
                mcPacketSupplier = () -> PacketUtil.createLoginPayloadRequest(this.key(), payload, Constants.Channels.LOGIN_PAYLOAD_TRANSACTION_ID);
            }
        } else {
            payload.writeVarLong(SpongePacketChannel.packTypeAndValue(SpongePacketChannel.TYPE_DYNAMIC_RESPONSE, transactionId));
            payload.writeVarInt(opcode);
            mcPacketSupplier = () -> PacketUtil.createPlayPayload(this.key(), payload, side);
        }
    }
    try {
        this.encodePayload(payload, packet);
    } catch (final Throwable ex) {
        this.handleException(connection, new ChannelIOException("Failed to encode request response", ex), null);
        return;
    }
    final net.minecraft.network.protocol.Packet<?> mcPacket = mcPacketSupplier.get();
    PacketSender.sendTo(connection, mcPacket);
}
Also used : RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) Packet(org.spongepowered.api.network.channel.packet.Packet) ChannelIOException(org.spongepowered.api.network.channel.ChannelIOException) ChannelBuf(org.spongepowered.api.network.channel.ChannelBuf)

Example 3 with Packet

use of org.spongepowered.api.network.channel.packet.Packet in project SpongeCommon by SpongePowered.

the class SpongePacketChannel method handleTransactionResponse.

@Override
protected void handleTransactionResponse(final EngineConnection connection, final Object stored, final TransactionResult result) {
    if (result.isSuccess()) {
        final ChannelBuf payload = result.getPayload();
        final long typeAndValue = payload.readVarLong();
        final int type = SpongePacketChannel.extractType(typeAndValue);
        final int value = SpongePacketChannel.extractValue(typeAndValue);
        if (type == SpongePacketChannel.TYPE_RESPONSE || type == SpongePacketChannel.TYPE_NO_RESPONSE || type == SpongePacketChannel.TYPE_DYNAMIC_RESPONSE) {
            final TransactionData<RequestPacket<Packet>, Packet> transactionData = (TransactionData<RequestPacket<Packet>, Packet>) stored;
            if (type == SpongePacketChannel.TYPE_RESPONSE) {
                this.handleTransactionResponse(connection, transactionData, result, SpongePacketChannel.NO_DYNAMIC_OPCODE);
            } else if (type == SpongePacketChannel.TYPE_NO_RESPONSE) {
                this.handleTransactionResponse(connection, transactionData, TransactionResult.failure(new NoResponseException()), SpongePacketChannel.NO_DYNAMIC_OPCODE);
            } else {
                this.handleTransactionResponse(connection, transactionData, result, value);
            }
        } else {
            this.handleException(connection, new ChannelIOException("Unknown packet type: " + type), null);
        }
    }
}
Also used : RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) Packet(org.spongepowered.api.network.channel.packet.Packet) RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) ChannelIOException(org.spongepowered.api.network.channel.ChannelIOException) ChannelBuf(org.spongepowered.api.network.channel.ChannelBuf) NoResponseException(org.spongepowered.api.network.channel.NoResponseException)

Example 4 with Packet

use of org.spongepowered.api.network.channel.packet.Packet in project SpongeCommon by SpongePowered.

the class SpongePacketChannel method handleRequestPacket.

private <C extends EngineConnection> void handleRequestPacket(final C connection, final int opcode, final int transactionId, final ChannelBuf payload) {
    final SpongePacketBinding<Packet> binding = this.requireBinding(opcode);
    final Packet request;
    try {
        request = this.decodePayload(binding.getPacketConstructor(), payload);
    } catch (final Throwable ex) {
        this.sendResponsePacketTo(connection, null, null, transactionId);
        this.handleException(connection, new ChannelIOException("Failed to decode request packet", ex), null);
        return;
    }
    boolean success = false;
    Throwable responseFailure = null;
    // TODO: Send cause of failure somehow?
    if (binding instanceof SpongeTransactionalPacketBinding) {
        final RequestPacketHandler<RequestPacket<Packet>, Packet, C> handler = ((SpongeTransactionalPacketBinding) binding).getRequestHandler(connection);
        if (handler != null) {
            final SpongeRequestPacketResponse<Packet> requestPacketResponse = new SpongeRequestPacketResponse<Packet>() {

                @Override
                protected void fail0(final ChannelException exception) {
                    // TODO: Use response failure?
                    SpongePacketChannel.this.sendResponsePacketTo(connection, null, null, transactionId);
                }

                @Override
                protected void success0(final Packet response) {
                    SpongePacketChannel.this.sendResponsePacketTo(connection, (SpongeTransactionalPacketBinding) binding, response, transactionId);
                }
            };
            try {
                handler.handleRequest((RequestPacket) request, connection, requestPacketResponse);
                success = true;
            } catch (final Throwable ex) {
                this.handleException(connection, new ChannelException("Failed to handle request packet", ex), null);
                responseFailure = ex;
            }
        }
    }
    if (!success) {
        // TODO: Use response failure?
        this.sendResponsePacketTo(connection, null, null, transactionId);
    }
}
Also used : RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) Packet(org.spongepowered.api.network.channel.packet.Packet) RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) ChannelIOException(org.spongepowered.api.network.channel.ChannelIOException) ChannelException(org.spongepowered.api.network.channel.ChannelException)

Example 5 with Packet

use of org.spongepowered.api.network.channel.packet.Packet in project SpongeCommon by SpongePowered.

the class PacketUtil method createPlayPayload.

public static net.minecraft.network.protocol.Packet<?> createPlayPayload(final ResourceKey channel, final ChannelBuf payload, final EngineConnectionSide<?> side) {
    if (side == EngineConnectionSide.CLIENT) {
        final ServerboundCustomPayloadPacketAccessor packet = (ServerboundCustomPayloadPacketAccessor) new ServerboundCustomPayloadPacket();
        packet.accessor$identifier((ResourceLocation) (Object) channel);
        packet.accessor$data((FriendlyByteBuf) payload);
        return (net.minecraft.network.protocol.Packet<?>) packet;
    } else if (side == EngineConnectionSide.SERVER) {
        final ClientboundCustomPayloadPacketAccessor packet = (ClientboundCustomPayloadPacketAccessor) new ClientboundCustomPayloadPacket();
        packet.accessor$identifier((ResourceLocation) (Object) channel);
        packet.accessor$data((FriendlyByteBuf) payload);
        return (net.minecraft.network.protocol.Packet<?>) packet;
    } else {
        throw new UnsupportedOperationException();
    }
}
Also used : FriendlyByteBuf(net.minecraft.network.FriendlyByteBuf) ServerboundCustomQueryPacket(net.minecraft.network.protocol.login.ServerboundCustomQueryPacket) ClientboundCustomPayloadPacket(net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket) ServerboundCustomPayloadPacket(net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket) Packet(org.spongepowered.api.network.channel.packet.Packet) ClientboundCustomQueryPacket(net.minecraft.network.protocol.login.ClientboundCustomQueryPacket) ServerboundCustomPayloadPacketAccessor(org.spongepowered.common.accessor.network.protocol.game.ServerboundCustomPayloadPacketAccessor) ClientboundCustomPayloadPacket(net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket) ServerboundCustomPayloadPacket(net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket) ClientboundCustomPayloadPacketAccessor(org.spongepowered.common.accessor.network.protocol.game.ClientboundCustomPayloadPacketAccessor) ResourceLocation(net.minecraft.resources.ResourceLocation)

Aggregations

Packet (org.spongepowered.api.network.channel.packet.Packet)11 RequestPacket (org.spongepowered.api.network.channel.packet.RequestPacket)10 ChannelBuf (org.spongepowered.api.network.channel.ChannelBuf)6 ChannelIOException (org.spongepowered.api.network.channel.ChannelIOException)5 ChannelException (org.spongepowered.api.network.channel.ChannelException)3 NoResponseException (org.spongepowered.api.network.channel.NoResponseException)2 TransactionStore (org.spongepowered.common.network.channel.TransactionStore)2 Supplier (java.util.function.Supplier)1 FriendlyByteBuf (net.minecraft.network.FriendlyByteBuf)1 ClientboundCustomPayloadPacket (net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket)1 ServerboundCustomPayloadPacket (net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket)1 ClientboundCustomQueryPacket (net.minecraft.network.protocol.login.ClientboundCustomQueryPacket)1 ServerboundCustomQueryPacket (net.minecraft.network.protocol.login.ServerboundCustomQueryPacket)1 ResourceLocation (net.minecraft.resources.ResourceLocation)1 EngineConnection (org.spongepowered.api.network.EngineConnection)1 RequestPacketHandler (org.spongepowered.api.network.channel.packet.RequestPacketHandler)1 ClientboundCustomPayloadPacketAccessor (org.spongepowered.common.accessor.network.protocol.game.ClientboundCustomPayloadPacketAccessor)1 ServerboundCustomPayloadPacketAccessor (org.spongepowered.common.accessor.network.protocol.game.ServerboundCustomPayloadPacketAccessor)1 TransactionResult (org.spongepowered.common.network.channel.TransactionResult)1