Split cache from deobfuscator into own project

This commit is contained in:
Adam
2016-05-28 19:42:03 -04:00
parent fdd60f0882
commit c42d313c38
53 changed files with 7385 additions and 1 deletions

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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;
public enum ConfigType
{
// types from https://github.com/im-frizzy/OpenRS/blob/master/source/net/openrs/cache/type/ConfigArchive.java
UNDERLAY(1),
IDENTKIT(3),
OVERLAY(4),
INV(5),
OBJECT(6),
ENUM(8),
NPC(9),
ITEM(10),
SEQUENCE(12),
SPOTANIM(13),
VARBIT(14),
VARCLIENT(19),
VARCLIENTSTRING(15),
VARPLAYER(16);
private final int id;
ConfigType(int id)
{
this.id = id;
}
public int getId()
{
return id;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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;
public enum IndexType
{
// names from https://github.com/im-frizzy/OpenRS/blob/master/source/net/openrs/cache/type/CacheIndex.java
SKINS(1),
CONFIGS(2),
INTERFACES(3),
SOUNDEFFECTS(4),
LANDSCAPES(5),
TRACK1(6),
MODELS(7),
SPRITES(8),
TEXTURES(9),
BINARY(10),
TRACK2(11),
CLIENTSCRIPT(12),
FONTS(13),
VORBIS(14),
INSTRUMENTS(15);
private int id;
IndexType(int id)
{
this.id = id;
}
public int getNumber()
{
return id;
}
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
import net.runelite.cache.definitions.ItemDefinition;
import net.runelite.cache.definitions.loaders.ItemLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
import net.runelite.cache.io.InputStream;
public class ItemDumper
{
private final File cache, out, java;
private final Gson gson;
private ItemLoader loader;
public ItemDumper(File cache, File out, File java)
{
this.cache = cache;
this.out = out;
this.java = java;
GsonBuilder builder = new GsonBuilder()
.setPrettyPrinting();
gson = builder.create();
}
public static void main(String[] args) throws IOException
{
if (args.length < 3)
System.exit(1);
File cache = new File(args[0]);
File out = new File(args[1]);
File java = new File(args[2]);
ItemDumper dumper = new ItemDumper(cache, out, java);
dumper.load();
dumper.dump();
dumper.java();
}
public void load() throws IOException
{
loader = new ItemLoader();
try (Store store = new Store(cache))
{
store.load();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.ITEM.getId());
for (net.runelite.cache.fs.File f : archive.getFiles())
{
loader.load(f.getFileId(), new InputStream(f.getContents()));
}
}
}
public void dump() throws IOException
{
for (ItemDefinition def : loader.getItems())
{
out.mkdirs();
java.io.File targ = new java.io.File(out, def.id + ".json");
try (FileWriter fw = new FileWriter(targ))
{
fw.write(gson.toJson(def));
}
}
}
public void java() throws IOException
{
java.mkdirs();
java.io.File targ = new java.io.File(java, "ItemID.java");
try (PrintWriter fw = new PrintWriter(targ))
{
Set<String> used = new HashSet<>();
fw.println("/* This file is automatically generated. Do not edit. */");
fw.println("package net.runelite.api;");
fw.println("");
fw.println("public final class ItemID {");
for (ItemDefinition def : loader.getItems())
{
if (def.name.equalsIgnoreCase("NULL"))
continue;
String name = name(def.name);
if (name == null)
continue;
String suffix = "";
while (used.contains(name + suffix))
{
if (suffix.isEmpty())
suffix = "_2";
else
suffix = "_" + (Integer.parseInt(suffix.substring(1)) + 1);
}
name += suffix;
used.add(name);
fw.println(" public static final int " + name + " = " + def.id + ";");
}
fw.println("}");
}
}
private static String name(String in)
{
String s = in.toUpperCase()
.replace(' ', '_')
.replaceAll("[^a-zA-Z0-9_]", "");
if (s.isEmpty())
return null;
if (Character.isDigit(s.charAt(0)))
return "_" + s;
else
return s;
}
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
import net.runelite.cache.definitions.NpcDefinition;
import net.runelite.cache.definitions.loaders.NpcLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
import net.runelite.cache.io.InputStream;
public class NpcDumper
{
private final File cache, out, java;
private final Gson gson;
private NpcLoader loader;
public NpcDumper(File cache, File out, File java)
{
this.cache = cache;
this.out = out;
this.java = java;
GsonBuilder builder = new GsonBuilder()
.setPrettyPrinting();
gson = builder.create();
}
public static void main(String[] args) throws IOException
{
if (args.length < 3)
System.exit(1);
File cache = new File(args[0]);
File out = new File(args[1]);
File java = new File(args[2]);
ItemDumper dumper = new ItemDumper(cache, out, java);
dumper.load();
dumper.dump();
dumper.java();
}
public void load() throws IOException
{
loader = new NpcLoader();
try (Store store = new Store(cache))
{
store.load();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.NPC.getId());
for (net.runelite.cache.fs.File f : archive.getFiles())
{
loader.load(f.getFileId(), new InputStream(f.getContents()));
}
}
}
public void dump() throws IOException
{
for (NpcDefinition def : loader.getNpcs())
{
out.mkdirs();
java.io.File targ = new java.io.File(out, def.id + ".json");
try (FileWriter fw = new FileWriter(targ))
{
fw.write(gson.toJson(def));
}
}
}
public void java() throws IOException
{
java.mkdirs();
java.io.File targ = new java.io.File(java, "NpcID.java");
try (PrintWriter fw = new PrintWriter(targ))
{
Set<String> used = new HashSet<>();
fw.println("/* This file is automatically generated. Do not edit. */");
fw.println("package net.runelite.api;");
fw.println("");
fw.println("public final class NpcID {");
for (NpcDefinition def : loader.getNpcs())
{
if (def.name.equalsIgnoreCase("NULL"))
continue;
String name = name(def.name);
if (name == null)
continue;
String suffix = "";
while (used.contains(name + suffix))
{
if (suffix.isEmpty())
suffix = "_2";
else
suffix = "_" + (Integer.parseInt(suffix.substring(1)) + 1);
}
name += suffix;
used.add(name);
fw.println(" public static final int " + name + " = " + def.id + ";");
}
fw.println("}");
}
}
private static String name(String in)
{
String s = in.toUpperCase()
.replace(' ', '_')
.replaceAll("[^a-zA-Z0-9_]", "");
if (s.isEmpty())
return null;
if (Character.isDigit(s.charAt(0)))
return "_" + s;
else
return s;
}
}

View File

@@ -0,0 +1,165 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.runelite.cache.definitions.ObjectDefinition;
import net.runelite.cache.definitions.loaders.ObjectLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
public class ObjectDumper
{
private final File cache, out, java;
private final Gson gson;
private ObjectLoader loader;
private final List<ObjectDefinition> objects = new ArrayList<>();
public ObjectDumper(File cache, File out, File java)
{
this.cache = cache;
this.out = out;
this.java = java;
GsonBuilder builder = new GsonBuilder()
.setPrettyPrinting();
gson = builder.create();
}
public static void main(String[] args) throws IOException
{
if (args.length < 3)
System.exit(1);
File cache = new File(args[0]);
File out = new File(args[1]);
File java = new File(args[2]);
ObjectDumper dumper = new ObjectDumper(cache, out, java);
dumper.load();
dumper.dump();
dumper.java();
}
public void load() throws IOException
{
loader = new ObjectLoader();
try (Store store = new Store(cache))
{
store.load();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.OBJECT.getId());
for (net.runelite.cache.fs.File f : archive.getFiles())
{
ObjectDefinition def = loader.load(f.getFileId(), f.getContents());
objects.add(def);
}
}
}
public void dump() throws IOException
{
for (ObjectDefinition def : objects)
{
out.mkdirs();
java.io.File targ = new java.io.File(out, def.getId() + ".json");
try (FileWriter fw = new FileWriter(targ))
{
fw.write(gson.toJson(def));
}
}
}
public void java() throws IOException
{
java.mkdirs();
java.io.File targ = new java.io.File(java, "ObjectID.java");
try (PrintWriter fw = new PrintWriter(targ))
{
Set<String> used = new HashSet<>();
fw.println("/* This file is automatically generated. Do not edit. */");
fw.println("package net.runelite.api;");
fw.println("");
fw.println("public final class ObjectID {");
for (ObjectDefinition def : objects)
{
if (def.getName().equalsIgnoreCase("NULL"))
continue;
String name = name(def.getName());
if (name == null)
continue;
String suffix = "";
while (used.contains(name + suffix))
{
if (suffix.isEmpty())
suffix = "_2";
else
suffix = "_" + (Integer.parseInt(suffix.substring(1)) + 1);
}
name += suffix;
used.add(name);
fw.println(" public static final int " + name + " = " + def.getId() + ";");
}
fw.println("}");
}
}
private static String name(String in)
{
String s = in.toUpperCase()
.replace(' ', '_')
.replaceAll("[^a-zA-Z0-9_]", "");
if (s.isEmpty())
return null;
if (Character.isDigit(s.charAt(0)))
return "_" + s;
else
return s;
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions;
public class EnumDefinition
{
private int id;
private int[] intVals;
private char keyType;
private char valType;
private String defaultString = "null";
private int defaultInt;
private int size;
private int[] keys;
private String[] stringVals;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public int[] getIntVals()
{
return intVals;
}
public void setIntVals(int[] intVals)
{
this.intVals = intVals;
}
public char getKeyType()
{
return keyType;
}
public void setKeyType(char keyType)
{
this.keyType = keyType;
}
public char getValType()
{
return valType;
}
public void setValType(char valType)
{
this.valType = valType;
}
public String getDefaultString()
{
return defaultString;
}
public void setDefaultString(String defaultString)
{
this.defaultString = defaultString;
}
public int getDefaultInt()
{
return defaultInt;
}
public void setDefaultInt(int defaultInt)
{
this.defaultInt = defaultInt;
}
public int getSize()
{
return size;
}
public void setSize(int size)
{
this.size = size;
}
public int[] getKeys()
{
return keys;
}
public void setKeys(int[] keys)
{
this.keys = keys;
}
public String[] getStringVals()
{
return stringVals;
}
public void setStringVals(String[] stringVals)
{
this.stringVals = stringVals;
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.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;
}
}

View File

@@ -0,0 +1,45 @@
package net.runelite.cache.definitions;
public class ModelDefinition
{
public short[] texTriangleX;
public int[] vertexX;
public byte[] faceRenderPriorities;
public int[] vertexY;
public int triangleFaceCount;
public int[] trianglePointsX;
public int[] vertexSkins;
public int[] trianglePointsZ;
public int anInt2562;
public int[] trianglePointsY;
public byte[] faceAlphas;
public short aShort2565;
public byte[] faceRenderType;
public short[] faceTextures;
public byte priority;
public int anInt2569;
public byte[] textureRenderTypes;
public short[] texTriangleY;
public short[] texTriangleZ;
public short[] aShortArray2574;
public short[] aShortArray2575;
public short[] aShortArray2577;
public short[] aShortArray2578;
boolean aBool2579;
public byte[] aByteArray2580;
public byte[] textureCoords;
public int[] triangleSkinValues;
public int[][] anIntArrayArray2583;
public int[][] anIntArrayArray2584;
public short[] aShortArray2586;
public short aShort2589;
public short[] faceColor;
public int shadowIntensity;
public int anInt2592;
public int anInt2593;
public int[] vertexZ;
public int anInt2595;
public int vertexCount = 0;
public short[] texturePrimaryColor;
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions;
public class NpcDefinition
{
public int id;
public short[] recolorToFind;
public int anInt2156 = 32;
public String name = "null";
public short[] recolorToReplace;
public int[] models;
public int[] models_2;
public int stanceAnimation = -1;
public int anInt2165 = -1;
public int tileSpacesOccupied = 1;
public int walkAnimation = -1;
public short[] retextureToReplace;
public int rotate90RightAnimation = -1;
public boolean aBool2170 = true;
public int resizeX = 128;
public int contrast = 0;
public int rotate180Animation = -1;
public int anInt2174 = -1;
public String[] options = new String[5];
public boolean renderOnMinimap = true;
public int combatLevel = -1;
public int rotate90LeftAnimation = -1;
public int resizeY = 128;
public boolean hasRenderPriority = false;
public int ambient = 0;
public int headIcon = -1;
public int anInt2184 = 30;
public int[] anIntArray2185;
public short[] retextureToFind;
public int anInt2187 = -1;
public boolean isClickable = true;
public int anInt2189 = -1;
public boolean aBool2190 = false;
public NpcDefinition(int definitionID)
{
this.id = definitionID;
}
}

View File

@@ -0,0 +1,508 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions;
public class ObjectDefinition
{
private int id;
private short[] retextureToFind;
private int anInt2069 = 16;
private boolean isSolid = false;
private String name = "null";
private int[] objectModels;
private int[] objectTypes;
private short[] recolorToFind;
private int mapIconID = -1;
private short[] textureToReplace;
private int sizeX = 1;
private int sizeY = 1;
private int anInt2083 = 0;
private int[] anIntArray2084;
private int offsetX = 0;
private boolean nonFlatShading = false;
private int anInt2088 = -1;
private int animationID = -1;
private int varpID = -1;
private int ambient = 0;
private int contrast = 0;
private String[] actions = new String[5];
private int anInt2094 = 2;
private int mapSceneID = -1;
private short[] recolorToReplace;
private boolean aBool2097 = true;
private int modelSizeX = 128;
private int modelSizeHeight = 128;
private int modelSizeY = 128;
private int objectID;
private int offsetHeight = 0;
private int offsetY = 0;
private boolean aBool2104 = false;
private int anInt2105 = -1;
private int anInt2106 = -1;
private int[] configChangeDest;
private boolean aBool2108 = false;
private int configId = -1;
private int anInt2110 = -1;
private boolean aBool2111 = false;
private int anInt2112 = 0;
private int anInt2113 = 0;
private boolean aBool2114 = true;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public short[] getRetextureToFind()
{
return retextureToFind;
}
public void setRetextureToFind(short[] retextureToFind)
{
this.retextureToFind = retextureToFind;
}
public int getAnInt2069()
{
return anInt2069;
}
public void setAnInt2069(int anInt2069)
{
this.anInt2069 = anInt2069;
}
public boolean isIsSolid()
{
return isSolid;
}
public void setIsSolid(boolean isSolid)
{
this.isSolid = isSolid;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int[] getObjectModels()
{
return objectModels;
}
public void setObjectModels(int[] objectModels)
{
this.objectModels = objectModels;
}
public int[] getObjectTypes()
{
return objectTypes;
}
public void setObjectTypes(int[] objectTypes)
{
this.objectTypes = objectTypes;
}
public short[] getRecolorToFind()
{
return recolorToFind;
}
public void setRecolorToFind(short[] recolorToFind)
{
this.recolorToFind = recolorToFind;
}
public int getMapIconID()
{
return mapIconID;
}
public void setMapIconID(int mapIconID)
{
this.mapIconID = mapIconID;
}
public short[] getTextureToReplace()
{
return textureToReplace;
}
public void setTextureToReplace(short[] textureToReplace)
{
this.textureToReplace = textureToReplace;
}
public int getSizeX()
{
return sizeX;
}
public void setSizeX(int sizeX)
{
this.sizeX = sizeX;
}
public int getSizeY()
{
return sizeY;
}
public void setSizeY(int sizeY)
{
this.sizeY = sizeY;
}
public int getAnInt2083()
{
return anInt2083;
}
public void setAnInt2083(int anInt2083)
{
this.anInt2083 = anInt2083;
}
public int[] getAnIntArray2084()
{
return anIntArray2084;
}
public void setAnIntArray2084(int[] anIntArray2084)
{
this.anIntArray2084 = anIntArray2084;
}
public int getOffsetX()
{
return offsetX;
}
public void setOffsetX(int offsetX)
{
this.offsetX = offsetX;
}
public boolean isNonFlatShading()
{
return nonFlatShading;
}
public void setNonFlatShading(boolean nonFlatShading)
{
this.nonFlatShading = nonFlatShading;
}
public int getAnInt2088()
{
return anInt2088;
}
public void setAnInt2088(int anInt2088)
{
this.anInt2088 = anInt2088;
}
public int getAnimationID()
{
return animationID;
}
public void setAnimationID(int animationID)
{
this.animationID = animationID;
}
public int getVarpID()
{
return varpID;
}
public void setVarpID(int varpID)
{
this.varpID = varpID;
}
public int getAmbient()
{
return ambient;
}
public void setAmbient(int ambient)
{
this.ambient = ambient;
}
public int getContrast()
{
return contrast;
}
public void setContrast(int contrast)
{
this.contrast = contrast;
}
public String[] getActions()
{
return actions;
}
public void setActions(String[] actions)
{
this.actions = actions;
}
public int getAnInt2094()
{
return anInt2094;
}
public void setAnInt2094(int anInt2094)
{
this.anInt2094 = anInt2094;
}
public int getMapSceneID()
{
return mapSceneID;
}
public void setMapSceneID(int mapSceneID)
{
this.mapSceneID = mapSceneID;
}
public short[] getRecolorToReplace()
{
return recolorToReplace;
}
public void setRecolorToReplace(short[] recolorToReplace)
{
this.recolorToReplace = recolorToReplace;
}
public boolean isaBool2097()
{
return aBool2097;
}
public void setaBool2097(boolean aBool2097)
{
this.aBool2097 = aBool2097;
}
public int getModelSizeX()
{
return modelSizeX;
}
public void setModelSizeX(int modelSizeX)
{
this.modelSizeX = modelSizeX;
}
public int getModelSizeHeight()
{
return modelSizeHeight;
}
public void setModelSizeHeight(int modelSizeHeight)
{
this.modelSizeHeight = modelSizeHeight;
}
public int getModelSizeY()
{
return modelSizeY;
}
public void setModelSizeY(int modelSizeY)
{
this.modelSizeY = modelSizeY;
}
public int getObjectID()
{
return objectID;
}
public void setObjectID(int objectID)
{
this.objectID = objectID;
}
public int getOffsetHeight()
{
return offsetHeight;
}
public void setOffsetHeight(int offsetHeight)
{
this.offsetHeight = offsetHeight;
}
public int getOffsetY()
{
return offsetY;
}
public void setOffsetY(int offsetY)
{
this.offsetY = offsetY;
}
public boolean isaBool2104()
{
return aBool2104;
}
public void setaBool2104(boolean aBool2104)
{
this.aBool2104 = aBool2104;
}
public int getAnInt2105()
{
return anInt2105;
}
public void setAnInt2105(int anInt2105)
{
this.anInt2105 = anInt2105;
}
public int getAnInt2106()
{
return anInt2106;
}
public void setAnInt2106(int anInt2106)
{
this.anInt2106 = anInt2106;
}
public int[] getConfigChangeDest()
{
return configChangeDest;
}
public void setConfigChangeDest(int[] configChangeDest)
{
this.configChangeDest = configChangeDest;
}
public boolean isaBool2108()
{
return aBool2108;
}
public void setaBool2108(boolean aBool2108)
{
this.aBool2108 = aBool2108;
}
public int getConfigId()
{
return configId;
}
public void setConfigId(int configId)
{
this.configId = configId;
}
public int getAnInt2110()
{
return anInt2110;
}
public void setAnInt2110(int anInt2110)
{
this.anInt2110 = anInt2110;
}
public boolean isaBool2111()
{
return aBool2111;
}
public void setaBool2111(boolean aBool2111)
{
this.aBool2111 = aBool2111;
}
public int getAnInt2112()
{
return anInt2112;
}
public void setAnInt2112(int anInt2112)
{
this.anInt2112 = anInt2112;
}
public int getAnInt2113()
{
return anInt2113;
}
public void setAnInt2113(int anInt2113)
{
this.anInt2113 = anInt2113;
}
public boolean isaBool2114()
{
return aBool2114;
}
public void setaBool2114(boolean aBool2114)
{
this.aBool2114 = aBool2114;
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions;
public class ScriptDefinition
{
private int id;
private int anInt2269;
private int[] instructions;
private int[] intOperands;
private String[] aStringArray2272;
private int localStringCount;
private int anInt2276;
private int localIntCount;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public int getAnInt2269()
{
return anInt2269;
}
public void setAnInt2269(int anInt2269)
{
this.anInt2269 = anInt2269;
}
public int[] getInstructions()
{
return instructions;
}
public void setInstructions(int[] instructions)
{
this.instructions = instructions;
}
public int[] getIntOperands()
{
return intOperands;
}
public void setIntOperands(int[] intOperands)
{
this.intOperands = intOperands;
}
public String[] getaStringArray2272()
{
return aStringArray2272;
}
public void setaStringArray2272(String[] aStringArray2272)
{
this.aStringArray2272 = aStringArray2272;
}
public int getLocalStringCount()
{
return localStringCount;
}
public void setLocalStringCount(int localStringCount)
{
this.localStringCount = localStringCount;
}
public int getAnInt2276()
{
return anInt2276;
}
public void setAnInt2276(int anInt2276)
{
this.anInt2276 = anInt2276;
}
public int getLocalIntCount()
{
return localIntCount;
}
public void setLocalIntCount(int localIntCount)
{
this.localIntCount = localIntCount;
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions;
import net.runelite.cache.definitions.loaders.SpriteLoader;
public class SpriteDefinition
{
private SpriteLoader loader;
private int offsetX;
private int offsetY;
private int width;
private int height;
private byte[] pixels;
private int maxWidth;
private int maxHeight;
public SpriteDefinition(SpriteLoader loader)
{
this.loader = loader;
}
public SpriteLoader getLoader()
{
return loader;
}
public void setLoader(SpriteLoader loader)
{
this.loader = loader;
}
public int getOffsetX()
{
return offsetX;
}
public void setOffsetX(int offsetX)
{
this.offsetX = offsetX;
}
public int getOffsetY()
{
return offsetY;
}
public void setOffsetY(int offsetY)
{
this.offsetY = offsetY;
}
public int getWidth()
{
return width;
}
public void setWidth(int width)
{
this.width = width;
}
public int getHeight()
{
return height;
}
public void setHeight(int height)
{
this.height = height;
}
public byte[] getPixels()
{
return pixels;
}
public void setPixels(byte[] pixels)
{
this.pixels = pixels;
}
public int getMaxWidth()
{
return maxWidth;
}
public void setMaxWidth(int maxWidth)
{
this.maxWidth = maxWidth;
}
public int getMaxHeight()
{
return maxHeight;
}
public void setMaxHeight(int maxHeight)
{
this.maxHeight = maxHeight;
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions.loaders;
import net.runelite.cache.definitions.EnumDefinition;
import net.runelite.cache.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EnumLoader
{
private static final Logger logger = LoggerFactory.getLogger(EnumLoader.class);
public EnumDefinition load(int id, byte[] b)
{
EnumDefinition def = new EnumDefinition();
InputStream is = new InputStream(b);
def.setId(id);
for (;;)
{
int opcode = is.readUnsignedByte();
if (opcode == 0)
{
break;
}
processOp(opcode, def, is);
}
return def;
}
private void processOp(int opcode, EnumDefinition def, InputStream is)
{
switch (opcode)
{
case 1:
def.setKeyType((char) is.readUnsignedByte());
break;
case 2:
def.setValType((char) is.readUnsignedByte());
break;
case 3:
def.setDefaultString(is.readString());
break;
case 4:
def.setDefaultInt(is.readInt());
break;
case 5:
{
int size = is.readUnsignedShort();
int[] keys = new int[size];
String[] stringVals = new String[size];
for (int index = 0; index < size; ++index)
{
keys[index] = is.readInt();
stringVals[index] = is.readString();
}
def.setKeys(keys);
def.setStringVals(stringVals);
break;
}
case 6:
{
int size = is.readUnsignedShort();
int[] keys = new int[size];
int[] intVals = new int[size];
for (int index = 0; index < size; ++index)
{
keys[index] = is.readInt();
intVals[index] = is.readInt();
}
def.setKeys(keys);
def.setIntVals(intVals);
break;
}
default:
logger.warn("Unrecognized opcode {}", opcode);
break;
}
}
}

View File

@@ -0,0 +1,266 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions.loaders;
import java.util.ArrayList;
import java.util.List;
import net.runelite.cache.definitions.ItemDefinition;
import net.runelite.cache.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ItemLoader
{
private static final Logger logger = LoggerFactory.getLogger(ItemLoader.class);
private final List<ItemDefinition> items = new ArrayList<>();
public List<ItemDefinition> 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 = stream.readString();
}
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] = stream.readString();
if (def.options[opcode - 30].equalsIgnoreCase("Hidden"))
{
def.options[opcode - 30] = null;
}
}
else if (opcode >= 35 && opcode < 40)
{
def.interfaceOptions[opcode - 35] = stream.readString();
}
else if (opcode == 40)
{
int var5 = stream.readUnsignedByte();
def.colorFind = new short[var5];
def.colorReplace = new short[var5];
for (int var4 = 0; var4 < var5; ++var4)
{
def.colorFind[var4] = (short) stream.readUnsignedShort();
def.colorReplace[var4] = (short) stream.readUnsignedShort();
}
}
else 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 if (opcode == 41)
{
int var5 = stream.readUnsignedByte();
def.textureFind = new short[var5];
def.textureReplace = new short[var5];
for (int var4 = 0; var4 < var5; ++var4)
{
def.textureFind[var4] = (short) stream.readUnsignedShort();
def.textureReplace[var4] = (short) stream.readUnsignedShort();
}
}
else if (opcode == 148)
{
stream.readUnsignedShort();
}
else if (opcode == 65)
{
}
else if (opcode == 139)
{
stream.readUnsignedShort();
}
else if (opcode == 140)
{
}
else
{
logger.warn("Unrecognized opcode {}", opcode);
}
}
}

View File

@@ -0,0 +1,741 @@
package net.runelite.cache.definitions.loaders;
import net.runelite.cache.definitions.ModelDefinition;
import net.runelite.cache.io.InputStream;
public class ModelLoader extends ModelDefinition
{
public void load(byte[] var1)
{
if (var1[var1.length - 1] == -1 && var1[var1.length - 2] == -1)
{
this.load1(var1);
}
else
{
this.load2(var1);
}
}
private void load1(byte[] var1)
{
InputStream var2 = new InputStream(var1);
InputStream var24 = new InputStream(var1);
InputStream var3 = new InputStream(var1);
InputStream var28 = new InputStream(var1);
InputStream var6 = new InputStream(var1);
InputStream var55 = new InputStream(var1);
InputStream var51 = new InputStream(var1);
var2.setOffset(var1.length - 23);
int verticeCount = var2.readUnsignedShort();
int triangleCount = var2.readUnsignedShort();
int textureTriangleCount = var2.readUnsignedByte();
int var13 = var2.readUnsignedByte();
int modelPriority = var2.readUnsignedByte();
int var50 = var2.readUnsignedByte();
int var17 = var2.readUnsignedByte();
int modelTexture = var2.readUnsignedByte();
int modelVertexSkins = var2.readUnsignedByte();
int var20 = var2.readUnsignedShort();
int var21 = var2.readUnsignedShort();
int var42 = var2.readUnsignedShort();
int var22 = var2.readUnsignedShort();
int var38 = var2.readUnsignedShort();
int textureAmount = 0;
int var7 = 0;
int var29 = 0;
int position;
if (textureTriangleCount > 0)
{
this.textureRenderTypes = new byte[textureTriangleCount];
var2.setOffset(0);
for (position = 0; position < textureTriangleCount; ++position)
{
byte renderType = this.textureRenderTypes[position] = var2.readByte();
if (renderType == 0)
{
++textureAmount;
}
if (renderType >= 1 && renderType <= 3)
{
++var7;
}
if (renderType == 2)
{
++var29;
}
}
}
position = textureTriangleCount + verticeCount;
int renderTypePos = position;
if (var13 == 1)
{
position += triangleCount;
}
int var49 = position;
position += triangleCount;
int priorityPos = position;
if (modelPriority == 255)
{
position += triangleCount;
}
int triangleSkinPos = position;
if (var17 == 1)
{
position += triangleCount;
}
int var35 = position;
if (modelVertexSkins == 1)
{
position += verticeCount;
}
int alphaPos = position;
if (var50 == 1)
{
position += triangleCount;
}
int var11 = position;
position += var22;
int texturePos = position;
if (modelTexture == 1)
{
position += triangleCount * 2;
}
int textureCoordPos = position;
position += var38;
int colorPos = position;
position += triangleCount * 2;
int var40 = position;
position += var20;
int var41 = position;
position += var21;
int var8 = position;
position += var42;
int var43 = position;
position += textureAmount * 6;
int var37 = position;
position += var7 * 6;
int var48 = position;
position += var7 * 6;
int var56 = position;
position += var7 * 2;
int var45 = position;
position += var7;
int var46 = position;
position += var7 * 2 + var29 * 2;
this.vertexCount = verticeCount;
this.triangleFaceCount = triangleCount;
this.anInt2569 = textureTriangleCount;
this.vertexX = new int[verticeCount];
this.vertexY = new int[verticeCount];
this.vertexZ = new int[verticeCount];
this.trianglePointsX = new int[triangleCount];
this.trianglePointsY = new int[triangleCount];
this.trianglePointsZ = new int[triangleCount];
if (modelVertexSkins == 1)
{
this.vertexSkins = new int[verticeCount];
}
if (var13 == 1)
{
this.faceRenderType = new byte[triangleCount];
}
if (modelPriority == 255)
{
this.faceRenderPriorities = new byte[triangleCount];
}
else
{
this.priority = (byte) modelPriority;
}
if (var50 == 1)
{
this.faceAlphas = new byte[triangleCount];
}
if (var17 == 1)
{
this.triangleSkinValues = new int[triangleCount];
}
if (modelTexture == 1)
{
this.faceTextures = new short[triangleCount];
}
if (modelTexture == 1 && textureTriangleCount > 0)
{
this.textureCoords = new byte[triangleCount];
}
this.faceColor = new short[triangleCount];
if (textureTriangleCount > 0)
{
this.texTriangleX = new short[textureTriangleCount];
this.texTriangleY = new short[textureTriangleCount];
this.texTriangleZ = new short[textureTriangleCount];
if (var7 > 0)
{
this.aShortArray2574 = new short[var7];
this.aShortArray2575 = new short[var7];
this.aShortArray2586 = new short[var7];
this.aShortArray2577 = new short[var7];
this.aByteArray2580 = new byte[var7];
this.aShortArray2578 = new short[var7];
}
if (var29 > 0)
{
this.texturePrimaryColor = new short[var29];
}
}
var2.setOffset(textureTriangleCount);
var24.setOffset(var40);
var3.setOffset(var41);
var28.setOffset(var8);
var6.setOffset(var35);
int vX = 0;
int vY = 0;
int vZ = 0;
int vertexZOffset;
int var10;
int vertexYOffset;
int var15;
int point;
for (point = 0; point < verticeCount; ++point)
{
int vertexFlags = var2.readUnsignedByte();
int vertexXOffset = 0;
if ((vertexFlags & 1) != 0)
{
vertexXOffset = var24.readShortSmart();
}
vertexYOffset = 0;
if ((vertexFlags & 2) != 0)
{
vertexYOffset = var3.readShortSmart();
}
vertexZOffset = 0;
if ((vertexFlags & 4) != 0)
{
vertexZOffset = var28.readShortSmart();
}
this.vertexX[point] = vX + vertexXOffset;
this.vertexY[point] = vY + vertexYOffset;
this.vertexZ[point] = vZ + vertexZOffset;
vX = this.vertexX[point];
vY = this.vertexY[point];
vZ = this.vertexZ[point];
if (modelVertexSkins == 1)
{
this.vertexSkins[point] = var6.readUnsignedByte();
}
}
var2.setOffset(colorPos);
var24.setOffset(renderTypePos);
var3.setOffset(priorityPos);
var28.setOffset(alphaPos);
var6.setOffset(triangleSkinPos);
var55.setOffset(texturePos);
var51.setOffset(textureCoordPos);
for (point = 0; point < triangleCount; ++point)
{
this.faceColor[point] = (short) var2.readUnsignedShort();
if (var13 == 1)
{
this.faceRenderType[point] = var24.readByte();
}
if (modelPriority == 255)
{
this.faceRenderPriorities[point] = var3.readByte();
}
if (var50 == 1)
{
this.faceAlphas[point] = var28.readByte();
}
if (var17 == 1)
{
this.triangleSkinValues[point] = var6.readUnsignedByte();
}
if (modelTexture == 1)
{
this.faceTextures[point] = (short) (var55.readUnsignedShort() - 1);
}
if (this.textureCoords != null && this.faceTextures[point] != -1)
{
this.textureCoords[point] = (byte) (var51.readUnsignedByte() - 1);
}
}
var2.setOffset(var11);
var24.setOffset(var49);
int trianglePointX = 0;
int trianglePointY = 0;
int trianglePointZ = 0;
vertexYOffset = 0;
int var16;
for (vertexZOffset = 0; vertexZOffset < triangleCount; ++vertexZOffset)
{
int numFaces = var24.readUnsignedByte();
if (numFaces == 1)
{
trianglePointX = var2.readShortSmart() + vertexYOffset;
trianglePointY = var2.readShortSmart() + trianglePointX;
trianglePointZ = var2.readShortSmart() + trianglePointY;
vertexYOffset = trianglePointZ;
this.trianglePointsX[vertexZOffset] = trianglePointX;
this.trianglePointsY[vertexZOffset] = trianglePointY;
this.trianglePointsZ[vertexZOffset] = trianglePointZ;
}
if (numFaces == 2)
{
trianglePointY = trianglePointZ;
trianglePointZ = var2.readShortSmart() + vertexYOffset;
vertexYOffset = trianglePointZ;
this.trianglePointsX[vertexZOffset] = trianglePointX;
this.trianglePointsY[vertexZOffset] = trianglePointY;
this.trianglePointsZ[vertexZOffset] = trianglePointZ;
}
if (numFaces == 3)
{
trianglePointX = trianglePointZ;
trianglePointZ = var2.readShortSmart() + vertexYOffset;
vertexYOffset = trianglePointZ;
this.trianglePointsX[vertexZOffset] = trianglePointX;
this.trianglePointsY[vertexZOffset] = trianglePointY;
this.trianglePointsZ[vertexZOffset] = trianglePointZ;
}
if (numFaces == 4)
{
int var57 = trianglePointX;
trianglePointX = trianglePointY;
trianglePointY = var57;
trianglePointZ = var2.readShortSmart() + vertexYOffset;
vertexYOffset = trianglePointZ;
this.trianglePointsX[vertexZOffset] = trianglePointX;
this.trianglePointsY[vertexZOffset] = var57;
this.trianglePointsZ[vertexZOffset] = trianglePointZ;
}
}
var2.setOffset(var43);
var24.setOffset(var37);
var3.setOffset(var48);
var28.setOffset(var56);
var6.setOffset(var45);
var55.setOffset(var46);
for (int texIndex = 0; texIndex < textureTriangleCount; ++texIndex)
{
int type = this.textureRenderTypes[texIndex] & 255;
if (type == 0)
{
this.texTriangleX[texIndex] = (short) var2.readUnsignedShort();
this.texTriangleY[texIndex] = (short) var2.readUnsignedShort();
this.texTriangleZ[texIndex] = (short) var2.readUnsignedShort();
}
if (type == 1)
{
this.texTriangleX[texIndex] = (short) var24.readUnsignedShort();
this.texTriangleY[texIndex] = (short) var24.readUnsignedShort();
this.texTriangleZ[texIndex] = (short) var24.readUnsignedShort();
this.aShortArray2574[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2575[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2586[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2577[texIndex] = (short) var28.readUnsignedShort();
this.aByteArray2580[texIndex] = var6.readByte();
this.aShortArray2578[texIndex] = (short) var55.readUnsignedShort();
}
if (type == 2)
{
this.texTriangleX[texIndex] = (short) var24.readUnsignedShort();
this.texTriangleY[texIndex] = (short) var24.readUnsignedShort();
this.texTriangleZ[texIndex] = (short) var24.readUnsignedShort();
this.aShortArray2574[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2575[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2586[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2577[texIndex] = (short) var28.readUnsignedShort();
this.aByteArray2580[texIndex] = var6.readByte();
this.aShortArray2578[texIndex] = (short) var55.readUnsignedShort();
this.texturePrimaryColor[texIndex] = (short) var55.readUnsignedShort();
}
if (type == 3)
{
this.texTriangleX[texIndex] = (short) var24.readUnsignedShort();
this.texTriangleY[texIndex] = (short) var24.readUnsignedShort();
this.texTriangleZ[texIndex] = (short) var24.readUnsignedShort();
this.aShortArray2574[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2575[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2586[texIndex] = (short) var3.readUnsignedShort();
this.aShortArray2577[texIndex] = (short) var28.readUnsignedShort();
this.aByteArray2580[texIndex] = var6.readByte();
this.aShortArray2578[texIndex] = (short) var55.readUnsignedShort();
}
}
var2.setOffset(position);
vertexZOffset = var2.readUnsignedByte();
if (vertexZOffset != 0)
{
//new Class41();
var2.readUnsignedShort();
var2.readUnsignedShort();
var2.readUnsignedShort();
var2.readInt();
}
}
private void load2(byte[] var1)
{
boolean var2 = false;
boolean var43 = false;
InputStream var5 = new InputStream(var1);
InputStream var39 = new InputStream(var1);
InputStream var26 = new InputStream(var1);
InputStream var9 = new InputStream(var1);
InputStream var3 = new InputStream(var1);
var5.setOffset(var1.length - 18);
int var10 = var5.readUnsignedShort();
int var11 = var5.readUnsignedShort();
int var12 = var5.readUnsignedByte();
int var13 = var5.readUnsignedByte();
int var14 = var5.readUnsignedByte();
int var30 = var5.readUnsignedByte();
int var15 = var5.readUnsignedByte();
int var28 = var5.readUnsignedByte();
int var27 = var5.readUnsignedShort();
int var20 = var5.readUnsignedShort();
int var36 = var5.readUnsignedShort();
int var23 = var5.readUnsignedShort();
byte var16 = 0;
int var46 = var16 + var10;
int var24 = var46;
var46 += var11;
int var25 = var46;
if (var14 == 255)
{
var46 += var11;
}
int var4 = var46;
if (var15 == 1)
{
var46 += var11;
}
int var42 = var46;
if (var13 == 1)
{
var46 += var11;
}
int var37 = var46;
if (var28 == 1)
{
var46 += var10;
}
int var29 = var46;
if (var30 == 1)
{
var46 += var11;
}
int var44 = var46;
var46 += var23;
int var17 = var46;
var46 += var11 * 2;
int var32 = var46;
var46 += var12 * 6;
int var34 = var46;
var46 += var27;
int var35 = var46;
var46 += var20;
int var10000 = var46 + var36;
this.vertexCount = var10;
this.triangleFaceCount = var11;
this.anInt2569 = var12;
this.vertexX = new int[var10];
this.vertexY = new int[var10];
this.vertexZ = new int[var10];
this.trianglePointsX = new int[var11];
this.trianglePointsY = new int[var11];
this.trianglePointsZ = new int[var11];
if (var12 > 0)
{
this.textureRenderTypes = new byte[var12];
this.texTriangleX = new short[var12];
this.texTriangleY = new short[var12];
this.texTriangleZ = new short[var12];
}
if (var28 == 1)
{
this.vertexSkins = new int[var10];
}
if (var13 == 1)
{
this.faceRenderType = new byte[var11];
this.textureCoords = new byte[var11];
this.faceTextures = new short[var11];
}
if (var14 == 255)
{
this.faceRenderPriorities = new byte[var11];
}
else
{
this.priority = (byte) var14;
}
if (var30 == 1)
{
this.faceAlphas = new byte[var11];
}
if (var15 == 1)
{
this.triangleSkinValues = new int[var11];
}
this.faceColor = new short[var11];
var5.setOffset(var16);
var39.setOffset(var34);
var26.setOffset(var35);
var9.setOffset(var46);
var3.setOffset(var37);
int var41 = 0;
int var33 = 0;
int var19 = 0;
int var6;
int var7;
int var8;
int var18;
int var31;
for (var18 = 0; var18 < var10; ++var18)
{
var8 = var5.readUnsignedByte();
var31 = 0;
if ((var8 & 1) != 0)
{
var31 = var39.readShortSmart();
}
var6 = 0;
if ((var8 & 2) != 0)
{
var6 = var26.readShortSmart();
}
var7 = 0;
if ((var8 & 4) != 0)
{
var7 = var9.readShortSmart();
}
this.vertexX[var18] = var41 + var31;
this.vertexY[var18] = var33 + var6;
this.vertexZ[var18] = var19 + var7;
var41 = this.vertexX[var18];
var33 = this.vertexY[var18];
var19 = this.vertexZ[var18];
if (var28 == 1)
{
this.vertexSkins[var18] = var3.readUnsignedByte();
}
}
var5.setOffset(var17);
var39.setOffset(var42);
var26.setOffset(var25);
var9.setOffset(var29);
var3.setOffset(var4);
for (var18 = 0; var18 < var11; ++var18)
{
this.faceColor[var18] = (short) var5.readUnsignedShort();
if (var13 == 1)
{
var8 = var39.readUnsignedByte();
if ((var8 & 1) == 1)
{
this.faceRenderType[var18] = 1;
var2 = true;
}
else
{
this.faceRenderType[var18] = 0;
}
if ((var8 & 2) == 2)
{
this.textureCoords[var18] = (byte) (var8 >> 2);
this.faceTextures[var18] = this.faceColor[var18];
this.faceColor[var18] = 127;
if (this.faceTextures[var18] != -1)
{
var43 = true;
}
}
else
{
this.textureCoords[var18] = -1;
this.faceTextures[var18] = -1;
}
}
if (var14 == 255)
{
this.faceRenderPriorities[var18] = var26.readByte();
}
if (var30 == 1)
{
this.faceAlphas[var18] = var9.readByte();
}
if (var15 == 1)
{
this.triangleSkinValues[var18] = var3.readUnsignedByte();
}
}
var5.setOffset(var44);
var39.setOffset(var24);
var18 = 0;
var8 = 0;
var31 = 0;
var6 = 0;
int var21;
int var22;
for (var7 = 0; var7 < var11; ++var7)
{
var22 = var39.readUnsignedByte();
if (var22 == 1)
{
var18 = var5.readShortSmart() + var6;
var8 = var5.readShortSmart() + var18;
var31 = var5.readShortSmart() + var8;
var6 = var31;
this.trianglePointsX[var7] = var18;
this.trianglePointsY[var7] = var8;
this.trianglePointsZ[var7] = var31;
}
if (var22 == 2)
{
var8 = var31;
var31 = var5.readShortSmart() + var6;
var6 = var31;
this.trianglePointsX[var7] = var18;
this.trianglePointsY[var7] = var8;
this.trianglePointsZ[var7] = var31;
}
if (var22 == 3)
{
var18 = var31;
var31 = var5.readShortSmart() + var6;
var6 = var31;
this.trianglePointsX[var7] = var18;
this.trianglePointsY[var7] = var8;
this.trianglePointsZ[var7] = var31;
}
if (var22 == 4)
{
var21 = var18;
var18 = var8;
var8 = var21;
var31 = var5.readShortSmart() + var6;
var6 = var31;
this.trianglePointsX[var7] = var18;
this.trianglePointsY[var7] = var21;
this.trianglePointsZ[var7] = var31;
}
}
var5.setOffset(var32);
for (var7 = 0; var7 < var12; ++var7)
{
this.textureRenderTypes[var7] = 0;
this.texTriangleX[var7] = (short) var5.readUnsignedShort();
this.texTriangleY[var7] = (short) var5.readUnsignedShort();
this.texTriangleZ[var7] = (short) var5.readUnsignedShort();
}
if (this.textureCoords != null)
{
boolean var45 = false;
for (var22 = 0; var22 < var11; ++var22)
{
var21 = this.textureCoords[var22] & 255;
if (var21 != 255)
{
if ((this.texTriangleX[var21] & '\uffff') == this.trianglePointsX[var22] && (this.texTriangleY[var21] & '\uffff') == this.trianglePointsY[var22] && (this.texTriangleZ[var21] & '\uffff') == this.trianglePointsZ[var22])
{
this.textureCoords[var22] = -1;
}
else
{
var45 = true;
}
}
}
if (!var45)
{
this.textureCoords = null;
}
}
if (!var43)
{
this.faceTextures = null;
}
if (!var2)
{
this.faceRenderType = null;
}
}
}

View File

@@ -0,0 +1,241 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions.loaders;
import java.util.ArrayList;
import java.util.List;
import net.runelite.cache.definitions.NpcDefinition;
import net.runelite.cache.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NpcLoader
{
private static final Logger logger = LoggerFactory.getLogger(NpcLoader.class);
private final List<NpcDefinition> npcs = new ArrayList<>();
public List<NpcDefinition> getNpcs()
{
return npcs;
}
public void load(int id, InputStream stream)
{
NpcDefinition def = new NpcDefinition(id);
while (true)
{
int opcode = stream.readUnsignedByte();
if (opcode == 0)
{
break;
}
this.decodeValues(opcode, def, stream);
}
npcs.add(def);
}
void decodeValues(int opcode, NpcDefinition def, InputStream stream)
{
int length;
int index;
if (1 == opcode)
{
length = stream.readUnsignedByte();
def.models = new int[length];
for (index = 0; index < length; ++index)
{
def.models[index] = stream.readUnsignedShort();
}
}
else if (2 == opcode)
{
def.name = stream.readString();
}
else if (12 == opcode)
{
def.tileSpacesOccupied = stream.readUnsignedByte();
}
else if (opcode == 13)
{
def.stanceAnimation = stream.readUnsignedShort();
}
else if (opcode == 14)
{
def.walkAnimation = stream.readUnsignedShort();
}
else if (15 == opcode)
{
def.anInt2165 = stream.readUnsignedShort();
}
else if (opcode == 16)
{
def.anInt2189 = stream.readUnsignedShort();
}
else if (17 == opcode)
{
def.walkAnimation = stream.readUnsignedShort();
def.rotate180Animation = stream.readUnsignedShort();
def.rotate90RightAnimation = stream.readUnsignedShort();
def.rotate90LeftAnimation = stream.readUnsignedShort();
}
else if (opcode >= 30 && opcode < 35)
{
def.options[opcode - 30] = stream.readString();
if (def.options[opcode - 30].equalsIgnoreCase("Hidden"))
{
def.options[opcode - 30] = null;
}
}
else if (opcode == 40)
{
length = stream.readUnsignedByte();
def.recolorToFind = new short[length];
def.recolorToReplace = new short[length];
for (index = 0; index < length; ++index)
{
def.recolorToFind[index] = (short) stream.readUnsignedShort();
def.recolorToReplace[index] = (short) stream.readUnsignedShort();
}
}
else if (opcode == 41)
{
length = stream.readUnsignedByte();
def.retextureToFind = new short[length];
def.retextureToReplace = new short[length];
for (index = 0; index < length; ++index)
{
def.retextureToFind[index] = (short) stream.readUnsignedShort();
def.retextureToReplace[index] = (short) stream.readUnsignedShort();
}
}
else if (60 == opcode)
{
length = stream.readUnsignedByte();
def.models_2 = new int[length];
for (index = 0; index < length; ++index)
{
def.models_2[index] = stream.readUnsignedShort();
}
}
else if (opcode == 93)
{
def.renderOnMinimap = false;
}
else if (95 == opcode)
{
def.combatLevel = stream.readUnsignedShort();
}
else if (97 == opcode)
{
def.resizeX = stream.readUnsignedShort();
}
else if (98 == opcode)
{
def.resizeY = stream.readUnsignedShort();
}
else if (opcode == 99)
{
def.hasRenderPriority = true;
}
else if (100 == opcode)
{
def.ambient = stream.readByte();
}
else if (101 == opcode)
{
def.contrast = stream.readByte();
}
else if (opcode == 102)
{
def.headIcon = stream.readUnsignedShort();
}
else if (103 == opcode)
{
def.anInt2156 = stream.readUnsignedShort();
}
else if (opcode == 106)
{
def.anInt2174 = stream.readUnsignedShort();
if ('\uffff' == def.anInt2174)
{
def.anInt2174 = -1;
}
def.anInt2187 = stream.readUnsignedShort();
if ('\uffff' == def.anInt2187)
{
def.anInt2187 = -40212193;
}
length = stream.readUnsignedByte();
def.anIntArray2185 = new int[length + 1];
for (index = 0; index <= length; ++index)
{
def.anIntArray2185[index] = stream.readUnsignedShort();
if (def.anIntArray2185[index] == '\uffff')
{
def.anIntArray2185[index] = -1;
}
}
}
else if (107 == opcode)
{
def.isClickable = false;
}
else if (opcode == 109)
{
def.aBool2170 = false;
}
else if (opcode == 111)
{
def.aBool2190 = true;
}
else if (opcode == 112)
{
def.anInt2184 = stream.readUnsignedByte();
}
else
{
logger.warn("Unrecognized opcode {}", opcode);
}
}
}

View File

@@ -0,0 +1,313 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions.loaders;
import net.runelite.cache.definitions.ObjectDefinition;
import net.runelite.cache.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ObjectLoader
{
private static final Logger logger = LoggerFactory.getLogger(ObjectLoader.class);
public ObjectDefinition load(int id, byte[] b)
{
ObjectDefinition def = new ObjectDefinition();
InputStream is = new InputStream(b);
def.setId(id);
for (;;)
{
int opcode = is.readUnsignedByte();
if (opcode == 0)
{
break;
}
processOp(opcode, def, is);
}
return def;
}
private void processOp(int opcode, ObjectDefinition def, InputStream is)
{
if (1 == opcode)
{
int length = is.readUnsignedByte();
if (length > 0)
{
int[] objectTypes = new int[length];
int[] objectModels = new int[length];
for (int index = 0; index < length; ++index)
{
objectModels[index] = is.readUnsignedShort();
objectTypes[index] = is.readUnsignedByte();
}
def.setObjectTypes(objectTypes);
def.setObjectModels(objectModels);
}
}
else if (opcode == 2)
{
def.setName(is.readString());
}
else if (opcode == 5)
{
int length = is.readUnsignedByte();
if (length > 0)
{
def.setObjectTypes(null);
int[] objectModels = new int[length];
for (int index = 0; index < length; ++index)
{
objectModels[index] = is.readUnsignedShort();
}
def.setObjectModels(objectModels);
}
}
else if (opcode == 14)
{
def.setSizeX(is.readUnsignedByte());
}
else if (15 == opcode)
{
def.setSizeY(is.readUnsignedByte());
}
else if (opcode == 17)
{
def.setAnInt2094(0);
def.setaBool2114(false);
}
else if (opcode == 18)
{
def.setaBool2114(false);
}
else if (opcode == 19)
{
def.setAnInt2088(is.readUnsignedByte());
}
else if (opcode == 21)
{
def.setAnInt2105(0);
}
else if (22 == opcode)
{
def.setNonFlatShading(false);
}
else if (opcode == 23)
{
def.setaBool2111(true);
}
else if (24 == opcode)
{
def.setAnimationID(is.readUnsignedShort());
if (def.getAnimationID() == 0xFFFF)
{
def.setAnimationID(-1);
}
}
else if (opcode == 27)
{
def.setAnInt2094(1);
}
else if (opcode == 28)
{
def.setAnInt2069(is.readUnsignedByte());
}
else if (opcode == 29)
{
def.setAmbient(is.readByte());
}
else if (opcode == 39)
{
def.setContrast(is.readByte());
}
else if (opcode >= 30 && opcode < 35)
{
String[] actions = def.getActions();
actions[opcode - 30] = is.readString();
if (actions[opcode - 30].equalsIgnoreCase("Hidden"))
{
actions[opcode - 30] = null;
}
}
else if (opcode == 40)
{
int length = is.readUnsignedByte();
short[] recolorToFind = new short[length];
short[] recolorToReplace = new short[length];
for (int index = 0; index < length; ++index)
{
recolorToFind[index] = is.readShort();
recolorToReplace[index] = is.readShort();
}
def.setRecolorToFind(recolorToFind);
def.setRecolorToReplace(recolorToReplace);
}
else if (opcode == 41)
{
int length = is.readUnsignedByte();
short[] retextureToFind = new short[length];
short[] textureToReplace = new short[length];
for (int index = 0; index < length; ++index)
{
retextureToFind[index] = is.readShort();
textureToReplace[index] = is.readShort();
}
def.setRetextureToFind(retextureToFind);
def.setTextureToReplace(textureToReplace);
}
else if (opcode == 60)
{
def.setMapIconID(is.readUnsignedShort());
}
else if (62 == opcode)
{
def.setaBool2108(true);
}
else if (opcode == 64)
{
def.setaBool2097(false);
}
else if (opcode == 65)
{
def.setModelSizeX(is.readUnsignedShort());
}
else if (opcode == 66)
{
def.setModelSizeHeight(is.readUnsignedShort());
}
else if (67 == opcode)
{
def.setModelSizeY(is.readUnsignedShort());
}
else if (opcode == 68)
{
def.setMapSceneID(is.readUnsignedShort());
}
else if (opcode == 69)
{
is.readByte();
}
else if (70 == opcode)
{
def.setOffsetX(is.readUnsignedShort());
}
else if (opcode == 71)
{
def.setOffsetHeight(is.readUnsignedShort());
}
else if (opcode == 72)
{
def.setOffsetY(is.readUnsignedShort());
}
else if (73 == opcode)
{
def.setaBool2104(true);
}
else if (74 == opcode)
{
def.setIsSolid(true);
}
else if (opcode == 75)
{
def.setAnInt2106(is.readUnsignedByte());
}
else if (opcode == 77)
{
int varpID = is.readUnsignedShort();
if (varpID == 0xFFFF)
{
varpID = -1;
}
def.setVarpID(varpID);
int configId = is.readUnsignedShort();
if (configId == 0xFFFF)
{
configId = -1;
}
def.setConfigId(configId);
int length = is.readUnsignedByte();
int[] configChangeDest = new int[length + 1];
for (int index = 0; index <= length; ++index)
{
configChangeDest[index] = is.readUnsignedShort();
if (0xFFFF == configChangeDest[index])
{
configChangeDest[index] = -1;
}
}
def.setConfigChangeDest(configChangeDest);
}
else if (opcode == 78)
{
def.setAnInt2110(is.readUnsignedShort());
def.setAnInt2083(is.readUnsignedByte());
}
else if (opcode == 79)
{
def.setAnInt2112(is.readUnsignedShort());
def.setAnInt2113(is.readUnsignedShort());
def.setAnInt2083(is.readUnsignedByte());
int length = is.readUnsignedByte();
int[] anIntArray2084 = new int[length];
for (int index = 0; index < length; ++index)
{
anIntArray2084[index] = is.readUnsignedShort();
}
def.setAnIntArray2084(anIntArray2084);
}
else if (opcode == 81)
{
def.setAnInt2105(is.readUnsignedByte());
}
else
{
logger.warn("Unrecognized opcode {}", opcode);
}
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions.loaders;
import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.io.InputStream;
public class ScriptLoader
{
public ScriptDefinition load(int id, byte[] b)
{
ScriptDefinition def = new ScriptDefinition();
InputStream in = new InputStream(b);
in.setOffset(in.getLength() - 12);
int paramCount = in.readInt();
int localIntCount = in.readUnsignedShort();
int localStringCount = in.readUnsignedShort();
int anInt2269 = in.readUnsignedShort();
int anInt2276 = in.readUnsignedShort();
def.setLocalIntCount(localIntCount);
def.setLocalStringCount(localStringCount);
def.setAnInt2269(anInt2269);
def.setAnInt2276(anInt2276);
in.setOffset(0);
in.readStringOrNull();
int[] instructions = new int[paramCount];
int[] intOperands = new int[paramCount];
String[] aStringArray2272 = new String[paramCount];
def.setInstructions(instructions);
def.setIntOperands(intOperands);
def.setaStringArray2272(aStringArray2272);
int var3;
for (int var6 = 0; in.getOffset() < in.getLength() - 12; instructions[var6++] = var3)
{
var3 = in.readUnsignedShort();
if (var3 == 3)
{
aStringArray2272[var6] = in.readString();
}
else if (var3 < 100 && 21 != var3 && 38 != var3 && 39 != var3)
{
intOperands[var6] = in.readInt();
}
else
{
intOperands[var6] = in.readUnsignedByte();
}
}
return def;
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.definitions.loaders;
import net.runelite.cache.definitions.SpriteDefinition;
import net.runelite.cache.io.InputStream;
public class SpriteLoader
{
private SpriteDefinition[] sprites;
private int[] loadedPalette;
private int loadedSpriteMaxWidth;
private int loadedSpriteMaxHeight;
public void load(InputStream stream)
{
stream.setOffset(stream.getLength() - 2);
int paletteChildCount = stream.readUnsignedShort();
sprites = new SpriteDefinition[paletteChildCount];
for (int i = 0; i < paletteChildCount; ++i)
{
sprites[i] = new SpriteDefinition(this);
}
stream.setOffset(stream.getLength() - 7 - paletteChildCount * 8);
loadedSpriteMaxWidth = stream.readUnsignedShort();
loadedSpriteMaxHeight = stream.readUnsignedShort();
int var3 = (stream.readUnsignedByte() & 255) + 1;
int spriteIndex;
for (spriteIndex = 0; spriteIndex < paletteChildCount; ++spriteIndex)
{
sprites[spriteIndex].setOffsetX(stream.readUnsignedShort());
}
for (spriteIndex = 0; spriteIndex < paletteChildCount; ++spriteIndex)
{
sprites[spriteIndex].setOffsetY(stream.readUnsignedShort());
}
for (spriteIndex = 0; spriteIndex < paletteChildCount; ++spriteIndex)
{
sprites[spriteIndex].setWidth(stream.readUnsignedShort());
}
for (spriteIndex = 0; spriteIndex < paletteChildCount; ++spriteIndex)
{
sprites[spriteIndex].setHeight(stream.readUnsignedShort());
}
stream.setOffset(stream.getLength() - 7 - paletteChildCount * 8 - (var3 - 1) * 3);
loadedPalette = new int[var3];
for (spriteIndex = 1; spriteIndex < var3; ++spriteIndex)
{
loadedPalette[spriteIndex] = stream.read24BitInt();
if (0 == loadedPalette[spriteIndex])
{
loadedPalette[spriteIndex] = 1;
}
}
stream.setOffset(0);
for (spriteIndex = 0; spriteIndex < paletteChildCount; ++spriteIndex)
{
SpriteDefinition def = sprites[spriteIndex];
int width = def.getWidth();
int height = def.getHeight();
int dimmension = width * height;
byte[] loadPixels = new byte[dimmension];
int var4 = stream.readUnsignedByte();
int var5;
if (var4 == 0)
{
for (var5 = 0; var5 < dimmension; ++var5)
{
loadPixels[var5] = (byte) stream.readByte();
}
}
else if (1 == var4)
{
for (var5 = 0; var5 < width; ++var5)
{
for (int var8 = 0; var8 < height; ++var8)
{
loadPixels[width * var8 + var5] = (byte) stream.readByte();
}
}
}
def.setPixels(loadPixels);
}
}
public SpriteDefinition[] getSprites()
{
return sprites;
}
public int[] getLoadedPalette()
{
return loadedPalette;
}
}

View File

@@ -0,0 +1,177 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import net.runelite.cache.io.InputStream;
public class Archive
{
private Index index; // member of this index
private int archiveId;
private int nameHash;
private byte[] whirlpool;
private int crc;
private int revision;
private List<File> files = new ArrayList<>();
public Archive(Index index, int id)
{
this.index = index;
this.archiveId = id;
}
@Override
public int hashCode()
{
int hash = 7;
hash = 47 * hash + this.archiveId;
hash = 47 * hash + this.nameHash;
hash = 47 * hash + this.revision;
hash = 47 * hash + Objects.hashCode(this.files);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Archive other = (Archive) obj;
if (this.archiveId != other.archiveId)
{
return false;
}
if (this.nameHash != other.nameHash)
{
return false;
}
// crc is of the file data, we always rewrite in one loop, so iti is different
if (this.revision != other.revision)
{
return false;
}
if (!Objects.equals(this.files, other.files))
{
return false;
}
return true;
}
public File addFile(int id)
{
File file = new File(this, id);
this.files.add(file);
return file;
}
public void load(InputStream stream, int numberOfFiles, int protocol)
{
int archive = 0;
for (int i = 0; i < numberOfFiles; ++i)
{
int fileId = archive += protocol >= 7 ? stream.readBigSmart() : stream.readUnsignedShort();
File file = new File(this, fileId);
this.files.add(file);
}
}
public void loadNames(InputStream stream, int numberOfFiles)
{
for (int i = 0; i < numberOfFiles; ++i)
{
File file = this.files.get(i);
int name = stream.readInt();
file.setNameHash(name);
}
}
public int getArchiveId()
{
return archiveId;
}
public int getNameHash()
{
return nameHash;
}
public void setNameHash(int nameHash)
{
this.nameHash = nameHash;
}
public byte[] getWhirlpool()
{
return whirlpool;
}
public void setWhirlpool(byte[] whirlpool)
{
this.whirlpool = whirlpool;
}
public int getCrc()
{
return crc;
}
public void setCrc(int crc)
{
this.crc = crc;
}
public int getRevision()
{
return revision;
}
public void setRevision(int revision)
{
this.revision = revision;
}
public List<File> getFiles()
{
return files;
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
public class CompressionType
{
public static final int NONE = 0;
public static final int BZ2 = 1;
public static final int GZ = 2;
}

View File

@@ -0,0 +1,373 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import net.runelite.cache.fs.util.BZip2;
import net.runelite.cache.io.InputStream;
import net.runelite.cache.io.OutputStream;
import net.runelite.cache.fs.util.CRC32HGenerator;
import net.runelite.cache.fs.util.GZip;
import net.runelite.cache.fs.util.Whirlpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DataFile implements Closeable
{
private static final Logger logger = LoggerFactory.getLogger(DataFile.class);
private static final int SECTOR_SIZE = 520;
private final Store store;
private final File file;
private final RandomAccessFile dat;
private final byte[] readCachedBuffer = new byte[SECTOR_SIZE];
public DataFile(Store store, File file) throws FileNotFoundException
{
this.file = file;
this.store = store;
dat = new RandomAccessFile(file, "rw");
}
@Override
public void close() throws IOException
{
dat.close();
}
/**
*
* @param indexId
* @param archiveId
* @param sector sector to start reading at
* @param size expected size of file
* @return
* @throws IOException
*/
public synchronized DataFileReadResult read(int indexId, int archiveId, int sector, int size) throws IOException
{
if (sector <= 0L || dat.length() / 520L < (long) sector)
{
logger.warn("bad read, dat length {}, requested sector {}", dat.length(), sector);
return null;
}
ByteBuffer buffer = ByteBuffer.allocate(size);
for (int part = 0, readBytesCount = 0, nextSector;
size > readBytesCount;
sector = nextSector)
{
if (sector == 0)
{
logger.warn("sector == 0");
return null;
}
dat.seek(SECTOR_SIZE * sector);
int dataBlockSize = size - readBytesCount;
byte headerSize;
int currentIndex;
int currentPart;
int currentArchive;
if (0xFFFF < archiveId)
{
headerSize = 10;
if (dataBlockSize > SECTOR_SIZE - headerSize)
{
dataBlockSize = SECTOR_SIZE - headerSize;
}
int i = dat.read(this.readCachedBuffer, 0, headerSize + dataBlockSize);
if (i != headerSize + dataBlockSize)
{
logger.warn("short read");
return null;
}
currentArchive = ((this.readCachedBuffer[1] & 255) << 16) + ((this.readCachedBuffer[0] & 255) << 24) + (('\uff00' & this.readCachedBuffer[2] << 8) - -(this.readCachedBuffer[3] & 255));
currentPart = ((this.readCachedBuffer[4] & 255) << 8) + (255 & this.readCachedBuffer[5]);
nextSector = (this.readCachedBuffer[8] & 255) + ('\uff00' & this.readCachedBuffer[7] << 8) + ((255 & this.readCachedBuffer[6]) << 16);
currentIndex = this.readCachedBuffer[9] & 255;
}
else
{
headerSize = 8;
if (dataBlockSize > SECTOR_SIZE - headerSize)
{
dataBlockSize = SECTOR_SIZE - headerSize;
}
int i = dat.read(this.readCachedBuffer, 0, headerSize + dataBlockSize);
if (i != headerSize + dataBlockSize)
{
logger.warn("short read");
return null;
}
currentArchive = (255 & this.readCachedBuffer[1]) + ('\uff00' & this.readCachedBuffer[0] << 8);
currentPart = ((this.readCachedBuffer[2] & 255) << 8) + (255 & this.readCachedBuffer[3]);
nextSector = (this.readCachedBuffer[6] & 255) + ('\uff00' & this.readCachedBuffer[5] << 8) + ((255 & this.readCachedBuffer[4]) << 16);
currentIndex = this.readCachedBuffer[7] & 255;
}
if (archiveId != currentArchive || currentPart != part || indexId != currentIndex)
{
logger.warn("data mismatch {} != {}, {} != {}, {} != {}",
archiveId, currentArchive,
part, currentPart,
indexId, currentIndex);
return null;
}
if (nextSector < 0 || dat.length() / SECTOR_SIZE < (long) nextSector)
{
logger.warn("Invalid next sector");
return null;
}
buffer.put(readCachedBuffer, headerSize, dataBlockSize);
readBytesCount += dataBlockSize;
++part;
}
buffer.flip();
//XTEA decrypt here?
return this.decompress(buffer.array());
}
public synchronized DataFileWriteResult write(int indexId, int archiveId, ByteBuffer data, int compression, int revision) throws IOException
{
int sector;
int startSector;
byte[] compressedData = this.compress(data.array(), compression, revision);
data = ByteBuffer.wrap(compressedData);
//XTEA encrypt here?
sector = (int) ((dat.length() + (long) (SECTOR_SIZE - 1)) / (long) SECTOR_SIZE);
if (sector == 0)
{
sector = 1;
}
startSector = sector;
for (int part = 0; data.hasRemaining(); ++part)
{
int nextSector = 0;
int dataToWrite;
if (nextSector == 0)
{
nextSector = (int) ((dat.length() + (long) (SECTOR_SIZE - 1)) / (long) SECTOR_SIZE);
if (nextSector == 0)
{
++nextSector;
}
if (nextSector == sector)
{
++nextSector;
}
}
if (0xFFFF < archiveId)
{
if (data.remaining() <= 510)
{
nextSector = 0;
}
this.readCachedBuffer[0] = (byte) (archiveId >> 24);
this.readCachedBuffer[1] = (byte) (archiveId >> 16);
this.readCachedBuffer[2] = (byte) (archiveId >> 8);
this.readCachedBuffer[3] = (byte) archiveId;
this.readCachedBuffer[4] = (byte) (part >> 8);
this.readCachedBuffer[5] = (byte) part;
this.readCachedBuffer[6] = (byte) (nextSector >> 16);
this.readCachedBuffer[7] = (byte) (nextSector >> 8);
this.readCachedBuffer[8] = (byte) nextSector;
this.readCachedBuffer[9] = (byte) indexId;
dat.seek(SECTOR_SIZE * sector);
dat.write(this.readCachedBuffer, 0, 10);
dataToWrite = data.remaining();
if (dataToWrite > 510)
{
dataToWrite = 510;
}
}
else
{
if (data.remaining() <= 512)
{
nextSector = 0;
}
this.readCachedBuffer[0] = (byte) (archiveId >> 8);
this.readCachedBuffer[1] = (byte) archiveId;
this.readCachedBuffer[2] = (byte) (part >> 8);
this.readCachedBuffer[3] = (byte) part;
this.readCachedBuffer[4] = (byte) (nextSector >> 16);
this.readCachedBuffer[5] = (byte) (nextSector >> 8);
this.readCachedBuffer[6] = (byte) nextSector;
this.readCachedBuffer[7] = (byte) indexId;
dat.seek(SECTOR_SIZE * sector);
dat.write(this.readCachedBuffer, 0, 8);
dataToWrite = data.remaining();
if (dataToWrite > 512)
{
dataToWrite = 512;
}
}
data.get(readCachedBuffer, 0, dataToWrite);
dat.write(readCachedBuffer, 0, dataToWrite);
sector = nextSector;
}
DataFileWriteResult res = new DataFileWriteResult();
res.sector = startSector;
res.compressedLength = compressedData.length;
res.crc = CRC32HGenerator.getHash(compressedData, compressedData.length - 2);
res.whirlpool = Whirlpool.getHash(compressedData, compressedData.length - 2);
return res;
}
private DataFileReadResult decompress(byte[] b)
{
InputStream stream = new InputStream(b);
int compression = stream.readUnsignedByte();
int compressedLength = stream.readInt();
if (compressedLength < 0 || compressedLength > 1000000)
throw new RuntimeException("Invalid data");
byte[] data;
int revision;
switch (compression)
{
case CompressionType.NONE:
data = new byte[compressedLength];
revision = this.checkRevision(stream, compressedLength);
stream.readBytes(data, 0, compressedLength);
break;
case CompressionType.BZ2:
{
int length = stream.readInt();
revision = this.checkRevision(stream, compressedLength);
data = BZip2.decompress(stream.getRemaining());
assert data.length == length;
break;
}
case CompressionType.GZ:
{
int length = stream.readInt();
revision = this.checkRevision(stream, compressedLength);
data = GZip.decompress(stream.getRemaining());
assert data.length == length;
break;
}
default:
throw new RuntimeException("Unknown decompression type");
}
DataFileReadResult res = new DataFileReadResult();
res.data = data;
res.revision = revision;
res.crc = CRC32HGenerator.getHash(b, b.length - 2);
res.whirlpool = Whirlpool.getHash(b, b.length - 2);
return res;
}
private byte[] compress(byte[] data, int compression, int revision) throws IOException
{
OutputStream stream = new OutputStream();
stream.writeByte(compression);
byte[] compressedData;
switch (compression)
{
case CompressionType.NONE:
compressedData = data;
stream.writeInt(data.length);
break;
case CompressionType.BZ2:
compressedData = BZip2.compress(data);
stream.writeInt(compressedData.length);
stream.writeInt(data.length);
break;
case CompressionType.GZ:
compressedData = GZip.compress(data);
stream.writeInt(compressedData.length);
stream.writeInt(data.length);
break;
default:
throw new RuntimeException("Unknown compression type");
}
stream.writeBytes(compressedData);
stream.writeShort(revision);
return stream.flip();
}
private 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();
stream.setOffset(offset);
}
else
{
revision = -1;
}
return revision;
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
public class DataFileReadResult
{
public byte[] data;
public int revision;
public int crc; // crc of compressed data
public byte[] whirlpool;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
public class DataFileWriteResult
{
public int sector, compressedLength;
public int crc; // crc of compressed data
public byte[] whirlpool;
}

View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.util.Arrays;
public class File
{
private Archive archive;
private int fileId;
private int nameHash;
private byte[] contents;
public File(Archive archive, int fileId)
{
this.archive = archive;
this.fileId = fileId;
}
@Override
public int hashCode()
{
int hash = 7;
hash = 97 * hash + this.fileId;
hash = 97 * hash + this.nameHash;
hash = 97 * hash + Arrays.hashCode(this.contents);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final File other = (File) obj;
if (this.fileId != other.fileId)
{
return false;
}
if (this.nameHash != other.nameHash)
{
return false;
}
if (!Arrays.equals(this.contents, other.contents))
{
return false;
}
return true;
}
public Archive getArchive()
{
return archive;
}
public int getFileId()
{
return fileId;
}
public int getNameHash()
{
return nameHash;
}
public void setNameHash(int nameHash)
{
this.nameHash = nameHash;
}
public byte[] getContents()
{
return contents;
}
public void setContents(byte[] contents)
{
this.contents = contents;
}
public int getSize()
{
return contents.length;
}
}

View File

@@ -0,0 +1,533 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import net.runelite.cache.fs.util.Djb2;
import net.runelite.cache.io.InputStream;
import net.runelite.cache.io.OutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Index implements Closeable
{
private static final Logger logger = LoggerFactory.getLogger(Index.class);
private final Store store;
private final IndexFile index;
private final int id;
private int revision;
private final List<Archive> archives = new ArrayList<>();
public Index(Store store, IndexFile index, int id)
{
this.store = store;
this.index = index;
this.id = id;
}
@Override
public void close() throws IOException
{
index.close();
}
@Override
public int hashCode()
{
int hash = 3;
hash = 97 * hash + this.id;
hash = 97 * hash + this.revision;
hash = 97 * hash + Objects.hashCode(this.archives);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Index other = (Index) obj;
if (this.id != other.id)
{
return false;
}
if (this.revision != other.revision)
{
return false;
}
if (!Objects.equals(this.archives, other.archives))
{
return false;
}
return true;
}
public int getId()
{
return id;
}
public IndexFile getIndex()
{
return index;
}
public List<Archive> getArchives()
{
return archives;
}
public Archive addArchive(int id)
{
Archive archive = new Archive(this, id);
this.archives.add(archive);
return archive;
}
public Archive getArchive(int id)
{
for (Archive a : archives)
if (a.getArchiveId() == id)
return a;
return null;
}
public Archive findArchiveByName(String name)
{
int hash = Djb2.hash(name);
for (Archive a : archives)
if (a.getNameHash() == hash)
return a;
return null;
}
public void load() throws IOException
{
DataFile dataFile = store.getData();
IndexFile index255 = store.getIndex255();
IndexEntry entry = index255.read(id);
DataFileReadResult res = dataFile.read(index255.getIndexFileId(), entry.getId(), entry.getSector(), entry.getLength());
byte[] data = res.data;
archives.clear();
readIndexData(data);
this.loadFiles();
}
public void save() throws IOException
{
saveFiles();
byte[] data = this.writeIndexData();
DataFile dataFile = store.getData();
IndexFile index255 = store.getIndex255();
DataFileWriteResult res = dataFile.write(index255.getIndexFileId(), this.id, ByteBuffer.wrap(data), 0, this.revision);
index255.write(new IndexEntry(index255, id, res.sector, res.compressedLength));
}
private void readIndexData(byte[] data)
{
InputStream stream = new InputStream(data);
int protocol = stream.readUnsignedByte();
if (protocol >= 5 && protocol <= 7)
{
if (protocol >= 6)
{
this.revision = stream.readInt();
}
int hash = stream.readUnsignedByte();
boolean named = (1 & hash) != 0;
boolean usesWhirpool = (2 & hash) != 0;
int validArchivesCount = protocol >= 7 ? stream.readBigSmart() : stream.readUnsignedShort();
int lastArchiveId = 0;
int index;
int archive;
for (index = 0; index < validArchivesCount; ++index)
{
archive = lastArchiveId += protocol >= 7 ? stream.readBigSmart() : stream.readUnsignedShort();
Archive a = new Archive(this, archive);
this.archives.add(a);
}
if (named)
{
for (index = 0; index < validArchivesCount; ++index)
{
int nameHash = stream.readInt();
Archive a = this.archives.get(index);
a.setNameHash(nameHash);
}
}
if (usesWhirpool)
{
for (index = 0; index < validArchivesCount; ++index)
{
byte[] var13 = new byte[64];
stream.readBytes(var13);
Archive a = this.archives.get(index);
a.setWhirlpool(var13);
}
}
for (index = 0; index < validArchivesCount; ++index)
{
int crc = stream.readInt();
Archive a = this.archives.get(index);
a.setCrc(crc);
}
for (index = 0; index < validArchivesCount; ++index)
{
int revision = stream.readInt();
Archive a = this.archives.get(index);
a.setRevision(revision);
}
int[] numberOfFiles = new int[validArchivesCount];
for (index = 0; index < validArchivesCount; ++index)
{
int num = protocol >= 7 ? stream.readBigSmart() : stream.readUnsignedShort();
numberOfFiles[index] = num;
}
for (index = 0; index < validArchivesCount; ++index)
{
archive = 0;
Archive a = this.archives.get(index);
a.load(stream, numberOfFiles[index], protocol);
}
if (named)
{
for (index = 0; index < validArchivesCount; ++index)
{
Archive a = this.archives.get(index);
a.loadNames(stream, numberOfFiles[index]);
}
}
}
}
private void loadFiles() throws IOException
{
// get data from index file
for (Archive a : archives)
{
IndexEntry entry = this.index.read(a.getArchiveId());
if (entry == null)
{
logger.debug("can't read archive " + a.getArchiveId() + " from index " + this.id);
continue;
}
assert this.index.getIndexFileId() == this.id;
assert entry.getId() == a.getArchiveId();
DataFileReadResult res = store.getData().read(this.id, entry.getId(), entry.getSector(), entry.getLength());
byte[] data = res.data;
if (a.getCrc() != res.crc)
{
logger.warn("crc mismatch for archive {}", a);
}
if (a.getWhirlpool() != null && !Arrays.equals(a.getWhirlpool(), res.whirlpool))
{
logger.warn("whirlpool mismatch for archive {}", a);
}
if (a.getFiles().size() == 1)
{
a.getFiles().get(0).setContents(data);
continue;
}
final int filesCount = a.getFiles().size();
int readPosition = data.length;
--readPosition;
int amtOfLoops = data[readPosition] & 255;
readPosition -= amtOfLoops * filesCount * 4;
InputStream stream = new InputStream(data);
stream.setOffset(readPosition);
int[] filesSize = new int[filesCount];
int sourceOffset;
int count;
for (int filesData = 0; filesData < amtOfLoops; ++filesData)
{
sourceOffset = 0;
for (count = 0; count < filesCount; ++count)
{
filesSize[count] += sourceOffset += stream.readInt();
}
}
byte[][] var18 = new byte[filesCount][];
for (sourceOffset = 0; sourceOffset < filesCount; ++sourceOffset)
{
var18[sourceOffset] = new byte[filesSize[sourceOffset]];
filesSize[sourceOffset] = 0;
}
stream.setOffset(readPosition);
sourceOffset = 0;
int fileId;
int i;
for (count = 0; count < amtOfLoops; ++count)
{
fileId = 0;
for (i = 0; i < filesCount; ++i)
{
fileId += stream.readInt();
System.arraycopy(data, sourceOffset, var18[i], filesSize[i], fileId);
sourceOffset += fileId;
filesSize[i] += fileId;
}
}
for (i = 0; i < filesCount; ++i)
{
File f = a.getFiles().get(i);
f.setContents(var18[i]);
}
}
}
public void saveFiles() throws IOException
{
for (Archive a : archives)
{
OutputStream stream = new OutputStream();
int sourceOffset = 0;
final int filesCount = a.getFiles().size();
if (filesCount == 1)
{
File file = a.getFiles().get(0);
stream.writeBytes(file.getContents());
}
else
{
for (int i = 0; i < filesCount; ++i)
{
File file = a.getFiles().get(i);
stream.writeBytes(file.getContents());
}
for (int count = 0; count < filesCount; ++count)
{
File file = a.getFiles().get(count);
int sz = file.getSize() - sourceOffset;
sourceOffset = file.getSize();
stream.writeInt(sz);
}
stream.writeByte(1); // number of loops
}
byte[] fileData = stream.flip();
assert this.index.getIndexFileId() == this.id;
DataFile data = store.getData();
// XXX old data is just left there in the file?
DataFileWriteResult res = data.write(this.id, a.getArchiveId(), ByteBuffer.wrap(fileData), 0, this.revision);
this.index.write(new IndexEntry(this.index, a.getArchiveId(), res.sector, res.compressedLength));
a.setCrc(res.crc);
a.setWhirlpool(res.whirlpool);
}
}
public byte[] writeIndexData()
{
OutputStream stream = new OutputStream();
int protocol = 7;//this.getProtocol();
stream.writeByte(protocol);
if (protocol >= 6)
{
stream.writeInt(this.revision);
}
boolean named = true, usesWhirpool = false;
stream.writeByte((named ? 1 : 0) | (usesWhirpool ? 2 : 0));
if (protocol >= 7)
{
stream.writeBigSmart(this.archives.size());
}
else
{
stream.writeShort(this.archives.size());
}
int data;
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
int archive = a.getArchiveId();
if (data != 0)
{
Archive prev = this.archives.get(data - 1);
archive -= prev.getArchiveId();
}
if (protocol >= 7)
{
stream.writeBigSmart(archive);
}
else
{
stream.writeShort(archive);
}
}
if (named)
{
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
stream.writeInt(a.getNameHash());
}
}
if (usesWhirpool)
{
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
stream.writeBytes(a.getWhirlpool());
}
}
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
stream.writeInt(a.getCrc());
}
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
stream.writeInt(a.getRevision());
}
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
int len = a.getFiles().size();
if (protocol >= 7)
{
stream.writeBigSmart(len);
}
else
{
stream.writeShort(len);
}
}
int index2;
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
for (index2 = 0; index2 < a.getFiles().size(); ++index2)
{
File file = a.getFiles().get(index2);
int offset = file.getFileId();
if (index2 != 0)
{
File prev = a.getFiles().get(index2 - 1);
offset -= prev.getFileId();
}
if (protocol >= 7)
{
stream.writeBigSmart(offset);
}
else
{
stream.writeShort(offset);
}
}
}
if (named)
{
for (data = 0; data < this.archives.size(); ++data)
{
Archive a = this.archives.get(data);
for (index2 = 0; index2 < a.getFiles().size(); ++index2)
{
File file = a.getFiles().get(index2);
stream.writeInt(file.getNameHash());
}
}
}
return stream.flip();
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.util.Objects;
public class IndexEntry
{
private final IndexFile indexFile;
private final int id, sector, length;
public IndexEntry(IndexFile indexFile, int id, int sector, int length)
{
this.indexFile = indexFile;
this.id = id;
this.sector = sector;
this.length = length;
}
public IndexFile getIndexFile()
{
return indexFile;
}
public int getId()
{
return id;
}
public int getSector()
{
return sector;
}
public int getLength()
{
return length;
}
@Override
public int hashCode()
{
int hash = 7;
hash = 19 * hash + Objects.hashCode(this.indexFile);
hash = 19 * hash + this.id;
hash = 19 * hash + this.sector;
hash = 19 * hash + this.length;
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final IndexEntry other = (IndexEntry) obj;
if (!Objects.equals(this.indexFile, other.indexFile))
{
return false;
}
if (this.id != other.id)
{
return false;
}
if (this.sector != other.sector)
{
return false;
}
if (this.length != other.length)
{
return false;
}
return true;
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IndexFile implements Closeable
{
private static final Logger logger = LoggerFactory.getLogger(IndexFile.class);
private static final int INDEX_ENTRY_LEN = 6;
private final Store store;
private final int indexFileId;
private final File file;
private final RandomAccessFile idx;
private final byte[] buffer = new byte[INDEX_ENTRY_LEN];
public IndexFile(Store store, int indexFileId, File file) throws FileNotFoundException
{
this.store = store;
this.indexFileId = indexFileId;
this.file = file;
this.idx = new RandomAccessFile(file, "rw");
}
@Override
public void close() throws IOException
{
idx.close();
}
@Override
public int hashCode()
{
int hash = 3;
hash = 41 * hash + Objects.hashCode(this.file);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final IndexFile other = (IndexFile) obj;
if (!Objects.equals(this.file, other.file))
{
return false;
}
return true;
}
public Store getStore()
{
return store;
}
public int getIndexFileId()
{
return indexFileId;
}
public synchronized void write(IndexEntry entry) throws IOException
{
idx.seek(entry.getId() * INDEX_ENTRY_LEN);
buffer[0] = (byte) (entry.getLength() >> 16);
buffer[1] = (byte) (entry.getLength() >> 8);
buffer[2] = (byte) entry.getLength();
buffer[3] = (byte) (entry.getSector() >> 16);
buffer[4] = (byte) (entry.getSector() >> 8);
buffer[5] = (byte) entry.getSector();
idx.write(buffer);
}
public synchronized IndexEntry read(int id) throws IOException
{
idx.seek(id * INDEX_ENTRY_LEN);
int i = idx.read(buffer);
if (i != INDEX_ENTRY_LEN)
{
logger.warn("short read for id {} on index {}: {}", id, indexFileId, i);
return null;
}
int length = ((buffer[0] & 0xFF) << 16) | ((buffer[1] & 0xFF) << 8) | (buffer[2] & 0xFF);
int sector = ((buffer[3] & 0xFF) << 16) | ((buffer[4] & 0xFF) << 8) | (buffer[5] & 0xFF);
if (length <= 0 || sector <= 0)
{
logger.debug("invalid length or sector {}/{}", length, sector);
return null;
}
return new IndexEntry(this, id, sector, length);
}
public synchronized int getIndexCount() throws IOException
{
return (int)(idx.length() / INDEX_ENTRY_LEN);
}
}

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import net.runelite.cache.IndexType;
public class Store implements Closeable
{
private static final String MAIN_FILE_CACHE_DAT = "main_file_cache.dat2";
private static final String MAIN_FILE_CACHE_IDX = "main_file_cache.idx";
private final File folder;
private final DataFile data;
private final IndexFile index255;
private final List<Index> indexes = new ArrayList<>();
public Store(File folder) throws IOException
{
this.folder = folder;
data = new DataFile(this, new File(folder, MAIN_FILE_CACHE_DAT));
index255 = new IndexFile(this, 255, new File(folder, MAIN_FILE_CACHE_IDX + "255"));
for (int i = 0; i < index255.getIndexCount(); ++i)
{
this.addIndex(i);
}
}
@Override
public void close() throws IOException
{
data.close();
index255.close();
for (Index i : indexes)
i.close();
}
@Override
public int hashCode()
{
int hash = 5;
hash = 79 * hash + Objects.hashCode(this.indexes);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Store other = (Store) obj;
if (!Objects.equals(this.indexes, other.indexes))
{
return false;
}
return true;
}
public final Index addIndex(int id) throws FileNotFoundException
{
for (Index i : indexes)
if (i.getIndex().getIndexFileId() == id)
throw new IllegalArgumentException("index " + id + " already exists");
IndexFile indexFile = new IndexFile(this, id, new File(folder, MAIN_FILE_CACHE_IDX + id));
Index index = new Index(this, indexFile, id);
this.indexes.add(index);
return index;
}
public void load() throws IOException
{
for (Index i : indexes)
{
int id = i.getIndex().getIndexFileId();
if (id == 5) // XXX maps, XTEA encrypted, can't decompress
continue;
if (id == 6 || id == 14)
continue; // XXX I get more Indexes than there is length of the index file for these
i.load();
}
}
public void save() throws IOException
{
for (Index i : indexes)
i.save();
}
public DataFile getData()
{
return data;
}
public IndexFile getIndex255()
{
return index255;
}
public List<Index> getIndexes()
{
return indexes;
}
public Index getIndex(IndexType type)
{
return indexes.get(type.getNumber());
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BZip2
{
private static final Logger logger = LoggerFactory.getLogger(BZip2.class);
private static final byte[] BZIP_HEADER = new byte[] {
'B', 'Z', // magic
'h', // 'h' for Bzip2 ('H'uffman coding)
'1' // block size
};
public static byte[] compress(byte[] bytes)
{
try
{
InputStream is = new ByteArrayInputStream(bytes);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try (OutputStream os = new BZip2CompressorOutputStream(bout))
{
IOUtils.copy(is, os);
}
byte[] out = bout.toByteArray();
return Arrays.copyOfRange(out, BZIP_HEADER.length, out.length); // remove header..
}
catch (IOException ex)
{
logger.warn(null, ex);
return null;
}
}
public static byte[] decompress(byte[] bytes)
{
try
{
byte[] data = new byte[bytes.length + BZIP_HEADER.length];
// add header
System.arraycopy(BZIP_HEADER, 0, data, 0, BZIP_HEADER.length);
System.arraycopy(bytes, 0, data, BZIP_HEADER.length, bytes.length);
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;
}
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs.util;
import java.util.zip.CRC32;
public final class CRC32HGenerator
{
public static final CRC32 CRC32Instance = new CRC32();
public static synchronized int getHash(byte[] data, int len)
{
CRC32Instance.update(data, 0, len);
try
{
return (int) CRC32Instance.getValue();
}
finally
{
CRC32Instance.reset();
}
}
}

View File

@@ -0,0 +1,28 @@
package net.runelite.cache.fs.util;
/**
* An implementation of the {@code djb2} hash function.
*
* @author Graham
* @author `Discardedx2
*/
public final class Djb2
{
/**
* An implementation of Dan Bernstein's {@code djb2} hash function which
* is slightly modified. Instead of the initial hash being 5381, it is
* zero.
*
* @param str The string to hash.
* @return The hash code.
*/
public static int hash(String str)
{
int hash = 0;
for (int i = 0; i < str.length(); i++)
{
hash = str.charAt(i) + ((hash << 5) - hash);
}
return hash;
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GZip
{
private static final Logger logger = LoggerFactory.getLogger(GZip.class);
public static byte[] compress(byte[] bytes)
{
InputStream is = new ByteArrayInputStream(bytes);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try (OutputStream os = new GZIPOutputStream(bout))
{
IOUtils.copy(is, os);
}
catch (IOException ex)
{
logger.warn(null, ex);
return null;
}
return bout.toByteArray();
}
public static byte[] decompress(byte[] bytes)
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
try (InputStream is = new GZIPInputStream(new ByteArrayInputStream(bytes)))
{
IOUtils.copy(is, os);
}
catch (IOException ex)
{
logger.warn(null, ex);
return null;
}
return os.toByteArray();
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs.util;
public class Whirlpool {
private static gnu.crypto.hash.Whirlpool whirlpool = new gnu.crypto.hash.Whirlpool();
public static synchronized byte[] getHash(byte[] data, int len)
{
whirlpool.update(data, 0, len);
try
{
return whirlpool.digest();
}
finally
{
whirlpool.reset();
}
}
}

View File

@@ -0,0 +1,193 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.io;
import java.io.IOException;
import java.nio.ByteBuffer;
public class InputStream extends java.io.InputStream
{
private static final char[] CHARACTERS = new char[]
{
'\u20ac', '\u0000', '\u201a', '\u0192', '\u201e', '\u2026',
'\u2020', '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039',
'\u0152', '\u0000', '\u017d', '\u0000', '\u0000', '\u2018',
'\u2019', '\u201c', '\u201d', '\u2022', '\u2013', '\u2014',
'\u02dc', '\u2122', '\u0161', '\u203a', '\u0153', '\u0000',
'\u017e', '\u0178'
};
private final ByteBuffer buffer;
public InputStream(byte[] buffer)
{
this.buffer = ByteBuffer.wrap(buffer);
}
public int read24BitInt()
{
return (this.readUnsignedByte() << 16) + (this.readUnsignedByte() << 8) + this.readUnsignedByte();
}
public void skip(int length)
{
int pos = buffer.position();
pos += length;
buffer.position(pos);
}
public void setOffset(int offset)
{
buffer.position(offset);
}
public int getOffset()
{
return buffer.position();
}
public int getLength()
{
return buffer.limit();
}
public byte readByte()
{
return buffer.get();
}
public void readBytes(byte[] buffer, int off, int len)
{
this.buffer.get(buffer, off, len);
}
public void readBytes(byte[] buffer)
{
this.buffer.get(buffer);
}
public int readUnsignedByte()
{
return this.readByte() & 0xFF;
}
public int readUnsignedShort()
{
return buffer.getShort() & 0xFFFF;
}
public short readShort()
{
return buffer.getShort();
}
public int readInt()
{
return buffer.getInt();
}
public byte peek()
{
int position = buffer.position();
try
{
return buffer.get();
}
finally
{
buffer.position(position);
}
}
public int readBigSmart()
{
return peek() >= 0 ? this.readUnsignedShort() : Integer.MAX_VALUE & this.readInt();
}
public int readShortSmart()
{
int var2 = this.peek() & 0xFF;
return var2 < 128 ? this.readUnsignedByte() - 64 : this.readUnsignedShort() - 0xc000;
}
public String readString()
{
StringBuilder sb = new StringBuilder();
for (;;)
{
int ch = this.readByte();
if (ch == 0)
break;
if (ch >= 128 && ch < 160)
{
char var7 = CHARACTERS[ch - 128];
if (0 == var7)
{
var7 = 63;
}
ch = var7;
}
sb.append((char) ch);
}
return sb.toString();
}
public String readStringOrNull()
{
if (this.peek() != 0)
{
return readString();
}
else
{
this.readByte(); // discard
return null;
}
}
public byte[] getRemaining()
{
byte[] b = new byte[buffer.remaining()];
buffer.get(b);
return b;
}
@Override
public int read() throws IOException
{
return this.readUnsignedByte();
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.io;
import java.io.IOException;
import java.nio.ByteBuffer;
public final class OutputStream extends java.io.OutputStream
{
private ByteBuffer buffer;
public OutputStream(int capacity)
{
buffer = ByteBuffer.allocate(capacity);
}
public OutputStream()
{
this(16);
}
private void ensureRemaining(int remaining)
{
while (remaining > buffer.remaining())
{
int newCapacity = buffer.capacity() * 2;
ByteBuffer old = buffer;
old.flip();
buffer = ByteBuffer.allocate(newCapacity);
buffer.put(old);
}
}
public void skip(int length)
{
int pos = buffer.position();
pos += length;
buffer.position(pos);
}
public void setOffset(int offset)
{
buffer.position(offset);
}
public void writeBytes(byte[] b)
{
ensureRemaining(b.length);
buffer.put(b);
}
public void writeByte(int i)
{
ensureRemaining(1);
buffer.put((byte) i);
}
public void writeBigSmart(int value)
{
if (value >= 65536)
{
ensureRemaining(5);
this.writeByte(-1);
this.writeInt(Integer.MAX_VALUE & value);
}
else
{
ensureRemaining(2);
this.writeShort(value);
}
}
public void writeShort(int i)
{
ensureRemaining(2);
buffer.putShort((short) i);
}
public void writeInt(int i)
{
ensureRemaining(4);
buffer.putInt(i);
}
public byte[] flip()
{
buffer.flip();
byte[] b = new byte[buffer.limit()];
buffer.get(b);
return b;
}
@Override
public void write(int b) throws IOException
{
buffer.put((byte) b);
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.renderable;
import java.awt.*;
import java.awt.image.*;
import net.runelite.cache.definitions.SpriteDefinition;
public class RGBSprite
{
private int offsetY;
private int spriteWidth;
private int spriteHeight;
private int offsetX;
private int maxHeight;
private int maxWidth;
private int[] pixels;
RGBSprite()
{
}
public int getOffsetY()
{
return offsetY;
}
public int getSpriteWidth()
{
return spriteWidth;
}
public int getSpriteHeight()
{
return spriteHeight;
}
public int getOffsetX()
{
return offsetX;
}
public int getMaxHeight()
{
return maxHeight;
}
public int getMaxWidth()
{
return maxWidth;
}
public int[] getPixels()
{
return pixels;
}
public static RGBSprite fromSpriteDefinition(SpriteDefinition def)
{
RGBSprite sprite = new RGBSprite();
sprite.maxWidth = def.getMaxWidth();
sprite.maxHeight = def.getMaxHeight();
sprite.offsetX = def.getOffsetX();
sprite.offsetY = def.getOffsetY();
sprite.spriteWidth = def.getWidth();
sprite.spriteHeight = def.getHeight();
int dimmension = sprite.spriteWidth * sprite.spriteHeight;
byte[] pixels = def.getPixels();
int[] palette = def.getLoader().getLoadedPalette();
sprite.pixels = new int[dimmension];
for (int pos = 0; pos < dimmension; ++pos)
{
sprite.pixels[pos] = palette[pixels[pos] & 255];
}
return sprite;
}
public BufferedImage getBufferedImage()
{
BufferedImage bi = new BufferedImage(spriteWidth, spriteHeight, BufferedImage.TYPE_INT_RGB);
bi.setRGB(0, 0, spriteWidth, spriteHeight, pixels, 0, spriteWidth);
Image img = makeColorTransparent(bi, new Color(0, 0, 0));
BufferedImage trans = imageToBufferedImage(img);
return trans;
}
private static Image makeColorTransparent(BufferedImage im, final Color color)
{
final int markerRGB = color.getRGB() | 0xFF000000;
RGBImageFilter filter = new RGBImageFilter()
{
@Override
public final int filterRGB(int x, int y, int rgb)
{
if ((rgb | 0xFF000000) == markerRGB)
{
return 0x00FFFFFF & rgb;
}
else
{
return rgb;
}
}
};
ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(ip);
}
private static BufferedImage imageToBufferedImage(Image image)
{
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
return bufferedImage;
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import net.runelite.cache.definitions.EnumDefinition;
import net.runelite.cache.definitions.loaders.EnumLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EnumDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(EnumDumperTest.class);
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test() throws IOException
{
File dumpDir = folder.newFolder();
int count = 0;
try (Store store = new Store(StoreLocation.LOCATION))
{
store.load();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.ENUM.getId());
EnumLoader loader = new EnumLoader();
for (net.runelite.cache.fs.File file : archive.getFiles())
{
byte[] b = file.getContents();
EnumDefinition def = loader.load(file.getFileId(), b);
Files.write(gson.toJson(def), new File(dumpDir, file.getFileId() + ".json"), Charset.defaultCharset());
++count;
}
}
logger.info("Dumped {} enums to {}", count, dumpDir);
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.io.File;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ItemDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(ItemDumperTest.class);
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test() throws IOException
{
File dumpDir = folder.newFolder(),
javaDir = folder.newFolder();
ItemDumper dumper = new ItemDumper(
StoreLocation.LOCATION,
dumpDir,
javaDir
);
dumper.load();
dumper.dump();
dumper.java();
logger.info("Dumped to {}, java {}", dumpDir, javaDir);
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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;
import com.google.gson.Gson;
import java.io.IOException;
import net.runelite.cache.definitions.loaders.ModelLoader;
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 org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ModelDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(ModelDumperTest.class);
private Gson gson = new Gson();
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test() throws IOException
{
java.io.File modelDir = folder.newFolder("models");
int count = 0;
try (Store store = new Store(StoreLocation.LOCATION))
{
store.load();
Index index = store.getIndex(IndexType.MODELS);
for (Archive archive : index.getArchives())
{
assert archive.getFiles().size() == 1;
File file = archive.getFiles().get(0);
byte[] contents = file.getContents();
ModelLoader loader = new ModelLoader();
loader.load(contents);
Files.write(contents, new java.io.File(modelDir, archive.getArchiveId() + ".model"));
//Files.write(gson.toJson(loader), new java.io.File(modelDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
++count;
}
}
logger.info("Dumped {} models to {}", count, modelDir);
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.io.File;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NpcDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(NpcDumperTest.class);
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test() throws IOException
{
File dumpDir = folder.newFolder(),
javaDir = folder.newFolder();
NpcDumper dumper = new NpcDumper(
StoreLocation.LOCATION,
dumpDir,
javaDir
);
dumper.load();
dumper.dump();
dumper.java();
logger.info("Dumped to {}, java {}", dumpDir, javaDir);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.io.File;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ObjectDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(ObjectDumperTest.class);
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test() throws IOException
{
File dumpDir = folder.newFolder(),
javaDir = folder.newFolder();
ObjectDumper dumper = new ObjectDumper(
StoreLocation.LOCATION,
dumpDir,
javaDir
);
dumper.load();
dumper.dump();
dumper.java();
logger.info("Dumped to {}, java {}", dumpDir, javaDir);
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.definitions.loaders.ScriptLoader;
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 org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ScriptDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(ScriptDumperTest.class);
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test() throws IOException
{
java.io.File outDir = folder.newFolder();
int count = 0;
try (Store store = new Store(StoreLocation.LOCATION))
{
store.load();
Index index = store.getIndex(IndexType.CLIENTSCRIPT);
ScriptLoader loader = new ScriptLoader();
for (Archive archive : index.getArchives())
{
assert archive.getFiles().size() == 1;
File file = archive.getFiles().get(0);
byte[] contents = file.getContents();
ScriptDefinition script = loader.load(file.getFileId(), contents);
Files.write(contents, new java.io.File(outDir, archive.getArchiveId() + ".script"));
++count;
}
}
logger.info("Dumped {} scripts to {}", count, outDir);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.io.File;
import java.net.URISyntaxException;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StoreLocation
{
private static final Logger logger = LoggerFactory.getLogger(StoreLocation.class);
public static File LOCATION;
static
{
try
{
LOCATION = new File(StoreLocation.class.getResource("/cache").toURI());
}
catch (URISyntaxException ex)
{
logger.error(null, ex);
}
File tmp = new File("d:/temp");
if (tmp.exists() || tmp.mkdir())
System.setProperty("java.io.tmpdir", "d:/temp");
}
public static TemporaryFolder getTemporaryFolder()
{
return new TemporaryFolder();
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import net.runelite.cache.StoreLocation;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class DataFileTest
{
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test1() throws IOException
{
File file = folder.newFile();
Store store = new Store(folder.getRoot());
DataFile df = new DataFile(store, file);
DataFileWriteResult res = df.write(42, 3, ByteBuffer.wrap("test".getBytes()), CompressionType.NONE, 0);
DataFileReadResult res2 = df.read(42, 3, res.sector, res.compressedLength);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("test", str);
file.delete();
}
@Test
public void test2() throws IOException
{
byte[] b = new byte[1024];
for (int i = 0; i < 1024; ++i)
b[i] = (byte) i;
File file = folder.newFile();
Store store = new Store(folder.getRoot());
DataFile df = new DataFile(store, file);
DataFileWriteResult res = df.write(42, 0x1FFFF, ByteBuffer.wrap(b), CompressionType.NONE, 0);
DataFileReadResult res2 = df.read(42, 0x1FFFF, res.sector, res.compressedLength);
byte[] buf = res2.data;
Assert.assertArrayEquals(b, buf);
file.delete();
}
@Test
public void testGZipCompression() throws IOException
{
try (Store store = new Store(folder.getRoot()))
{
DataFile df = new DataFile(store, folder.newFile());
DataFileWriteResult res = df.write(41, 4, ByteBuffer.wrap("test".getBytes()), CompressionType.GZ, 0);
DataFileReadResult res2 = df.read(41, 4, res.sector, res.compressedLength);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("test", str);
}
}
@Test
public void testBZip2Compression() throws IOException
{
try (Store store = new Store(folder.getRoot()))
{
DataFile df = new DataFile(store, folder.newFile());
DataFileWriteResult res = df.write(41, 4, ByteBuffer.wrap("test".getBytes()), CompressionType.BZ2, 0);
DataFileReadResult res2 = df.read(41, 4, res.sector, res.compressedLength);
byte[] buf = res2.data;
String str = new String(buf);
Assert.assertEquals("test", str);
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.io.File;
import java.io.IOException;
import net.runelite.cache.StoreLocation;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class IndexFileTest
{
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void test1() throws IOException
{
File file = folder.newFile();
Store store = new Store(folder.getRoot());
IndexFile index = new IndexFile(store, 5, file);
IndexEntry entry = new IndexEntry(index, 7, 8, 9);
index.write(entry);
IndexEntry entry2 = index.read(7);
Assert.assertEquals(entry, entry2);
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import com.google.common.io.Files;
import java.io.FileOutputStream;
import java.io.IOException;
import net.runelite.cache.StoreLocation;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class StoreLoadTest
{
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void testLoad() throws IOException
{
Store store = new Store(StoreLocation.LOCATION);
store.load();
System.out.println(store);
}
@Test
public void testSave() throws IOException
{
Store store = new Store(StoreLocation.LOCATION);
store.load();
java.io.File testStoreFile = folder.newFolder();
for (java.io.File f : StoreLocation.LOCATION.listFiles())
Files.copy(f, new java.io.File(testStoreFile, f.getName()));
Store testStore = new Store(testStoreFile);
testStore.load();
Assert.assertTrue(store.equals(testStore));
testStore.save();
testStore.load();
Assert.assertTrue(store.equals(testStore));
}
//@Test
public void unpackStore() throws IOException
{
java.io.File base = StoreLocation.LOCATION;
try (Store store = new Store(base))
{
store.load();
for (Index i : store.getIndexes())
{
java.io.File ifile = new java.io.File(folder.newFolder(), "" + i.getId());
ifile.mkdir();
for (Archive a : i.getArchives())
{
java.io.File afile = new java.io.File(ifile, "" + a.getArchiveId());
afile.mkdir();
for (File f : a.getFiles())
{
java.io.File ffile = new java.io.File(afile, "" + f.getFileId());
try (FileOutputStream fout = new FileOutputStream(ffile))
{
if (f.getContents() != null)
{
fout.write(f.getContents());
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.fs;
import java.io.IOException;
import java.util.Random;
import net.runelite.cache.StoreLocation;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class StoreTest
{
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void testOneFile() throws IOException
{
try (Store store = new Store(folder.getRoot()))
{
Index index = store.addIndex(0);
Archive archive = index.addArchive(0);
File file = archive.addFile(0);
file.setNameHash(7);
file.setContents("test".getBytes());
store.save();
try (Store store2 = new Store(folder.getRoot()))
{
store2.load();
Assert.assertEquals(store, store2);
}
}
}
private static final int NUMBER_OF_FILES = 1024;
@Test
public void testManyFiles() throws IOException
{
Random random = new Random(42L);
try (Store store = new Store(folder.getRoot()))
{
Index index = store.addIndex(0);
Archive archive = index.addArchive(0);
archive.setNameHash(random.nextInt());
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
File file = archive.addFile(i);
file.setNameHash(random.nextInt());
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
store.save();
try (Store store2 = new Store(folder.getRoot()))
{
store2.load();
Assert.assertEquals(store, store2);
}
}
}
@Test
public void testMultipleArchives() throws IOException
{
Random random = new Random(43L);
try (Store store = new Store(folder.getRoot()))
{
Index index = store.addIndex(0);
Index index2 = store.addIndex(1);
Archive archive = index.addArchive(0);
archive.setNameHash(random.nextInt());
Archive archive2 = index.addArchive(1);
Archive archive3 = index2.addArchive(0);
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
File file = archive.addFile(i);
file.setNameHash(random.nextInt());
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
File file = archive2.addFile(i);
file.setNameHash(random.nextInt());
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
for (int i = 0; i < NUMBER_OF_FILES; ++i)
{
File file = archive3.addFile(i);
file.setNameHash(random.nextInt());
byte[] data = new byte[random.nextInt(1024)];
random.nextBytes(data);
file.setContents(data);
}
store.save();
try (Store store2 = new Store(folder.getRoot()))
{
store2.load();
Assert.assertEquals(store, store2);
}
}
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.loaders;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import net.runelite.cache.IndexType;
import net.runelite.cache.StoreLocation;
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 net.runelite.cache.renderable.RGBSprite;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SpriteLoaderTest
{
private static final Logger logger = LoggerFactory.getLogger(SpriteLoaderTest.class);
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void extract() throws IOException
{
java.io.File base = StoreLocation.LOCATION,
outDir = folder.newFolder();
try (Store store = new Store(base))
{
store.load();
Index index = store.getIndex(IndexType.SPRITES);
for (Archive a : index.getArchives())
{
List<File> files = a.getFiles();
Assert.assertEquals(1, files.size());
File file = files.get(0);
byte[] contents = file.getContents();
SpriteLoader loader = new SpriteLoader();
loader.load(new InputStream(contents));
SpriteDefinition[] defs = loader.getSprites();
for (int i = 0; i < defs.length; ++i)
{
RGBSprite sp = RGBSprite.fromSpriteDefinition(defs[i]);
// I don't know why this happens
if (sp.getSpriteHeight() <= 0 || sp.getSpriteWidth() <= 0)
continue;
BufferedImage image = sp.getBufferedImage();
java.io.File targ = new java.io.File(outDir, a.getArchiveId() + "-" + i + ".png");
targ.mkdirs();
ImageIO.write(image, "png", targ);
}
}
}
logger.info("Dumped to {}", outDir);
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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 <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> 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 <Adam@sigterm.info> ''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 <Adam@sigterm.info> 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.loaders;
import java.io.IOException;
import java.nio.file.Files;
import net.runelite.cache.IndexType;
import net.runelite.cache.StoreLocation;
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 org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TitleDumper
{
private static final Logger logger = LoggerFactory.getLogger(TitleDumper.class);
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@Test
public void extract() throws IOException
{
java.io.File base = StoreLocation.LOCATION,
outFile = folder.newFile();
try (Store store = new Store(base))
{
store.load();
Index index = store.getIndex(IndexType.BINARY);
Archive a = index.findArchiveByName("title.jpg");
File file = a.getFiles().get(0);
Files.write(outFile.toPath(), file.getContents());
}
logger.info("Dumped to {}", outFile);
}
}