From 7682370c4e72ba0bcc7a87570133bb38ae60bb0a Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 18 Jun 2016 18:11:20 -0400 Subject: [PATCH] Bubble up gzip/bzip errors, fix map dumper test, add datafile xtea testcase --- .../cache/downloader/CacheClient.java | 2 +- .../runelite/cache/downloader/FileResult.java | 3 +- .../java/net/runelite/cache/fs/Archive.java | 3 +- .../java/net/runelite/cache/fs/DataFile.java | 20 +---- .../java/net/runelite/cache/util/BZip2.java | 78 ++++++++----------- .../java/net/runelite/cache/util/GZip.java | 14 +--- .../net/runelite/cache/MapDumperTest.java | 45 +++++++++-- .../net/runelite/cache/fs/DataFileTest.java | 24 ++++++ 8 files changed, 103 insertions(+), 86 deletions(-) diff --git a/cache/src/main/java/net/runelite/cache/downloader/CacheClient.java b/cache/src/main/java/net/runelite/cache/downloader/CacheClient.java index 65fe2fd460..f18aa79c97 100644 --- a/cache/src/main/java/net/runelite/cache/downloader/CacheClient.java +++ b/cache/src/main/java/net/runelite/cache/downloader/CacheClient.java @@ -128,7 +128,7 @@ public class CacheClient return clientRevision; } - public void download() throws InterruptedException, ExecutionException, FileNotFoundException + public void download() throws InterruptedException, ExecutionException, FileNotFoundException, IOException { FileResult result = requestFile(255, 255).get(); result.decompress(null); diff --git a/cache/src/main/java/net/runelite/cache/downloader/FileResult.java b/cache/src/main/java/net/runelite/cache/downloader/FileResult.java index 7f9f98b3ae..154f505e7c 100644 --- a/cache/src/main/java/net/runelite/cache/downloader/FileResult.java +++ b/cache/src/main/java/net/runelite/cache/downloader/FileResult.java @@ -30,6 +30,7 @@ package net.runelite.cache.downloader; +import java.io.IOException; import net.runelite.cache.fs.DataFile; import net.runelite.cache.fs.DataFileReadResult; @@ -67,7 +68,7 @@ public class FileResult return compressedData; } - public void decompress(int[] keys) + public void decompress(int[] keys) throws IOException { DataFileReadResult res = DataFile.decompress(compressedData, keys); diff --git a/cache/src/main/java/net/runelite/cache/fs/Archive.java b/cache/src/main/java/net/runelite/cache/fs/Archive.java index 6e4d0cc7ca..3b580b73a0 100644 --- a/cache/src/main/java/net/runelite/cache/fs/Archive.java +++ b/cache/src/main/java/net/runelite/cache/fs/Archive.java @@ -30,6 +30,7 @@ package net.runelite.cache.fs; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -134,7 +135,7 @@ public class Archive } } - public void decompressAndLoad(int[] keys) + public void decompressAndLoad(int[] keys) throws IOException { byte[] encryptedData = this.getData(); diff --git a/cache/src/main/java/net/runelite/cache/fs/DataFile.java b/cache/src/main/java/net/runelite/cache/fs/DataFile.java index 9c8a020f4d..a20f9d45a3 100644 --- a/cache/src/main/java/net/runelite/cache/fs/DataFile.java +++ b/cache/src/main/java/net/runelite/cache/fs/DataFile.java @@ -280,7 +280,7 @@ public class DataFile implements Closeable return res; } - public static DataFileReadResult decompress(byte[] b, int[] keys) + public static DataFileReadResult decompress(byte[] b, int[] keys) throws IOException { InputStream stream = new InputStream(b); @@ -420,24 +420,6 @@ public class DataFile implements Closeable return stream.flip(); } - - private static int checkRevision(InputStream stream, int compressedLength) - { - int offset = stream.getOffset(); - int revision; - if (stream.getLength() - (compressedLength + stream.getOffset()) >= 2) - { - stream.setOffset(stream.getLength() - 2); - revision = stream.readUnsignedShort(); - assert revision != -1; - stream.setOffset(offset); - } - else - { - revision = -1; - } - return revision; - } private static byte[] decrypt(byte[] data, int length, int[] keys) { diff --git a/cache/src/main/java/net/runelite/cache/util/BZip2.java b/cache/src/main/java/net/runelite/cache/util/BZip2.java index 1f9ed5cc26..b47ba80ceb 100644 --- a/cache/src/main/java/net/runelite/cache/util/BZip2.java +++ b/cache/src/main/java/net/runelite/cache/util/BZip2.java @@ -27,7 +27,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - package net.runelite.cache.util; import java.io.ByteArrayInputStream; @@ -46,62 +45,47 @@ public class BZip2 { private static final Logger logger = LoggerFactory.getLogger(BZip2.class); - private static final byte[] BZIP_HEADER = new byte[] { + private static final byte[] BZIP_HEADER = new byte[] + { 'B', 'Z', // magic - 'h', // 'h' for Bzip2 ('H'uffman coding) + 'h', // 'h' for Bzip2 ('H'uffman coding) '1' // block size }; - - public static byte[] compress(byte[] bytes) + + public static byte[] compress(byte[] bytes) throws IOException { - try + InputStream is = new ByteArrayInputStream(bytes); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + try (OutputStream os = new BZip2CompressorOutputStream(bout, 1)) { - InputStream is = new ByteArrayInputStream(bytes); - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try (OutputStream os = new BZip2CompressorOutputStream(bout, 1)) - { - IOUtils.copy(is, os); - } - - byte[] out = bout.toByteArray(); - - assert BZIP_HEADER[0] == out[0]; - assert BZIP_HEADER[1] == out[1]; - assert BZIP_HEADER[2] == out[2]; - assert BZIP_HEADER[3] == out[3]; - - return Arrays.copyOfRange(out, BZIP_HEADER.length, out.length); // remove header.. - } - catch (IOException ex) - { - logger.warn(null, ex); - return null; + IOUtils.copy(is, os); } + + byte[] out = bout.toByteArray(); + + assert BZIP_HEADER[0] == out[0]; + assert BZIP_HEADER[1] == out[1]; + assert BZIP_HEADER[2] == out[2]; + assert BZIP_HEADER[3] == out[3]; + + return Arrays.copyOfRange(out, BZIP_HEADER.length, out.length); // remove header.. } - public static byte[] decompress(byte[] bytes, int len) + public static byte[] decompress(byte[] bytes, int len) throws IOException { - try + byte[] data = new byte[len + BZIP_HEADER.length]; + + // add header + System.arraycopy(BZIP_HEADER, 0, data, 0, BZIP_HEADER.length); + System.arraycopy(bytes, 0, data, BZIP_HEADER.length, len); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + try (InputStream is = new BZip2CompressorInputStream(new ByteArrayInputStream(data))) { - byte[] data = new byte[len + BZIP_HEADER.length]; - - // add header - System.arraycopy(BZIP_HEADER, 0, data, 0, BZIP_HEADER.length); - System.arraycopy(bytes, 0, data, BZIP_HEADER.length, len); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - try (InputStream is = new BZip2CompressorInputStream(new ByteArrayInputStream(data))) - { - IOUtils.copy(is, os); - } - - return os.toByteArray(); - } - catch (IOException ex) - { - logger.warn(null, ex); - return null; + IOUtils.copy(is, os); } + + return os.toByteArray(); } } diff --git a/cache/src/main/java/net/runelite/cache/util/GZip.java b/cache/src/main/java/net/runelite/cache/util/GZip.java index 3dddd34e6e..ec98f3eb1e 100644 --- a/cache/src/main/java/net/runelite/cache/util/GZip.java +++ b/cache/src/main/java/net/runelite/cache/util/GZip.java @@ -45,7 +45,7 @@ public class GZip { private static final Logger logger = LoggerFactory.getLogger(GZip.class); - public static byte[] compress(byte[] bytes) + public static byte[] compress(byte[] bytes) throws IOException { InputStream is = new ByteArrayInputStream(bytes); ByteArrayOutputStream bout = new ByteArrayOutputStream(); @@ -54,16 +54,11 @@ public class GZip { IOUtils.copy(is, os); } - catch (IOException ex) - { - logger.warn(null, ex); - return null; - } return bout.toByteArray(); } - public static byte[] decompress(byte[] bytes, int len) + public static byte[] decompress(byte[] bytes, int len) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); @@ -71,11 +66,6 @@ public class GZip { IOUtils.copy(is, os); } - catch (IOException ex) - { - logger.warn(null, ex); - return null; - } return os.toByteArray(); } diff --git a/cache/src/test/java/net/runelite/cache/MapDumperTest.java b/cache/src/test/java/net/runelite/cache/MapDumperTest.java index 0d07fdcf64..b6ede35489 100644 --- a/cache/src/test/java/net/runelite/cache/MapDumperTest.java +++ b/cache/src/test/java/net/runelite/cache/MapDumperTest.java @@ -1,3 +1,33 @@ +/* + * Copyright (c) 2016, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam + * 4. Neither the name of the Adam nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Adam ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Adam BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + package net.runelite.cache; import com.google.common.io.Files; @@ -26,7 +56,7 @@ public class MapDumperTest public void dump() throws IOException { File base = StoreLocation.LOCATION, - outDir = new java.io.File("d:/rs/07/cache/maps");//folder.newFolder(); + outDir = folder.newFolder(); try (Store store = new Store(base)) { @@ -63,13 +93,18 @@ public class MapDumperTest if (keys != null) { - land.decompressAndLoad(keys); + try + { + land.decompressAndLoad(keys); + } + catch (IOException ex) + { + logger.warn("Unable to decompress and load land " + x + "/" + y + " (bad keys?)", ex); + continue; + } data = land.getFiles().get(0).getContents(); - if (data == null) - continue; // key is probably wrong - Files.write(data, new File(outDir, "l" + x + "_" + y + ".dat")); } } diff --git a/cache/src/test/java/net/runelite/cache/fs/DataFileTest.java b/cache/src/test/java/net/runelite/cache/fs/DataFileTest.java index a5bf048b59..b154fdb16a 100644 --- a/cache/src/test/java/net/runelite/cache/fs/DataFileTest.java +++ b/cache/src/test/java/net/runelite/cache/fs/DataFileTest.java @@ -150,4 +150,28 @@ public class DataFileTest Assert.assertEquals(42, res2.revision); } } + + @Test + public void testKeys() throws IOException + { + File file = folder.newFile(); + int[] keys = new int[] { 4, 8, 15, 16 }; + + try (Store store = new Store(folder.getRoot())) + { + DataFile df = new DataFile(store, file); + + byte[] compressedData = DataFile.compress("testtesttesttest1".getBytes(), CompressionType.NONE, 42, keys); + DataFileWriteResult res = df.write(42, 3, compressedData, 0); + + compressedData = df.read(42, 3, res.sector, res.compressedLength); + DataFileReadResult res2 = DataFile.decompress(compressedData, keys); + + byte[] buf = res2.data; + String str = new String(buf); + Assert.assertEquals("testtesttesttest1", str); + Assert.assertEquals(res.crc, res2.crc); + Assert.assertEquals(42, res2.revision); + } + } }