Search in sources :

Example 1 with TransactionStore

use of org.spongepowered.common.network.channel.TransactionStore 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 TransactionStore

use of org.spongepowered.common.network.channel.TransactionStore in project SpongeCommon by SpongePowered.

the class SpongePacketChannel method sendRequestPacketTo.

private <P extends RequestPacket<R>, R extends Packet> void sendRequestPacketTo(final EngineConnection connection, final P packet, final CompletableFuture<?> future, @Nullable final Consumer<R> response, @Nullable final Runnable sendSuccess) {
    final SpongeTransactionalPacketBinding<P, R> binding = (SpongeTransactionalPacketBinding) this.requireBinding(packet.getClass());
    final TransactionStore transactionStore = ConnectionUtil.getTransactionStore(connection);
    final int transactionId = transactionStore.nextId();
    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 (isLoginPhase) {
        if (side == EngineConnectionSide.CLIENT) {
            payload.writeString(this.key().formatted());
            payload.writeVarLong(SpongePacketChannel.packTypeAndValue(SpongePacketChannel.TYPE_REQUEST, transactionId));
            payload.writeVarInt(binding.opcode());
            mcPacketSupplier = () -> PacketUtil.createLoginPayloadResponse(payload, Constants.Channels.LOGIN_PAYLOAD_TRANSACTION_ID);
        } else {
            payload.writeVarLong(SpongePacketChannel.packTypeAndValue(SpongePacketChannel.TYPE_REQUEST, binding.opcode()));
            mcPacketSupplier = () -> PacketUtil.createLoginPayloadRequest(this.key(), payload, transactionId);
        }
    } else {
        payload.writeVarLong(SpongePacketChannel.packTypeAndValue(SpongePacketChannel.TYPE_REQUEST, transactionId));
        payload.writeVarInt(binding.opcode());
        mcPacketSupplier = () -> PacketUtil.createPlayPayload(this.key(), payload, side);
    }
    try {
        this.encodePayload(payload, packet);
    } catch (final Throwable ex) {
        this.handleException(connection, ex, future);
        return;
    }
    if (response != null) {
        final TransactionData<P, R> transactionData = new TransactionData<>(packet, binding, response, future);
        transactionStore.put(transactionId, this, transactionData);
    }
    final net.minecraft.network.protocol.Packet<?> mcPacket = mcPacketSupplier.get();
    PacketSender.sendTo(connection, mcPacket, sendFuture -> {
        if (!sendFuture.isSuccess()) {
            this.handleException(connection, sendFuture.cause(), future);
            // and remove it from the store
            if (response != null) {
                transactionStore.remove(transactionId);
            }
        } else if (sendSuccess != null) {
            sendSuccess.run();
        }
    });
}
Also used : RequestPacket(org.spongepowered.api.network.channel.packet.RequestPacket) Packet(org.spongepowered.api.network.channel.packet.Packet) ChannelBuf(org.spongepowered.api.network.channel.ChannelBuf) TransactionStore(org.spongepowered.common.network.channel.TransactionStore)

Example 3 with TransactionStore

use of org.spongepowered.common.network.channel.TransactionStore in project SpongeCommon by SpongePowered.

the class SpongeRawLoginDataChannel method sendTo.

@Override
public CompletableFuture<ChannelBuf> sendTo(final EngineConnection connection, final Consumer<ChannelBuf> payload) {
    ConnectionUtil.checkHandshakePhase(connection);
    final CompletableFuture<ChannelBuf> future = new CompletableFuture<>();
    final ChannelBuf buf;
    try {
        buf = this.parent.encodePayload(payload);
    } catch (final Throwable t) {
        this.parent.handleException(connection, t, future);
        return future;
    }
    final TransactionStore transactionStore = ConnectionUtil.getTransactionStore(connection);
    final int transactionId = transactionStore.nextId();
    final Consumer<TransactionResult> resultConsumer = result -> {
        if (result.isSuccess()) {
            future.complete(result.getPayload());
        } else {
            this.parent.handleException(connection, result.getCause(), future);
        }
    };
    final Packet<?> mcPacket = PacketUtil.createLoginPayloadRequest(this.parent.key(), buf, transactionId);
    PacketSender.sendTo(connection, mcPacket, sendFuture -> {
        if (sendFuture.isSuccess()) {
            transactionStore.put(transactionId, this.parent, resultConsumer);
        } else {
            // The packet already failed before it could reach the client
            future.completeExceptionally(sendFuture.cause());
        }
    });
    return future;
}
Also used : PacketUtil(org.spongepowered.common.network.channel.PacketUtil) SpongeChannel(org.spongepowered.common.network.channel.SpongeChannel) TransactionStore(org.spongepowered.common.network.channel.TransactionStore) EngineConnection(org.spongepowered.api.network.EngineConnection) ChannelException(org.spongepowered.api.network.channel.ChannelException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) EngineConnectionSide(org.spongepowered.api.network.EngineConnectionSide) CompletableFuture(java.util.concurrent.CompletableFuture) PacketSender(org.spongepowered.common.network.channel.PacketSender) ChannelBuf(org.spongepowered.api.network.channel.ChannelBuf) Objects(java.util.Objects) Consumer(java.util.function.Consumer) RawDataChannel(org.spongepowered.api.network.channel.raw.RawDataChannel) ConnectionUtil(org.spongepowered.common.network.channel.ConnectionUtil) Map(java.util.Map) Packet(net.minecraft.network.protocol.Packet) RawHandshakeDataRequestResponse(org.spongepowered.api.network.channel.raw.handshake.RawHandshakeDataRequestResponse) TransactionResult(org.spongepowered.common.network.channel.TransactionResult) RawHandshakeDataRequestHandler(org.spongepowered.api.network.channel.raw.handshake.RawHandshakeDataRequestHandler) RawHandshakeDataChannel(org.spongepowered.api.network.channel.raw.handshake.RawHandshakeDataChannel) TransactionStore(org.spongepowered.common.network.channel.TransactionStore) CompletableFuture(java.util.concurrent.CompletableFuture) TransactionResult(org.spongepowered.common.network.channel.TransactionResult) ChannelBuf(org.spongepowered.api.network.channel.ChannelBuf)

