use of org.spongepowered.api.network.channel.ChannelIOException in project SpongeCommon by SpongePowered.
the class SpongeBasicPacketChannel method handleLoginRequestPayload.
@Override
protected void handleLoginRequestPayload(final EngineConnection connection, final int transactionId, final ChannelBuf payload) {
// Is currently always executed on the client,
// the server always expects a response
final int opcode = this.readOpcode(payload);
final SpongePacketBinding<Packet> binding = this.requireBinding(opcode);
final Packet packet = this.decodePayload(() -> binding.getPacketConstructor().get(), payload);
// A normal packet binding
if (binding instanceof SpongeHandlerPacketBinding) {
final SpongeHandlerPacketBinding<Packet> handlerBinding = (SpongeHandlerPacketBinding<Packet>) binding;
this.handle(connection, handlerBinding, packet);
// The server always expects a response
PacketSender.sendTo(connection, PacketUtil.createLoginPayloadResponse(null, transactionId));
} else {
// A transactional packet binding
final SpongeTransactionalPacketBinding<RequestPacket<Packet>, Packet> transactionalBinding = (SpongeTransactionalPacketBinding) binding;
final RequestPacketHandler<Packet, Packet, EngineConnection> handler = (RequestPacketHandler<Packet, Packet, EngineConnection>) transactionalBinding.getRequestHandler(connection);
boolean success = false;
if (handler != null) {
final SpongeRequestPacketResponse<Packet> response = new SpongeRequestPacketResponse<Packet>() {
@Override
protected void fail0(final ChannelException exception) {
final net.minecraft.network.protocol.Packet<?> mcPacket = PacketUtil.createLoginPayloadResponse(null, transactionId);
PacketSender.sendTo(connection, mcPacket);
}
@Override
protected void success0(final Packet response) {
try {
final ChannelBuf responsePayload = SpongeBasicPacketChannel.this.encodeLoginPayload(transactionalBinding.opcode(), response);
final net.minecraft.network.protocol.Packet<?> mcPacket = PacketUtil.createLoginPayloadResponse(responsePayload, transactionId);
PacketSender.sendTo(connection, mcPacket);
} catch (final Throwable ex) {
SpongeBasicPacketChannel.this.handleException(connection, new ChannelIOException("Failed to encode response packet", ex), null);
}
}
};
try {
handler.handleRequest(packet, connection, response);
success = true;
} catch (final Throwable ex) {
this.handleException(connection, new ChannelIOException("Failed to handle request packet", ex), null);
}
}
if (!success) {
final net.minecraft.network.protocol.Packet<?> mcPacket = PacketUtil.createLoginPayloadResponse(null, transactionId);
PacketSender.sendTo(connection, mcPacket);
}
}
}
use of org.spongepowered.api.network.channel.ChannelIOException in project SpongeCommon by SpongePowered.
the class SpongePacketChannel method handleLoginRequestPayload.
@Override
protected void handleLoginRequestPayload(final EngineConnection connection, final int transactionId, final ChannelBuf payload) {
final long typeAndValue = payload.readVarLong();
final int type = SpongePacketChannel.extractType(typeAndValue);
final int value = SpongePacketChannel.extractValue(typeAndValue);
if (type == SpongePacketChannel.TYPE_NORMAL) {
this.handleNormalPacket(connection, value, payload);
} else if (type == SpongePacketChannel.TYPE_REQUEST) {
this.handleRequestPacket(connection, value, transactionId, payload);
} else if (type == SpongePacketChannel.TYPE_RESPONSE) {
this.handleResponsePacket(connection, transactionId, payload, SpongePacketChannel.NO_DYNAMIC_OPCODE);
} else if (type == SpongePacketChannel.TYPE_NO_RESPONSE) {
this.handleResponsePacket(connection, transactionId, null, SpongePacketChannel.NO_DYNAMIC_OPCODE);
} else if (type == SpongePacketChannel.TYPE_DYNAMIC_RESPONSE) {
this.handleResponsePacket(connection, transactionId, payload, value);
} else {
this.handleException(connection, new ChannelIOException("Unknown packet type: " + type), null);
}
}
use of org.spongepowered.api.network.channel.ChannelIOException in project SpongeCommon by SpongePowered.
the class SpongePacketChannel method handleTransactionResponse.
private <P extends RequestPacket<R>, R extends Packet> void handleTransactionResponse(final EngineConnection connection, final TransactionData<P, R> transactionData, final TransactionResult result, final int dynamicOpcode) {
if (result.isSuccess()) {
final ChannelBuf payload = result.getPayload();
SpongePacketBinding<R> responseBinding = null;
final Supplier<R> packetSupplier;
if (dynamicOpcode != SpongePacketChannel.NO_DYNAMIC_OPCODE) {
responseBinding = (SpongePacketBinding<R>) this.requireBinding(dynamicOpcode);
packetSupplier = responseBinding.getPacketConstructor();
} else if (transactionData.binding instanceof SpongeFixedTransactionalPacketBinding) {
packetSupplier = (Supplier<R>) ((SpongeFixedTransactionalPacketBinding<RequestPacket<Packet>, Packet>) transactionData.binding).getResponsePacketConstructor();
} else {
throw new ChannelException("A fixed response was send but no fixed response was bound to the request: " + transactionData.request.getClass());
}
final R packet;
try {
packet = this.decodePayload(packetSupplier, payload);
} catch (final Throwable ex) {
this.handleException(connection, new ChannelIOException("Failed to decode packet", ex), transactionData.future);
return;
}
if (responseBinding != null) {
this.handle(connection, (SpongeHandlerPacketBinding<Packet>) responseBinding, packet);
} else {
this.handleResponse(connection, transactionData.binding, transactionData.request, packet);
}
if (transactionData.success != null) {
transactionData.success.accept(packet);
}
} else {
this.handleException(connection, result.getCause(), transactionData.future);
this.handleResponseFailure(connection, transactionData.binding, transactionData.request, result.getCause());
}
}
Aggregations