diff --git a/core/test/com/riiablo/mpq_bytebuf/MPQInputStreamTest.java b/core/test/com/riiablo/mpq_bytebuf/MPQInputStreamTest.java new file mode 100644 index 00000000..2dd7c81f --- /dev/null +++ b/core/test/com/riiablo/mpq_bytebuf/MPQInputStreamTest.java @@ -0,0 +1,107 @@ +package com.riiablo.mpq_bytebuf; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import java.io.IOException; +import java.io.InputStream; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import com.riiablo.RiiabloTest; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; + +public class MPQInputStreamTest extends RiiabloTest { + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.mpq_bytebuf", Level.DEBUG); + LogManager.setLevel("com.riiablo.mpq_bytebuf.MPQInputStream", Level.TRACE); + LogManager.setLevel("com.riiablo.mpq_bytebuf.util", Level.DEBUG); + } + + private static MPQ load(String mpq) { + return MPQ.load(new FileHandle("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\" + mpq + ".mpq")); + } + + private static void test(MPQ mpq, String filename) { + FileHandle expectedHandle = Gdx.files.internal("test/" + FilenameUtils.getName(filename)); + final String expected = ByteBufUtil.hexDump(Unpooled.wrappedBuffer(expectedHandle.readBytes())); + + MPQFileHandle actualHandle = new MPQFileHandle(mpq, filename); + final ByteBuf actualBuffer = actualHandle.readByteBuf(); + final String actual; + try { + actual = ByteBufUtil.hexDump(actualBuffer); + } finally { + actualBuffer.release(); + } + + boolean equal = actual.equalsIgnoreCase(expected); + if (!equal) { + System.out.println("Expected:"); + System.out.println(expected); + + System.out.println("Actual:"); + System.out.println(actual); + } + + Assert.assertTrue(equal); + } + + private static void testStream(MPQ mpq, String filename) throws IOException { + FileHandle expectedHandle = Gdx.files.internal("test/" + FilenameUtils.getName(filename)); + final String expected = ByteBufUtil.hexDump(Unpooled.wrappedBuffer(expectedHandle.readBytes())); + + MPQFileHandle actualHandle = new MPQFileHandle(mpq, filename); + InputStream in = actualHandle.read(); + final ByteBuf actualBuffer = Unpooled.wrappedBuffer(IOUtils.readFully(in, in.available())); + final String actual; + try { + actual = ByteBufUtil.hexDump(actualBuffer); + } finally { + actualBuffer.release(); + } + + boolean equal = actual.equalsIgnoreCase(expected); + if (!equal) { + System.out.println("Expected:"); + System.out.println(expected); + + System.out.println("Actual:"); + System.out.println(actual); + } + + Assert.assertTrue(equal); + } + + @Test + public void readBytes() { + final MPQ d2data = load("d2data"); + test(d2data, "data\\global\\missiles\\blessedhammer.dcc"); + } + + @Test + public void readBytes_COMPRESSED_ENCRYPTED_KEY_ADJUSTED() { + final MPQ d2speech = load("d2speech"); + test(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_needhelp.wav"); + } + + @Test + public void read() throws IOException { + final MPQ d2data = load("d2data"); + testStream(d2data, "data\\global\\missiles\\blessedhammer.dcc"); + } + + @Test + public void read_COMPRESSED_ENCRYPTED_KEY_ADJUSTED() throws IOException { + final MPQ d2speech = load("d2speech"); + testStream(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_needhelp.wav"); + } +} \ No newline at end of file diff --git a/core/test/com/riiablo/mpq_bytebuf/MPQTest.java b/core/test/com/riiablo/mpq_bytebuf/MPQTest.java new file mode 100644 index 00000000..8b2b794b --- /dev/null +++ b/core/test/com/riiablo/mpq_bytebuf/MPQTest.java @@ -0,0 +1,119 @@ +package com.riiablo.mpq_bytebuf; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import com.riiablo.Riiablo; +import com.riiablo.RiiabloTest; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; + +public class MPQTest extends RiiabloTest { + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.mpq_bytebuf", Level.DEBUG); + LogManager.setLevel("com.riiablo.mpq_bytebuf.MPQInputStream", Level.INFO); + LogManager.setLevel("com.riiablo.mpq_bytebuf.util", Level.WARN); + } + + private static MPQ load(String mpq) { + return MPQ.load(new FileHandle("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\" + mpq + ".mpq")); + } + + @Test + public void load() { + load("d2char"); + } + + @Test + public void loadAll() { + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\patch_d2.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2exp.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xmusic.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xtalk.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xvideo.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2data.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2char.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2sfx.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2music.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2speech.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2video.mpq")); + } + + @Test + public void yloadAll_old() { + for (int i = 0; i < 1000; i++) { + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\patch_d2.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2exp.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xmusic.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xtalk.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xvideo.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2data.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2char.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2sfx.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2music.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2speech.mpq")); + com.riiablo.mpq.MPQ.loadFromFile(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2video.mpq")); + } + } + + @Test + public void contains() { + final MPQ mpq = load("d2char"); + final MPQFileHandle handle = new MPQFileHandle(mpq, "data\\global\\CHARS\\BA\\COF\\BAA11HS.COF"); + Assert.assertTrue(handle.exists()); + System.out.println("searches: " + mpq.searches + ", misses: " + mpq.misses); + } + + @Test + public void stress_new() { + final MPQ d2speech = load("d2speech"); + final long start = System.currentTimeMillis(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_needhelp.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_needkey.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_needmana.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_no.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_notenoughmana.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_nothere.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_notintown.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_noway.wav").readByteBuf().release(); + new MPQFileHandle(d2speech, "data\\local\\sfx\\Common\\Amazon\\Ama_nowdie.wav").readByteBuf().release(); + System.out.println(System.currentTimeMillis() - start); + } + + @Test + public void stress_old() { + final long start = System.currentTimeMillis(); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_needhelp.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_needkey.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_needmana.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_no.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_notenoughmana.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_nothere.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_notintown.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_noway.wav"); + Riiablo.mpqs.d2speech.readBytes("data\\local\\sfx\\Common\\Amazon\\Ama_nowdie.wav"); + System.out.println(System.currentTimeMillis() - start); + } + + @Test + public void zloadAll_new() { + for (int i = 0; i < 1000; i++) { + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\patch_d2.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2exp.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xmusic.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xtalk.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2xvideo.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2data.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2char.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2sfx.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2music.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2speech.mpq")); + MPQ.load(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2video.mpq")); + } + } +} \ No newline at end of file diff --git a/core/test/com/riiablo/mpq_bytebuf/util/ADPCMTest.java b/core/test/com/riiablo/mpq_bytebuf/util/ADPCMTest.java new file mode 100644 index 00000000..e10fd299 --- /dev/null +++ b/core/test/com/riiablo/mpq_bytebuf/util/ADPCMTest.java @@ -0,0 +1,34 @@ +package com.riiablo.mpq_bytebuf.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import com.riiablo.RiiabloTest; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; + +public class ADPCMTest extends RiiabloTest { + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.mpq_bytebuf.util.ADPCM", Level.TRACE); + } + + @Test + public void decompress() { + FileHandle pcm_in = Gdx.files.internal("test/pcm_in.bin"); + ByteBuf actual = Unpooled.buffer(0x1000).writeBytes(pcm_in.readBytes()); + ADPCM.decompress(actual, 1); + System.out.println(ByteBufUtil.prettyHexDump(actual)); + + FileHandle pcm_out = Gdx.files.internal("test/pcm_out.bin"); + ByteBuf expected = Unpooled.wrappedBuffer(pcm_out.readBytes()); + Assert.assertTrue(ByteBufUtil.equals(expected, actual)); + } +} \ No newline at end of file diff --git a/core/test/com/riiablo/mpq_bytebuf/util/DecompressorTest.java b/core/test/com/riiablo/mpq_bytebuf/util/DecompressorTest.java new file mode 100644 index 00000000..8b780c8c --- /dev/null +++ b/core/test/com/riiablo/mpq_bytebuf/util/DecompressorTest.java @@ -0,0 +1,34 @@ +package com.riiablo.mpq_bytebuf.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import com.riiablo.RiiabloTest; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; + +public class DecompressorTest extends RiiabloTest { + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.mpq_bytebuf.util", Level.TRACE); + } + + @Test + public void decompress() { + FileHandle decompressor_in = Gdx.files.internal("test/decompressor_in.bin"); + ByteBuf actual = Unpooled.buffer(0x1000).writeBytes(decompressor_in.readBytes()); + Decompressor.decompress(actual, 1528, 4096); + System.out.println(ByteBufUtil.prettyHexDump(actual)); + + FileHandle decompressor_out = Gdx.files.internal("test/decompressor_out.bin"); + ByteBuf expected = Unpooled.wrappedBuffer(decompressor_out.readBytes()); + Assert.assertTrue(ByteBufUtil.equals(expected, actual)); + } +} \ No newline at end of file diff --git a/core/test/com/riiablo/mpq_bytebuf/util/DecryptorTest.java b/core/test/com/riiablo/mpq_bytebuf/util/DecryptorTest.java new file mode 100644 index 00000000..6d72bf1f --- /dev/null +++ b/core/test/com/riiablo/mpq_bytebuf/util/DecryptorTest.java @@ -0,0 +1,58 @@ +package com.riiablo.mpq_bytebuf.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import com.riiablo.RiiabloTest; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; + +import static com.riiablo.mpq_bytebuf.util.Decryptor.BLOCK_TABLE_KEY; +import static com.riiablo.mpq_bytebuf.util.Decryptor.HASH_ENCRYPTION_KEY; +import static com.riiablo.mpq_bytebuf.util.Decryptor.HASH_TABLE_KEY; +import static com.riiablo.mpq_bytebuf.util.Decryptor.SEED2; + +public class DecryptorTest extends RiiabloTest { + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.mpq_bytebuf.Decryptor", Level.TRACE); + } + @Test + public void HASH_TABLE_KEY() { + Assert.assertEquals(HASH_TABLE_KEY, HASH_ENCRYPTION_KEY.hash("(hash table)")); + } + + @Test + public void BLOCK_TABLE_KEY() { + Assert.assertEquals(BLOCK_TABLE_KEY, HASH_ENCRYPTION_KEY.hash("(block table)")); + } + + @Test + public void decrypt_hash_table() { + FileHandle hashtable_in = Gdx.files.internal("test/hashtable_in.bin"); + ByteBuf actual = Unpooled.wrappedBuffer(hashtable_in.readBytes()); + Decryptor.decrypt(HASH_TABLE_KEY, SEED2, actual); + + FileHandle hashtable_out = Gdx.files.internal("test/hashtable_out.bin"); + ByteBuf expected = Unpooled.wrappedBuffer(hashtable_out.readBytes()); + Assert.assertTrue(ByteBufUtil.equals(expected, actual)); + } + + @Test + public void decrypt_block_table() { + FileHandle blocktable_in = Gdx.files.internal("test/blocktable_in.bin"); + ByteBuf actual = Unpooled.wrappedBuffer(blocktable_in.readBytes()); + Decryptor.decrypt(BLOCK_TABLE_KEY, SEED2, actual); + + FileHandle blocktable_out = Gdx.files.internal("test/blocktable_out.bin"); + ByteBuf expected = Unpooled.wrappedBuffer(blocktable_out.readBytes()); + Assert.assertTrue(ByteBufUtil.equals(expected, actual)); + } +} \ No newline at end of file diff --git a/core/test/com/riiablo/mpq_bytebuf/util/ExploderTest.java b/core/test/com/riiablo/mpq_bytebuf/util/ExploderTest.java new file mode 100644 index 00000000..13b34948 --- /dev/null +++ b/core/test/com/riiablo/mpq_bytebuf/util/ExploderTest.java @@ -0,0 +1,34 @@ +package com.riiablo.mpq_bytebuf.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import com.riiablo.RiiabloTest; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; + +public class ExploderTest extends RiiabloTest { + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.mpq_bytebuf.util.Exploder", Level.TRACE); + } + + @Test + public void explode() { + FileHandle exploder_in = Gdx.files.internal("test/exploder_in.bin"); + ByteBuf actual = Unpooled.buffer(0x1000).writeBytes(exploder_in.readBytes()); + Exploder.pkexplode(actual); + System.out.println(ByteBufUtil.prettyHexDump(actual)); + + FileHandle exploder_out = Gdx.files.internal("test/exploder_out.bin"); + ByteBuf expected = Unpooled.wrappedBuffer(exploder_out.readBytes()); + Assert.assertTrue(ByteBufUtil.equals(expected, actual)); + } +} \ No newline at end of file diff --git a/core/test/com/riiablo/mpq_bytebuf/util/HuffmanTest.java b/core/test/com/riiablo/mpq_bytebuf/util/HuffmanTest.java new file mode 100644 index 00000000..76afe982 --- /dev/null +++ b/core/test/com/riiablo/mpq_bytebuf/util/HuffmanTest.java @@ -0,0 +1,34 @@ +package com.riiablo.mpq_bytebuf.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import com.riiablo.RiiabloTest; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; + +public class HuffmanTest extends RiiabloTest { + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.mpq_bytebuf.util.Huffman", Level.TRACE); + } + + @Test + public void decompress() { + FileHandle huffman_in = Gdx.files.internal("test/huffman_in.bin"); + ByteBuf actual = Unpooled.buffer(0x1000).writeBytes(huffman_in.readBytes()); + new Huffman().decompress(actual); + System.out.println(ByteBufUtil.prettyHexDump(actual)); + + FileHandle huffman_out = Gdx.files.internal("test/huffman_out.bin"); + ByteBuf expected = Unpooled.wrappedBuffer(huffman_out.readBytes()); + Assert.assertTrue(ByteBufUtil.equals(expected, actual)); + } +} \ No newline at end of file