Example 4 with TransactionStore

use of org.spongepowered.common.network.channel.TransactionStore in project SpongeCommon by SpongePowered.

the class ServerLoginPacketListenerImplMixin_Vanilla method impl$onTick.

@Inject(method = "tick", at = @At("HEAD"))
private void impl$onTick(final CallbackInfo ci) {
    if (this.state == ServerLoginPacketListenerImpl.State.NEGOTIATING) {
        final ServerSideConnection connection = (ServerSideConnection) this;
        if (this.impl$handshakeState == ServerLoginPacketListenerImplMixin_Vanilla.HANDSHAKE_NOT_STARTED) {
            this.impl$handshakeState = ServerLoginPacketListenerImplMixin_Vanilla.HANDSHAKE_CLIENT_TYPE;
            ((SpongeChannelManager) Sponge.channelManager()).requestClientType(connection).thenAccept(result -> {
                this.impl$handshakeState = ServerLoginPacketListenerImplMixin_Vanilla.HANDSHAKE_SYNC_CHANNEL_REGISTRATIONS;
            });
        } else if (this.impl$handshakeState == ServerLoginPacketListenerImplMixin_Vanilla.HANDSHAKE_SYNC_CHANNEL_REGISTRATIONS) {
            ((SpongeChannelManager) Sponge.channelManager()).sendLoginChannelRegistry(connection).thenAccept(result -> {
                final Cause cause = Cause.of(EventContext.empty(), this);
                final ServerSideConnectionEvent.Handshake event = SpongeEventFactory.createServerSideConnectionEventHandshake(cause, connection);
                SpongeCommon.post(event);
                this.impl$handshakeState = ServerLoginPacketListenerImplMixin_Vanilla.HANDSHAKE_SYNC_PLUGIN_DATA;
            });
        } else if (this.impl$handshakeState == ServerLoginPacketListenerImplMixin_Vanilla.HANDSHAKE_SYNC_PLUGIN_DATA) {
            final TransactionStore store = ConnectionUtil.getTransactionStore(connection);
            if (store.isEmpty()) {
                this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT;
            }
        }
    }
}
Also used : ServerSideConnection(org.spongepowered.api.network.ServerSideConnection) ServerLoginPacketListener(net.minecraft.network.protocol.login.ServerLoginPacketListener) ServerLoginPacketListenerImpl(net.minecraft.server.network.ServerLoginPacketListenerImpl) ServerSideConnectionEvent(org.spongepowered.api.event.network.ServerSideConnectionEvent) TransactionStore(org.spongepowered.common.network.channel.TransactionStore) ServerboundCustomQueryPacket(net.minecraft.network.protocol.login.ServerboundCustomQueryPacket) Inject(org.spongepowered.asm.mixin.injection.Inject) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) EngineConnection(org.spongepowered.api.network.EngineConnection) Sponge(org.spongepowered.api.Sponge) SpongeChannelManager(org.spongepowered.common.network.channel.SpongeChannelManager) SpongeCommon(org.spongepowered.common.SpongeCommon) Final(org.spongepowered.asm.mixin.Final) EventContext(org.spongepowered.api.event.EventContext) Cause(org.spongepowered.api.event.Cause) CallbackInfo(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) MinecraftServer(net.minecraft.server.MinecraftServer) Mixin(org.spongepowered.asm.mixin.Mixin) ConnectionUtil(org.spongepowered.common.network.channel.ConnectionUtil) ServerboundHelloPacket(net.minecraft.network.protocol.login.ServerboundHelloPacket) Shadow(org.spongepowered.asm.mixin.Shadow) At(org.spongepowered.asm.mixin.injection.At) TransactionStore(org.spongepowered.common.network.channel.TransactionStore) Cause(org.spongepowered.api.event.Cause) SpongeChannelManager(org.spongepowered.common.network.channel.SpongeChannelManager) ServerSideConnection(org.spongepowered.api.network.ServerSideConnection) Inject(org.spongepowered.asm.mixin.injection.Inject)

Aggregations

TransactionStore (org.spongepowered.common.network.channel.TransactionStore)4 EngineConnection (org.spongepowered.api.network.EngineConnection)2 ChannelBuf (org.spongepowered.api.network.channel.ChannelBuf)2 Packet (org.spongepowered.api.network.channel.packet.Packet)2 RequestPacket (org.spongepowered.api.network.channel.packet.RequestPacket)2 ConnectionUtil (org.spongepowered.common.network.channel.ConnectionUtil)2 Map (java.util.Map)1 Objects (java.util.Objects)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Consumer (java.util.function.Consumer)1 Packet (net.minecraft.network.protocol.Packet)1 ServerLoginPacketListener (net.minecraft.network.protocol.login.ServerLoginPacketListener)1 ServerboundCustomQueryPacket (net.minecraft.network.protocol.login.ServerboundCustomQueryPacket)1 ServerboundHelloPacket (net.minecraft.network.protocol.login.ServerboundHelloPacket)1 MinecraftServer (net.minecraft.server.MinecraftServer)1 ServerLoginPacketListenerImpl (net.minecraft.server.network.ServerLoginPacketListenerImpl)1 Sponge (org.spongepowered.api.Sponge)1 Cause (org.spongepowered.api.event.Cause)1 EventContext (org.spongepowered.api.event.EventContext)1