Example usage for io.netty.buffer ByteBuf readIntLE

List of usage examples for io.netty.buffer ByteBuf readIntLE

Introduction

In this page you can find the example usage for io.netty.buffer ByteBuf readIntLE.

Prototype

public abstract int readIntLE();

Source Link

Document

Gets a 32-bit integer at the current readerIndex in the Little Endian Byte Order and increases the readerIndex by 4 in this buffer.

Usage

From source file:com.ibasco.agql.protocols.valve.source.query.handlers.SourceQueryPacketAssembler.java

License:Open Source License

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    log.trace("SourcePacketHandler.channelRead() : START");

    try {//  www.j  a  va 2  s .c  o m
        //Make sure we are only receiving an instance of DatagramPacket
        if (!(msg instanceof DatagramPacket)) {
            return;
        }

        final DatagramPacket packet = (DatagramPacket) msg;
        final ByteBuf data = ((DatagramPacket) msg).content();

        //Verify size
        if (data.readableBytes() <= 5) {
            log.debug(
                    "Not a valid datagram for processing. Size getTotalRequests needs to be at least more than or equal to 5 bytes. Discarding. (Readable Bytes: {})",
                    data.readableBytes());
            return;
        }

        //Try to read protocol header, determine if its a single packet or a split-packet
        int protocolHeader = data.readIntLE();

        //If the packet arrived is single type, we can already forward it to the next handler
        if (protocolHeader == 0xFFFFFFFF) {
            //Pass the message to the succeeding handlers
            ctx.fireChannelRead(packet.retain());
            return;
        }
        //If the packet is a split type...we need to process each succeeding read until we have a complete packet
        else if (protocolHeader == 0xFFFFFFFE) {
            final ByteBuf reassembledPacket = processSplitPackets(data, ctx.channel().alloc(), packet.sender());
            //Check if we already have a reassembled packet
            if (reassembledPacket != null) {
                ctx.fireChannelRead(packet.replace(reassembledPacket));
                return;
            }
        }
        //Packet is not being handled by any of our processors, discard
        else {
            log.debug("Not a valid protocol header. Discarding. (Header Received: Dec = {}, Hex = {})",
                    protocolHeader, Integer.toHexString(protocolHeader));
            return;
        }
    } catch (Exception e) {
        log.error(String.format("Error while processing packet for %s", ((DatagramPacket) msg).sender()), e);
        throw e;
    } finally {
        //Release the message
        ReferenceCountUtil.release(msg);
    }
    log.trace("SourcePacketHandler.channelRead() : END");
}

From source file:com.ibasco.agql.protocols.valve.source.query.handlers.SourceQueryPacketAssembler.java

License:Open Source License

/**
 * Process split-packet data/*from   ww w. ja  va2 s . c o m*/
 *
 * @param data
 *         The {@link ByteBuf} containing the split-packet data
 * @param allocator
 *         The {@link ByteBufAllocator} used to create/allocate pooled buffers
 *
 * @return Returns a non-null {@link ByteBuf} if the split-packets have been assembled. Null if the
 *
 * @throws Exception
 */
