diff --git a/pom.xml b/pom.xml
index ccb775cbae..f0f8bb8be5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,11 @@
sspace
2.0.4
+
+ com.google.code.gson
+ gson
+ 2.4
+
org.slf4j
diff --git a/src/main/java/net/runelite/cache/IndexType.java b/src/main/java/net/runelite/cache/IndexType.java
index 51e12c8ae8..b7af6dacfc 100644
--- a/src/main/java/net/runelite/cache/IndexType.java
+++ b/src/main/java/net/runelite/cache/IndexType.java
@@ -2,6 +2,7 @@ package net.runelite.cache;
public enum IndexType
{
+ TWO(2),
SPRITE(8);
private int id;
diff --git a/src/main/java/net/runelite/cache/definitions/ItemDefinition.java b/src/main/java/net/runelite/cache/definitions/ItemDefinition.java
index 133cf79497..f76bf5c80e 100644
--- a/src/main/java/net/runelite/cache/definitions/ItemDefinition.java
+++ b/src/main/java/net/runelite/cache/definitions/ItemDefinition.java
@@ -1,191 +1,78 @@
-//package net.runelite.cache.definitions;
-//
-//import net.runelite.cache.io.InputStream;
-//import net.runelite.cache.utils.StringUtilities;
-//
-///**
-// * Created by Allen Kinzalow on 3/14/2015.
-// */
-//public class ItemDefinition extends Definition {
-//
-// public final static int INDEX_ID = 2;
-// public final static int ARCHIVE_ID = 10;
-//
-// public int resizeY;
-// public int xan2d = 0;
-// public int cost = 1;
-// public int inventoryModel;
-// public int resizeZ;
-// public short[] colorFind;
-// public short[] colorReplace;
-// public short[] textureFind;
-// public String name = "null";
-// public int zoom2d = 200000;
-// public int yan2d = 0;
-// public int zan2d = 0;
-// public int maleOffset;
-// public int yOffset2d = 0;
-// public int stackable = 0;
-// public int[] countCo;
-// public boolean members = false;
-// public String[] options;
-// public String[] interfaceOptions;
-// public int maleModel0;
-// public int maleModel1;
-// public short[] textureReplace;
-// public int femaleModel1;
-// public int femaleOffset;
-// public int maleModel2;
-// public int xOffset2d = 0;
-// public int maleHeadModel;
-// public int maleHeadModel2;
-// public int femaleHeadModel;
-// public int femaleHeadModel2;
-// public int[] countObj;
-// public int femaleModel2;
-// public int notedID;
-// public int femaleModel0;
-// public int resizeX;
-// public int notedTemplate;
-// public int ambient;
-// public int contrast;
-// public int team;
-//
-// public ItemDefinition(int definitionID) {
-// super(definitionID);
-// this.options = new String[]{null, null, "Take", null, null};
-// this.interfaceOptions = new String[]{null, null, null, null, "Drop"};
-// this.maleModel0 = -1;
-// this.maleModel1 = -1;
-// this.maleOffset = 0;
-// this.femaleModel0 = -1;
-// this.femaleModel1 = -1;
-// this.femaleOffset = 0;
-// this.maleModel2 = -1;
-// this.femaleModel2 = -1;
-// this.maleHeadModel = -1;
-// this.maleHeadModel2 = -1;
-// this.femaleHeadModel = -1;
-// this.femaleHeadModel2 = -1;
-// this.notedID = -1;
-// this.notedTemplate = -1;
-// this.resizeX = 0;
-// this.resizeY = 0;
-// this.resizeZ = 0;
-// this.ambient = 0;
-// this.contrast = 0;
-// this.team = 0;
-// }
-//
-// @Override
-// void decodeValues(int opcode, InputStream stream) {
-// if (opcode == 1) {
-// this.inventoryModel = stream.readUnsignedShort();
-// } else if (opcode == 2) {
-// this.name = StringUtilities.readString_2(stream);
-// } else if (opcode == 4) {
-// this.zoom2d = stream.readUnsignedShort();
-// } else if (opcode == 5) {
-// this.xan2d = stream.readUnsignedShort();
-// } else if (opcode == 6) {
-// this.yan2d = stream.readUnsignedShort();
-// } else if (7 == opcode) {
-// this.xOffset2d = stream.readUnsignedShort();
-// if (this.xOffset2d > 32767) {
-// this.xOffset2d -= 65536;
-// }
-// } else if (8 == opcode) {
-// this.yOffset2d = stream.readUnsignedShort();
-// if (this.yOffset2d > 32767) {
-// this.yOffset2d -= 65536;
-// }
-// } else if (11 == opcode) {
-// this.stackable = 1;
-// } else if (opcode == 12) {
-// this.cost = stream.readInt();
-// } else if (16 == opcode) {
-// this.members = true;
-// } else if (opcode == 23) {
-// this.maleModel0 = stream.readUnsignedShort();
-// this.maleOffset = stream.readUnsignedByte();
-// } else if (opcode == 24) {
-// this.maleModel1 = stream.readUnsignedShort();
-// } else if (25 == opcode) {
-// this.femaleModel0 = stream.readUnsignedShort();
-// this.femaleOffset = stream.readUnsignedByte();
-// } else if (26 == opcode) {
-// this.femaleModel1 = stream.readUnsignedShort();
-// } else if (opcode >= 30 && opcode < 35) {
-// this.options[opcode - 30] = StringUtilities.readString_2(stream);
-// if (this.options[opcode - 30].equalsIgnoreCase("Hidden")) {
-// this.options[opcode - 30] = null;
-// }
-// } else if (opcode >= 35 && opcode < 40) {
-// this.interfaceOptions[opcode - 35] = StringUtilities.readString_2(stream);
-// } else {
-// int var4;
-// int var5;
-// if (opcode == 40) {
-// var5 = stream.readUnsignedByte();
-// this.colorFind = new short[var5];
-// this.colorReplace = new short[var5];
-//
-// for (var4 = 0; var4 < var5; ++var4) {
-// this.colorFind[var4] = (short) stream.readUnsignedShort();
-// this.colorReplace[var4] = (short) stream.readUnsignedShort();
-// }
-//
-// } else if (41 != opcode) {
-// if (opcode == 78) {
-// this.maleModel2 = stream.readUnsignedShort();
-// } else if (opcode == 79) {
-// this.femaleModel2 = stream.readUnsignedShort();
-// } else if (90 == opcode) {
-// this.maleHeadModel = stream.readUnsignedShort();
-// } else if (91 == opcode) {
-// this.femaleHeadModel = stream.readUnsignedShort();
-// } else if (92 == opcode) {
-// this.maleHeadModel2 = stream.readUnsignedShort();
-// } else if (opcode == 93) {
-// this.femaleHeadModel2 = stream.readUnsignedShort();
-// } else if (opcode == 95) {
-// this.zan2d = stream.readUnsignedShort();
-// } else if (97 == opcode) {
-// this.notedID = stream.readUnsignedShort();
-// } else if (98 == opcode) {
-// this.notedTemplate = stream.readUnsignedShort();
-// } else if (opcode >= 100 && opcode < 110) {
-// if (this.countObj == null) {
-// this.countObj = new int[10];
-// this.countCo = new int[10];
-// }
-//
-// this.countObj[opcode - 100] = stream.readUnsignedShort();
-// this.countCo[opcode - 100] = stream.readUnsignedShort();
-// } else if (110 == opcode) {
-// this.resizeX = stream.readUnsignedShort();
-// } else if (opcode == 111) {
-// this.resizeY = stream.readUnsignedShort();
-// } else if (opcode == 112) {
-// this.resizeZ = stream.readUnsignedShort();
-// } else if (opcode == 113) {
-// this.ambient = stream.readByte();
-// } else if (114 == opcode) {
-// this.contrast = stream.readByte();
-// } else if (115 == opcode) {
-// this.team = stream.readUnsignedByte();
-// }
-// } else {
-// var5 = stream.readUnsignedByte();
-// this.textureFind = new short[var5];
-// this.textureReplace = new short[var5];
-//
-// for (var4 = 0; var4 < var5; ++var4) {
-// this.textureFind[var4] = (short) stream.readUnsignedShort();
-// this.textureReplace[var4] = (short) stream.readUnsignedShort();
-// }
-//
-// }
-// }
-// }
-//}
+package net.runelite.cache.definitions;
+
+public class ItemDefinition
+{
+ public int id;
+ public int resizeY;
+ public int xan2d = 0;
+ public int cost = 1;
+ public int inventoryModel;
+ public int resizeZ;
+ public short[] colorFind;
+ public short[] colorReplace;
+ public short[] textureFind;
+ public String name = "null";
+ public int zoom2d = 200000;
+ public int yan2d = 0;
+ public int zan2d = 0;
+ public int maleOffset;
+ public int yOffset2d = 0;
+ public int stackable = 0;
+ public int[] countCo;
+ public boolean members = false;
+ public String[] options;
+ public String[] interfaceOptions;
+ public int maleModel0;
+ public int maleModel1;
+ public short[] textureReplace;
+ public int femaleModel1;
+ public int femaleOffset;
+ public int maleModel2;
+ public int xOffset2d = 0;
+ public int maleHeadModel;
+ public int maleHeadModel2;
+ public int femaleHeadModel;
+ public int femaleHeadModel2;
+ public int[] countObj;
+ public int femaleModel2;
+ public int notedID;
+ public int femaleModel0;
+ public int resizeX;
+ public int notedTemplate;
+ public int ambient;
+ public int contrast;
+ public int team;
+
+ public ItemDefinition(int definitionID)
+ {
+ this.id = definitionID;
+ this.options = new String[]
+ {
+ null, null, "Take", null, null
+ };
+ this.interfaceOptions = new String[]
+ {
+ null, null, null, null, "Drop"
+ };
+ this.maleModel0 = -1;
+ this.maleModel1 = -1;
+ this.maleOffset = 0;
+ this.femaleModel0 = -1;
+ this.femaleModel1 = -1;
+ this.femaleOffset = 0;
+ this.maleModel2 = -1;
+ this.femaleModel2 = -1;
+ this.maleHeadModel = -1;
+ this.maleHeadModel2 = -1;
+ this.femaleHeadModel = -1;
+ this.femaleHeadModel2 = -1;
+ this.notedID = -1;
+ this.notedTemplate = -1;
+ this.resizeX = 0;
+ this.resizeY = 0;
+ this.resizeZ = 0;
+ this.ambient = 0;
+ this.contrast = 0;
+ this.team = 0;
+ }
+}
diff --git a/src/main/java/net/runelite/cache/definitions/loaders/ItemLoader.java b/src/main/java/net/runelite/cache/definitions/loaders/ItemLoader.java
new file mode 100644
index 0000000000..c9e3200725
--- /dev/null
+++ b/src/main/java/net/runelite/cache/definitions/loaders/ItemLoader.java
@@ -0,0 +1,224 @@
+package net.runelite.cache.definitions.loaders;
+
+import java.util.ArrayList;
+import java.util.List;
+import net.runelite.cache.IndexType;
+import net.runelite.cache.definitions.ItemDefinition;
+import net.runelite.cache.io.InputStream;
+import net.runelite.cache.utils.StringUtilities;
+
+public class ItemLoader
+{
+ public static final IndexType INDEX_TYPE = IndexType.TWO;
+ public static final int ARCHIVE_ID = 10;
+
+ private final List items = new ArrayList<>();
+
+ public List getItems()
+ {
+ return items;
+ }
+
+ public void load(int id, InputStream stream)
+ {
+ ItemDefinition def = new ItemDefinition(id);
+ while (true)
+ {
+ int opcode = stream.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ this.decodeValues(opcode, def, stream);
+ }
+ items.add(def);
+ }
+
+ private void decodeValues(int opcode, ItemDefinition def, InputStream stream)
+ {
+ if (opcode == 1)
+ {
+ def.inventoryModel = stream.readUnsignedShort();
+ }
+ else if (opcode == 2)
+ {
+ def.name = StringUtilities.readString_2(stream);
+ }
+ else if (opcode == 4)
+ {
+ def.zoom2d = stream.readUnsignedShort();
+ }
+ else if (opcode == 5)
+ {
+ def.xan2d = stream.readUnsignedShort();
+ }
+ else if (opcode == 6)
+ {
+ def.yan2d = stream.readUnsignedShort();
+ }
+ else if (7 == opcode)
+ {
+ def.xOffset2d = stream.readUnsignedShort();
+ if (def.xOffset2d > 32767)
+ {
+ def.xOffset2d -= 65536;
+ }
+ }
+ else if (8 == opcode)
+ {
+ def.yOffset2d = stream.readUnsignedShort();
+ if (def.yOffset2d > 32767)
+ {
+ def.yOffset2d -= 65536;
+ }
+ }
+ else if (11 == opcode)
+ {
+ def.stackable = 1;
+ }
+ else if (opcode == 12)
+ {
+ def.cost = stream.readInt();
+ }
+ else if (16 == opcode)
+ {
+ def.members = true;
+ }
+ else if (opcode == 23)
+ {
+ def.maleModel0 = stream.readUnsignedShort();
+ def.maleOffset = stream.readUnsignedByte();
+ }
+ else if (opcode == 24)
+ {
+ def.maleModel1 = stream.readUnsignedShort();
+ }
+ else if (25 == opcode)
+ {
+ def.femaleModel0 = stream.readUnsignedShort();
+ def.femaleOffset = stream.readUnsignedByte();
+ }
+ else if (26 == opcode)
+ {
+ def.femaleModel1 = stream.readUnsignedShort();
+ }
+ else if (opcode >= 30 && opcode < 35)
+ {
+ def.options[opcode - 30] = StringUtilities.readString_2(stream);
+ if (def.options[opcode - 30].equalsIgnoreCase("Hidden"))
+ {
+ def.options[opcode - 30] = null;
+ }
+ }
+ else if (opcode >= 35 && opcode < 40)
+ {
+ def.interfaceOptions[opcode - 35] = StringUtilities.readString_2(stream);
+ }
+ else
+ {
+ int var4;
+ int var5;
+ if (opcode == 40)
+ {
+ var5 = stream.readUnsignedByte();
+ def.colorFind = new short[var5];
+ def.colorReplace = new short[var5];
+
+ for (var4 = 0; var4 < var5; ++var4)
+ {
+ def.colorFind[var4] = (short) stream.readUnsignedShort();
+ def.colorReplace[var4] = (short) stream.readUnsignedShort();
+ }
+
+ }
+ else if (41 != opcode)
+ {
+ if (opcode == 78)
+ {
+ def.maleModel2 = stream.readUnsignedShort();
+ }
+ else if (opcode == 79)
+ {
+ def.femaleModel2 = stream.readUnsignedShort();
+ }
+ else if (90 == opcode)
+ {
+ def.maleHeadModel = stream.readUnsignedShort();
+ }
+ else if (91 == opcode)
+ {
+ def.femaleHeadModel = stream.readUnsignedShort();
+ }
+ else if (92 == opcode)
+ {
+ def.maleHeadModel2 = stream.readUnsignedShort();
+ }
+ else if (opcode == 93)
+ {
+ def.femaleHeadModel2 = stream.readUnsignedShort();
+ }
+ else if (opcode == 95)
+ {
+ def.zan2d = stream.readUnsignedShort();
+ }
+ else if (97 == opcode)
+ {
+ def.notedID = stream.readUnsignedShort();
+ }
+ else if (98 == opcode)
+ {
+ def.notedTemplate = stream.readUnsignedShort();
+ }
+ else if (opcode >= 100 && opcode < 110)
+ {
+ if (def.countObj == null)
+ {
+ def.countObj = new int[10];
+ def.countCo = new int[10];
+ }
+
+ def.countObj[opcode - 100] = stream.readUnsignedShort();
+ def.countCo[opcode - 100] = stream.readUnsignedShort();
+ }
+ else if (110 == opcode)
+ {
+ def.resizeX = stream.readUnsignedShort();
+ }
+ else if (opcode == 111)
+ {
+ def.resizeY = stream.readUnsignedShort();
+ }
+ else if (opcode == 112)
+ {
+ def.resizeZ = stream.readUnsignedShort();
+ }
+ else if (opcode == 113)
+ {
+ def.ambient = stream.readByte();
+ }
+ else if (114 == opcode)
+ {
+ def.contrast = stream.readByte();
+ }
+ else if (115 == opcode)
+ {
+ def.team = stream.readUnsignedByte();
+ }
+ }
+ else
+ {
+ var5 = stream.readUnsignedByte();
+ def.textureFind = new short[var5];
+ def.textureReplace = new short[var5];
+
+ for (var4 = 0; var4 < var5; ++var4)
+ {
+ def.textureFind[var4] = (short) stream.readUnsignedShort();
+ def.textureReplace[var4] = (short) stream.readUnsignedShort();
+ }
+
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java b/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java
index faf91fe018..93181c2ed1 100644
--- a/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java
+++ b/src/main/java/net/runelite/cache/definitions/loaders/SpriteLoader.java
@@ -11,7 +11,7 @@ public class SpriteLoader
private int loadedSpriteMaxWidth;
private int loadedSpriteMaxHeight;
- public void decode(InputStream stream)
+ public void load(InputStream stream)
{
stream.setOffset(stream.getLength() - 2);
int paletteChildCount = stream.readUnsignedShort();
diff --git a/src/main/java/net/runelite/cache/fs/Index.java b/src/main/java/net/runelite/cache/fs/Index.java
index a5a616ec14..049ce33c3f 100644
--- a/src/main/java/net/runelite/cache/fs/Index.java
+++ b/src/main/java/net/runelite/cache/fs/Index.java
@@ -99,6 +99,14 @@ public class Index implements Closeable
return archive;
}
+ public Archive getArchive(int id)
+ {
+ for (Archive a : archives)
+ if (a.getArchiveId() == id)
+ return a;
+ return null;
+ }
+
public void load() throws IOException
{
DataFile dataFile = store.getData();
diff --git a/src/main/java/net/runelite/cache/renderable/RGBSprite.java b/src/main/java/net/runelite/cache/renderable/RGBSprite.java
index f50c04e876..83c28aaa50 100644
--- a/src/main/java/net/runelite/cache/renderable/RGBSprite.java
+++ b/src/main/java/net/runelite/cache/renderable/RGBSprite.java
@@ -89,7 +89,7 @@ public class RGBSprite
private static Image makeColorTransparent(BufferedImage im, final Color color)
{
- int markerRGB = color.getRGB() | 0xFF000000;
+ final int markerRGB = color.getRGB() | 0xFF000000;
RGBImageFilter filter = new RGBImageFilter()
{
diff --git a/src/test/java/net/runelite/cache/loaders/ItemLoaderTest.java b/src/test/java/net/runelite/cache/loaders/ItemLoaderTest.java
new file mode 100644
index 0000000000..e245f904e6
--- /dev/null
+++ b/src/test/java/net/runelite/cache/loaders/ItemLoaderTest.java
@@ -0,0 +1,60 @@
+package net.runelite.cache.loaders;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.FileWriter;
+import java.io.IOException;
+import net.runelite.cache.StoreLocation;
+import net.runelite.cache.definitions.ItemDefinition;
+import net.runelite.cache.definitions.loaders.ItemLoader;
+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.Test;
+
+public class ItemLoaderTest
+{
+ @Test
+ public void extract() throws IOException
+ {
+ ItemLoader loader = new ItemLoader();
+
+ java.io.File base = StoreLocation.LOCATION;
+ try (Store store = new Store(base))
+ {
+ store.load();
+
+ Index index = store.getIndex(ItemLoader.INDEX_TYPE);
+ Archive archive = index.getArchive(ItemLoader.ARCHIVE_ID);
+
+ for (File f : archive.getFiles())
+ {
+ loader.load(f.getFileId(), new InputStream(f.getContents()));
+ }
+
+ //for (Archive a : index.getArchives())
+ //{
+ // List files = a.getFiles();
+
+ // Assert.assertEquals(1, files.size());
+ //}
+ }
+
+ new java.io.File(base, "items").mkdir();
+
+ GsonBuilder builder = new GsonBuilder()
+ .setPrettyPrinting();
+ Gson g = builder.create();
+
+ for (ItemDefinition def : loader.getItems())
+ {
+ java.io.File targ = new java.io.File(base, "items/" + def.id + ".json");
+ try (FileWriter fw = new FileWriter(targ))
+ {
+ fw.write(g.toJson(def));
+ }
+ }
+ }
+}
diff --git a/src/test/java/net/runelite/cache/loaders/SpriteLoaderTest.java b/src/test/java/net/runelite/cache/loaders/SpriteLoaderTest.java
index 91119eaf7e..5bc033a1b3 100644
--- a/src/test/java/net/runelite/cache/loaders/SpriteLoaderTest.java
+++ b/src/test/java/net/runelite/cache/loaders/SpriteLoaderTest.java
@@ -39,7 +39,7 @@ public class SpriteLoaderTest
byte[] contents = file.getContents();
SpriteLoader loader = new SpriteLoader();
- loader.decode(new InputStream(contents));
+ loader.load(new InputStream(contents));
SpriteDefinition[] defs = loader.getSprites();