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

121
cache/pom.xml vendored Normal file
View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<groupId>net.runelite</groupId>
<artifactId>cache</artifactId>
<version>1.1.0-SNAPSHOT</version>
<name>Cache</name>
<dependencies>
<dependency>
<groupId>net.runelite.rs</groupId>
<artifactId>api</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.gnu</groupId>
<artifactId>gnu-crypto</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<enableAssertions>true</enableAssertions>
<argLine>-Xmx1024m</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

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);
}
}