private ByteBuf processSplitPackets(ByteBuf data, ByteBufAllocator allocator, InetSocketAddress senderAddress)
        throws Exception {
    int packetCount, packetNumber, requestId, splitSize, packetChecksum = 0;
    boolean isCompressed;

    //Start processing
    requestId = data.readIntLE();
    //read the most significant bit is set
    isCompressed = ((requestId & 0x80000000) != 0);
    //The total number of packets in the response.
    packetCount = data.readByte();
    //The number of the packet. Starts at 0.
    packetNumber = data.readByte();

    //Create our key for this request (request id + sender ip)
    final SplitPacketKey key = new SplitPacketKey(requestId, senderAddress);

    log.debug("Processing split packet {}", key);

    log.debug(
            "Split Packet Received = (AbstractRequest {}, Packet Number {}, Packet Count {}, Is Compressed: {})",
            requestId, packetNumber, packetCount, isCompressed);

    //Try to retrieve the split packet container for this request (if existing)
    //If request is not yet on the map, create and retrieve
    SplitPacketContainer splitPackets = this.requestMap.computeIfAbsent(key,
            k -> new SplitPacketContainer(packetCount));

    //As per protocol specs, the size is only present in the first packet of the response and only if the response is being compressed.
    //split size = Maximum size of packet before packet switching occurs. The default value is 1248 bytes (0x04E0
    if (isCompressed) {
        splitSize = data.readIntLE();
        packetChecksum = data.readIntLE();
    } else {
        splitSize = data.readShortLE();
    }

    //TODO: Handle compressed split packets
    int bufferSize = Math.min(splitSize, data.readableBytes());
    byte[] splitPacket = new byte[bufferSize];
    data.readBytes(splitPacket); //transfer the split data into this buffer

    //Add the split packet to the container
    splitPackets.addPacket(packetNumber, splitPacket);

    //Have we received all packets for this request?
    if (splitPackets.isComplete()) {
        log.debug(
                "Split Packets have all been successfully received from AbstractRequest {}. Re-assembling packets.",
                requestId);

        //Retrieve total split packets received based on their length
        int packetSize = splitPackets.getPacketSize();
        //Allocate a new buffer to store the re-assembled packets
        final ByteBuf packetBuffer = allocator.buffer(packetSize);
        boolean done = false;
        try {
            //Start re-assembling split-packets from the container
            done = reassembleSplitPackets(splitPackets, packetBuffer, isCompressed, splitSize, packetChecksum);
        } catch (Exception e) {
            //If an error occurs during re-assembly, make sure we release the allocated buffer
            packetBuffer.release();
            throw e;
        } finally {
            if (done)
                requestMap.remove(key);
        }

        return packetBuffer;
    }

    //Return null, indicating that we still don't have a complete packet
    return null;
}

From source file:com.ibasco.agql.protocols.valve.source.query.handlers.SourceRconPacketDecoder.java

License:Open Source License

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

    final String separator = "=================================================================================================";

    //TODO: Move all code logic below to SourceRconPacketBuilder

    log.debug(separator);/*  w ww. ja  va  2 s. c  o m*/
    log.debug(" ({}) DECODING INCOMING DATA : Bytes Received = {} {}", index.incrementAndGet(),
            in.readableBytes(), index.get() > 1 ? "[Continuation]" : "");
    log.debug(separator);

    String desc = StringUtils.rightPad("Minimum allowable size?", PAD_SIZE);
    //Verify we have the minimum allowable size
    if (in.readableBytes() < 14) {
        log.debug(" [ ] {} = NO (Actual Readable Bytes: {})", desc, in.readableBytes());
        return;
    }
    log.debug(" [x] {} = YES (Actual Readable Bytes: {})", desc, in.readableBytes());

    //Reset if this happens to be not a valid source rcon packet
    in.markReaderIndex();

    //Read and Verify size
    desc = StringUtils.rightPad("Bytes received at least => than the \"declared\" size?", PAD_SIZE);
    int size = in.readIntLE();
    int readableBytes = in.readableBytes();
    if (readableBytes < size) {
        log.debug(" [ ] {} = NO (Declared Size: {}, Actual Bytes Read: {})", desc, readableBytes, size);
        in.resetReaderIndex();
        return;
    }
    log.debug(" [x] {} = YES (Declared Size: {}, Actual Bytes Read: {})", desc, readableBytes, size);

    //Read and verify request id
    desc = StringUtils.rightPad("Request Id within the valid range?", PAD_SIZE);
    int id = in.readIntLE();
    if (!(id == -1 || id == SourceRconUtil.RCON_TERMINATOR_RID || SourceRconUtil.isValidRequestId(id))) {
        log.debug(" [ ] {} = NO (Actual: {})", desc, id);
        in.resetReaderIndex();
        return;
    }
    log.debug(" [x] {} = YES (Actual: {})", desc, id);

    //Read and verify request type
    desc = StringUtils.rightPad("Valid response type?", PAD_SIZE);
    int type = in.readIntLE();
    if (get(type) == null) {
        log.debug(" [ ] {} = NO (Actual: {})", desc, type);
        in.resetReaderIndex();
        return;
    }
    log.debug(" [x] {} = YES (Actual: {} = {})", desc, type, SourceRconResponseType.get(type));

    //Read and verify body
    desc = StringUtils.rightPad("Contains Body?", PAD_SIZE);
    int bodyLength = in.bytesBefore((byte) 0);
    String body = StringUtils.EMPTY;
    if (bodyLength <= 0)
        log.debug(" [ ] {} = NO", desc);
    else {
        body = in.readCharSequence(bodyLength, StandardCharsets.UTF_8).toString();
        log.debug(" [x] {} = YES (Length: {}, Body: {})", desc, bodyLength,
                StringUtils.replaceAll(StringUtils.truncate(body, 30), "\n", "\\\\n"));
    }

    //Peek at the last two bytes and verify that they are null-bytes
    byte bodyTerminator = in.getByte(in.readerIndex());
    byte packetTerminator = in.getByte(in.readerIndex() + 1);

    desc = StringUtils.rightPad("Contains TWO null-terminating bytes at the end?", PAD_SIZE);

    //Make sure the last two bytes are NULL bytes (request id: 999 is reserved for split packet responses)
    if ((bodyTerminator != 0 || packetTerminator != 0) && (id == SourceRconUtil.RCON_TERMINATOR_RID)) {
        log.debug("Skipping {} bytes", in.readableBytes());
        in.skipBytes(in.readableBytes());
        return;
    } else if (bodyTerminator != 0 || packetTerminator != 0) {
        log.debug(" [ ] {} = NO (Actual: Body Terminator = {}, Packet Terminator = {})", desc, bodyTerminator,
                packetTerminator);
        in.resetReaderIndex();
        return;
    } else {
        log.debug(" [x] {} = YES (Actual: Body Terminator = {}, Packet Terminator = {})", desc, bodyTerminator,
                packetTerminator);
        //All is good, skip the last two bytes
        if (in.readableBytes() >= 2)
            in.skipBytes(2);
    }

    //At this point, we can now construct a packet
    log.debug(" [x] Status: PASS (Size = {}, Id = {}, Type = {}, Remaining Bytes = {}, Body Size = {})", size,
            id, type, in.readableBytes(), bodyLength);
    log.debug(separator);

    //Reset the index
    index.set(0);

    //Construct the response packet and send to the next handlers
    SourceRconResponsePacket responsePacket;

    //Did we receive a terminator packet?
    if (this.terminatingPacketsEnabled && id == SourceRconUtil.RCON_TERMINATOR_RID
            && StringUtils.isBlank(body)) {
        responsePacket = new SourceRconTermResponsePacket();
    } else {
        responsePacket = SourceRconPacketBuilder.getResponsePacket(type);
    }

    if (responsePacket != null) {
        responsePacket.setSize(size);
        responsePacket.setId(id);
        responsePacket.setType(type);
        responsePacket.setBody(body);
        log.debug(
                "Decode Complete. Passing response for request id : '{}' to the next handler. Remaining bytes ({})",
                id, in.readableBytes());
        out.add(responsePacket);
    }
}

