Search in sources :

Example 1 with ArchiveResponsePacket

use of net.runelite.protocol.api.update.ArchiveResponsePacket in project runelite by runelite.

the class ArchiveRequestHandler method handleRequest.

private void handleRequest(ChannelHandlerContext ctx, int index, int archiveId) throws IOException {
    logger.info("Client {} requests index {} archive {}", ctx.channel().remoteAddress(), index, archiveId);
    Index i = store.findIndex(index);
    assert i != null;
    Archive archive = i.getArchive(archiveId);
    assert archive != null;
    Storage storage = store.getStorage();
    // is compressed, includes length and type
    byte[] packed = storage.loadArchive(archive);
    if (packed == null) {
        logger.warn("Missing archive {}/{}", index, archiveId);
        // is it possible to notify the client of an error with this?
        return;
    }
    byte compression = packed[0];
    int compressedSize = Ints.fromBytes(packed[1], packed[2], packed[3], packed[4]);
    // size the client expects the data to be
    int expectedSize = // compression type
    1 + // compressed size
    4 + compressedSize + (compression != CompressionType.NONE ? 4 : 0);
    if (packed.length != expectedSize) {
        // the update server will never have it
        assert packed.length - expectedSize == 2 : "packed length != expected size";
        packed = Arrays.copyOf(packed, packed.length - 2);
    }
    ArchiveResponsePacket response = new ArchiveResponsePacket();
    response.setIndex(index);
    response.setArchive(archiveId);
    response.setData(packed);
    ctx.writeAndFlush(response);
}
Also used : Archive(net.runelite.cache.fs.Archive) Storage(net.runelite.cache.fs.Storage) DiskStorage(net.runelite.cache.fs.jagex.DiskStorage) Index(net.runelite.cache.fs.Index) ArchiveResponsePacket(net.runelite.protocol.api.update.ArchiveResponsePacket)

Example 2 with ArchiveResponsePacket

use of net.runelite.protocol.api.update.ArchiveResponsePacket in project runelite by runelite.

the class ArchiveRequestHandler method handleRequest255.

private void handleRequest255(ChannelHandlerContext ctx, int index, int archiveId) throws IOException {
    logger.info("Client {} requests 255: index {}, archive {}", ctx.channel().remoteAddress(), index, archiveId);
    byte[] compressed;
    if (archiveId == 255) {
        // index 255 data, for each index:
        // 4 byte crc
        // 4 byte revision
        ByteBuf buffer = ctx.alloc().heapBuffer(store.getIndexes().size() * 8);
        for (Index i : store.getIndexes()) {
            buffer.writeInt(i.getCrc());
            buffer.writeInt(i.getRevision());
        }
        compressed = compress(CompressionType.NONE, Arrays.copyOf(buffer.array(), buffer.readableBytes()));
        buffer.release();
    } else {
        // Requires disk storage. Use packed index data from
        // store as its crc matches
        DiskStorage storage = (DiskStorage) store.getStorage();
        compressed = storage.readIndex(archiveId);
    }
    ArchiveResponsePacket response = new ArchiveResponsePacket();
    response.setIndex(index);
    response.setArchive(archiveId);
    response.setData(compressed);
    ctx.writeAndFlush(response);
}
Also used : Index(net.runelite.cache.fs.Index) ByteBuf(io.netty.buffer.ByteBuf) DiskStorage(net.runelite.cache.fs.jagex.DiskStorage) ArchiveResponsePacket(net.runelite.protocol.api.update.ArchiveResponsePacket)

Example 3 with ArchiveResponsePacket

use of net.runelite.protocol.api.update.ArchiveResponsePacket in project runelite by runelite.

the class ArchiveResponseEncoderTest method testEncode.

