diff --git a/cache/src/main/java/net/runelite/cache/Cache.java b/cache/src/main/java/net/runelite/cache/Cache.java index ad678bd88e..d8d1ca6f06 100644 --- a/cache/src/main/java/net/runelite/cache/Cache.java +++ b/cache/src/main/java/net/runelite/cache/Cache.java @@ -48,6 +48,7 @@ public class Cache options.addOption(null, "items", true, "directory to dump items to"); options.addOption(null, "npcs", true, "directory to dump npcs to"); options.addOption(null, "objects", true, "directory to dump objects to"); + options.addOption(null, "sprites", true, "directory to dump sprites to"); CommandLineParser parser = new DefaultParser(); CommandLine cmd; @@ -117,6 +118,7 @@ public class Cache if (itemdir == null) { System.err.println("Item directory must be specified"); + return; } System.out.println("Dumping items to " + itemdir); @@ -129,6 +131,7 @@ public class Cache if (npcdir == null) { System.err.println("NPC directory must be specified"); + return; } System.out.println("Dumping npcs to " + npcdir); @@ -141,11 +144,25 @@ public class Cache if (objectdir == null) { System.err.println("Object directory must be specified"); + return; } System.out.println("Dumping objects to " + objectdir); dumpObjects(store, new File(objectdir)); } + else if (cmd.hasOption("sprites")) + { + String spritedir = cmd.getOptionValue("sprites"); + + if (spritedir == null) + { + System.err.println("Sprite directory must be specified"); + return; + } + + System.out.println("Dumping sprites to " + spritedir); + dumpSprites(store, new File(spritedir)); + } else { System.err.println("Nothing to do"); @@ -192,4 +209,11 @@ public class Cache dumper.dump(); dumper.java(); } + + private static void dumpSprites(Store store, File spritedir) throws IOException + { + SpriteDumper dumper = new SpriteDumper(store, spritedir); + dumper.load(); + dumper.dump(); + } } diff --git a/cache/src/main/java/net/runelite/cache/SpriteDumper.java b/cache/src/main/java/net/runelite/cache/SpriteDumper.java new file mode 100644 index 0000000000..2fbf254407 --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/SpriteDumper.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016-2017, 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.imageio.ImageIO; +import net.runelite.cache.definitions.SpriteDefinition; +import net.runelite.cache.definitions.loaders.SpriteLoader; +import net.runelite.cache.fs.Archive; +import net.runelite.cache.fs.Index; +import net.runelite.cache.fs.Store; + +public class SpriteDumper +{ + private final Store store; + private final File outDir; + private final List sprites = new ArrayList<>(); + + public SpriteDumper(Store store, File outDir) + { + this.store = store; + this.outDir = outDir; + } + + public void load() + { + Index index = store.getIndex(IndexType.SPRITES); + + for (Archive a : index.getArchives()) + { + List files = a.getFiles(); + + assert files.size() == 1; + + net.runelite.cache.fs.File file = files.get(0); + byte[] contents = file.getContents(); + + SpriteLoader loader = new SpriteLoader(); + SpriteDefinition[] sprites = loader.load(a.getArchiveId(), contents); + + this.sprites.addAll(Arrays.asList(sprites)); + } + } + + public void dump() throws IOException + { + for (SpriteDefinition def : sprites) + { + // I don't know why this happens + if (def.getHeight() <= 0 || def.getWidth() <= 0) + { + continue; + } + + dump(def, outDir); + } + } + + public static void dump(SpriteDefinition sprite, File outDir) throws IOException + { + BufferedImage image = getBufferedImage(sprite); + File targ = new File(outDir, sprite.getId() + "-" + sprite.getFrame() + ".png"); + targ.mkdirs(); + ImageIO.write(image, "png", targ); + } + + private static BufferedImage getBufferedImage(SpriteDefinition def) + { + BufferedImage bi = new BufferedImage(def.getWidth(), def.getHeight(), BufferedImage.TYPE_INT_ARGB); + bi.setRGB(0, 0, def.getWidth(), def.getHeight(), def.getPixels(), 0, def.getWidth()); + return bi; + } +} diff --git a/cache/src/test/java/net/runelite/cache/SpriteDumperTest.java b/cache/src/test/java/net/runelite/cache/SpriteDumperTest.java index 4083f25f50..2eaec97b2f 100644 --- a/cache/src/test/java/net/runelite/cache/SpriteDumperTest.java +++ b/cache/src/test/java/net/runelite/cache/SpriteDumperTest.java @@ -22,21 +22,11 @@ * (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 java.awt.image.BufferedImage; +import java.io.File; import java.io.IOException; -import java.util.List; -import javax.imageio.ImageIO; -import net.runelite.cache.definitions.SpriteDefinition; -import net.runelite.cache.definitions.loaders.SpriteLoader; -import net.runelite.cache.fs.Archive; -import net.runelite.cache.fs.File; -import net.runelite.cache.fs.Index; import net.runelite.cache.fs.Store; -import net.runelite.cache.io.InputStream; -import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -51,56 +41,22 @@ public class SpriteDumperTest public TemporaryFolder folder = StoreLocation.getTemporaryFolder(); @Test - public void extract() throws IOException + public void test() throws IOException { - java.io.File base = StoreLocation.LOCATION, - outDir = folder.newFolder(); + File dumpDir = folder.newFolder(); - int count = 0; - - try (Store store = new Store(base)) + try (Store store = new Store(StoreLocation.LOCATION)) { store.load(); - - Index index = store.getIndex(IndexType.SPRITES); - - for (Archive a : index.getArchives()) - { - List files = a.getFiles(); - - Assert.assertEquals(1, files.size()); - - File file = files.get(0); - byte[] contents = file.getContents(); - - SpriteLoader loader = new SpriteLoader(); - SpriteDefinition[] sprites = loader.load(a.getArchiveId(), contents); - for (SpriteDefinition def : sprites) - { - // I don't know why this happens - if (def.getHeight() <= 0 || def.getWidth() <= 0) - continue; - - BufferedImage image = getBufferedImage(def); - java.io.File targ = new java.io.File(outDir, def.getId() + "-" + def.getFrame() + ".png"); - targ.mkdirs(); - ImageIO.write(image, "png", targ); - - ++count; - } - } + SpriteDumper dumper = new SpriteDumper( + store, + dumpDir + ); + dumper.load(); + dumper.dump(); } - Assert.assertTrue(count > 3000); - - logger.info("Dumped {} sprites to {}", count, outDir); - } - - private BufferedImage getBufferedImage(SpriteDefinition def) - { - BufferedImage bi = new BufferedImage(def.getWidth(), def.getHeight(), BufferedImage.TYPE_INT_ARGB); - bi.setRGB(0, 0, def.getWidth(), def.getHeight(), def.getPixels(), 0, def.getWidth()); - return bi; + logger.info("Dumped to {}", dumpDir); } }