From source file:com.ibasco.agql.protocols.valve.source.query.logger.SourceLogListenHandler.java

License:Open Source License

@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
    ByteBuf data = msg.content();
    if (data.readableBytes() > 6 && data.readIntLE() == -1) {
        byte[] raw = new byte[data.readableBytes() - 2];
        data.readBytes(raw);/* w  w w  .jav  a 2s  .  co m*/
        data.skipBytes(2);
        //Pass to the callback
        if (logEventCallback != null)
            logEventCallback.accept(new SourceLogEntry(new String(raw, Charsets.UTF_8), msg.sender()));
    }
}

From source file:com.ibasco.agql.protocols.valve.source.query.packets.response.SourceChallengeResponsePacket.java

License:Open Source License

@Override
public Integer toObject() {
    ByteBuf data = getPayloadBuffer();
    Integer challengeNumber;//from   w  ww .  j  a v a 2s .  c o m
    //Read the 32bit challenge number
    challengeNumber = data.readIntLE();
    return challengeNumber;
}

From source file:com.ibasco.agql.protocols.valve.source.query.packets.response.SourcePlayerResponsePacket.java

License:Open Source License

@Override
public List<SourcePlayer> toObject() {
    ByteBuf data = getPayloadBuffer();
    List<SourcePlayer> playerList = new ArrayList<>();
    byte numOfPlayers = data.readByte();
    for (int i = 0; i < numOfPlayers; i++)
        playerList.add(new SourcePlayer(data.readByte(), ByteBufUtils.readString(data, CharsetUtil.UTF_8),
                data.readIntLE(), Float.intBitsToFloat(data.readIntLE())));
    return playerList;
}