@Test
public void testEncode() throws Exception {
    byte[] data = new byte[1000];
    Random random = new Random(42L);
    random.nextBytes(data);
    Container container = new Container(CompressionType.NONE, -1);
    container.compress(data, null);
    byte[] compressedData = container.data;
    ArchiveResponsePacket archiveResponse = new ArchiveResponsePacket();
    archiveResponse.setIndex(0);
    archiveResponse.setArchive(1);
    archiveResponse.setData(compressedData);
    ByteBuf buf = Unpooled.buffer(1024);
    ArchiveResponseEncoder encoder = new ArchiveResponseEncoder();
    encoder.encode(null, archiveResponse, buf);
    ArchiveResponseDecoder decoder = new ArchiveResponseDecoder();
    List<Object> out = new ArrayList<>();
    decoder.decode(null, buf, out);
    Assert.assertEquals(1, out.size());
    ArchiveResponsePacket response = (ArchiveResponsePacket) out.get(0);
    Assert.assertEquals(archiveResponse.getIndex(), response.getIndex());
    Assert.assertEquals(archiveResponse.getArchive(), response.getArchive());
    Assert.assertArrayEquals(archiveResponse.getData(), response.getData());
    byte[] decompressedData = Container.decompress(response.getData(), null).data;
    Assert.assertArrayEquals(data, decompressedData);
}
Also used : Container(net.runelite.cache.fs.Container) Random(java.util.Random) ArrayList(java.util.ArrayList) ByteBuf(io.netty.buffer.ByteBuf) ArchiveResponsePacket(net.runelite.protocol.api.update.ArchiveResponsePacket) ArchiveResponseDecoder(net.runelite.protocol.update.decoders.ArchiveResponseDecoder) Test(org.junit.Test)

Example 4 with ArchiveResponsePacket

use of net.runelite.protocol.api.update.ArchiveResponsePacket in project runelite by runelite.

the class ArchiveResponseDecoder method decode.

@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    if (in.readableBytes() < 8) {
        return;
    }
    ByteBuf copy = in.slice();
    int index = copy.readUnsignedByte();
    int file = copy.readUnsignedShort();
    // decompress() starts reading here
    int compression = copy.readUnsignedByte();
    int compressedFileSize = copy.readInt();
    assert compression == CompressionType.NONE || compression == CompressionType.BZ2 || compression == CompressionType.GZ;
    int size = compressedFileSize + // 1 byte compresion type, 4 byte compressed size
    5 + // compression has leading 4 byte decompressed length
    (compression != CompressionType.NONE ? 4 : 0);
    assert size > 0;
    int breaks = calculateBreaks(size);
    // 3 for index/file
    if (size + 3 + breaks > in.readableBytes()) {
        logger.trace("Index {} archive {}: Not enough data yet {} > {}", index, file, size + 3 + breaks, in.readableBytes());
        return;
    }
    ByteBuf compressedData = Unpooled.buffer(size);
    int totalRead = 3;
    // skip index/file
    in.skipBytes(3);
    for (int i = 0; i < breaks + 1; ++i) {
        int bytesInBlock = CHUNK_SIZE - (totalRead % CHUNK_SIZE);
        int bytesToRead = Math.min(bytesInBlock, size - compressedData.writerIndex());
        logger.trace("{}/{}: reading block {}/{}, read so far this block: {}, file status: {}/{}", index, file, (totalRead % CHUNK_SIZE), CHUNK_SIZE, bytesInBlock, compressedData.writerIndex(), size);
        ByteBuf chunk = in.readBytes(bytesToRead);
        compressedData.writeBytes(chunk);
        chunk.release();
        totalRead += bytesToRead;
        if (i < breaks) {
            assert compressedData.writerIndex() < size;
            int b = in.readUnsignedByte();
            ++totalRead;
            assert b == 0xff;
        }
    }
    assert compressedData.writerIndex() == size;
    logger.trace("{}/{}: done downloading file, remaining buffer {}", index, file, in.readableBytes());
    ArchiveResponsePacket archiveResponse = new ArchiveResponsePacket();
    archiveResponse.setIndex(index);
    archiveResponse.setArchive(file);
    archiveResponse.setData(compressedData.array());
    out.add(archiveResponse);
    compressedData.release();
}
Also used : ByteBuf(io.netty.buffer.ByteBuf) ArchiveResponsePacket(net.runelite.protocol.api.update.ArchiveResponsePacket)

Aggregations

ArchiveResponsePacket (net.runelite.protocol.api.update.ArchiveResponsePacket)4 ByteBuf (io.netty.buffer.ByteBuf)3 Index (net.runelite.cache.fs.Index)2 DiskStorage (net.runelite.cache.fs.jagex.DiskStorage)2 ArrayList (java.util.ArrayList)1 Random (java.util.Random)1 Archive (net.runelite.cache.fs.Archive)1 Container (net.runelite.cache.fs.Container)1 Storage (net.runelite.cache.fs.Storage)1 ArchiveResponseDecoder (net.runelite.protocol.update.decoders.ArchiveResponseDecoder)1 Test (org.junit.Test)1