From source file:com.ibasco.agql.protocols.valve.source.query.SourcePacketBuilder.java

License:Open Source License

@Override
public <T extends SourceServerPacket> T construct(ByteBuf data) {
    //Mark Index//from   w  w w. j  a va  2 s .com
    data.markReaderIndex();

    try {
        //Reset the index
        data.readerIndex(0);

        //Verify size
        if (data.readableBytes() < 5)
            throw new IllegalStateException(
                    "Cannot continue processing buffer with less than or equal to 4 bytes");

        //Read protocol header
        int protocolHeader = data.readIntLE();

        //Check if this is a split packet
        if (protocolHeader == 0xFFFFFFFE)
            throw new IllegalStateException("Cannot construct a response from a partial/split packet.");

        //Verify that we have a valid header
        if (protocolHeader != 0xFFFFFFFF)
            throw new IllegalStateException("Protocol header not supported.");

        //Read packet header
        byte packetHeader = data.readByte();

        //Read payload
        byte[] payload = new byte[data.readableBytes()];
        data.readBytes(payload);

        //Verify if packet header is valid
        SourceServerPacket packet = createResponsePacketFromHeader(packetHeader);

        //If packet is empty, means the supplied packet header is not supported
        if (packet == null)
            return null;

        packet.setProtocolHeader(ByteUtils.byteArrayFromInteger(protocolHeader));
        packet.setHeader(packetHeader);
        packet.setPayload(payload);

        return (T) packet;
    } finally {
        data.resetReaderIndex();
    }
}

From source file:com.ibasco.agql.protocols.valve.source.query.SourceRconPacketBuilder.java

License:Open Source License

@SuppressWarnings("unchecked")
@Override/*from   w  ww  .  j  a v a 2s. c o m*/
public <T extends SourceRconPacket> T construct(ByteBuf data) {
    try {
        if (data.readableBytes() < 14) {
            log.warn("Packet is less than 10 bytes. Unsupported packet.");
            if (log.isDebugEnabled())
                log.debug("Unrecognized Packet: \n{}", ByteBufUtil.prettyHexDump(data));
            return null;
        }

        //Remember the reader index
        data.markReaderIndex();

        //Read from the listen
        data.readerIndex(0);
        int size = data.readIntLE();
        int id = data.readIntLE();
        int type = data.readIntLE();

        String body = data.readCharSequence(data.readableBytes() - 2, StandardCharsets.UTF_8).toString();

        SourceRconResponsePacket packet = getResponsePacket(type);

        if (packet != null) {
            //Ok, we have a valid response packet. Lets keep reading.
            packet.setId(id);
            packet.setSize(size);
            packet.setType(type);
            packet.setBody(body);
            return (T) packet;
        }
    } finally {
        //Reset the index
        data.resetReaderIndex();
    }
    return null;
}

From source file:nearenough.protocol.RtWireTest.java

License:Open Source License

@Test
public void encodeEmptyMessage() {
    RtMessage msg = RtMessage.fromBytes(new byte[] { 0, 0, 0, 0 });
    ByteBuf onWire = RtWire.toWire(msg);

    // Empty message will be a single uint32
    assertThat(onWire.readableBytes(), equalTo(4));
    assertThat(onWire.readIntLE(), equalTo(0));
}

From source file:nearenough.protocol.RtWireTest.java

License:Open Source License

@Test
public void encodeSingleTagMessage() {
    byte[] value = new byte[64];
    Arrays.fill(value, (byte) 'a');

    RtMessage msg = RtMessage.builder().add(RtTag.CERT, value).build();

    // Wire encoding is 4 (num_tags) + 4 (CERT) + 64 (CERT value)
    ByteBuf onWire = RtWire.toWire(msg);
    assertThat(onWire.readableBytes(), equalTo(72));

    // num_tags//from w  w w  .  ja va  2  s  .  co m
    assertThat(onWire.readIntLE(), equalTo(1));

    // CERT tag
    assertThat(onWire.readInt(), equalTo(RtTag.CERT.wireEncoding()));

    // CERT value
    assertThat(onWire.readableBytes(), equalTo(value.length));
    byte[] readValue = new byte[onWire.readableBytes()];
    onWire.readBytes(readValue);
    assertArrayEquals(value, readValue);

    // Message was completely read
    assertThat(onWire.readableBytes(), equalTo(0));
}