From 76529e028a69c5cf89c92e65f5fa4c6fd5b80120 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 26 Nov 2016 11:05:17 -0500 Subject: [PATCH] Add sequence loading --- .../cache/definitions/SequenceDefinition.java | 60 +++++++ .../cache/definitions/loaders/NpcLoader.java | 2 +- .../definitions/loaders/SequenceLoader.java | 160 ++++++++++++++++++ .../net/runelite/cache/SequenceDumper.java | 86 ++++++++++ 4 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 cache/src/main/java/net/runelite/cache/definitions/SequenceDefinition.java create mode 100644 cache/src/main/java/net/runelite/cache/definitions/loaders/SequenceLoader.java create mode 100644 cache/src/test/java/net/runelite/cache/SequenceDumper.java diff --git a/cache/src/main/java/net/runelite/cache/definitions/SequenceDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/SequenceDefinition.java new file mode 100644 index 0000000000..42dedcae90 --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/SequenceDefinition.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam + * 4. Neither the name of the Adam 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 ''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 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 SequenceDefinition +{ + private final int id; + public int[] frameIDs; + public int[] field3048; + public int[] frameLenghts; + public int rightHandItem = -1; + public int[] interleaveLeave; + public boolean stretches = false; + public int forcedPriority = 5; + public int maxLoops = 99; + public int[] field3056; + public int precedenceAnimating = -1; + public int leftHandItem = -1; + public int replyMode = 2; + public int frameStep = -1; + public int priority = -1; + + public SequenceDefinition(int id) + { + this.id = id; + } + + public int getId() + { + return id; + } + +} diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/NpcLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/NpcLoader.java index f2cced76c1..39adf35f3f 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/NpcLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/NpcLoader.java @@ -56,7 +56,7 @@ public class NpcLoader return def; } - void decodeValues(int opcode, NpcDefinition def, InputStream stream) + private void decodeValues(int opcode, NpcDefinition def, InputStream stream) { int length; int index; diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/SequenceLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/SequenceLoader.java new file mode 100644 index 0000000000..dda18ec7a1 --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/SequenceLoader.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2016, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam + * 4. Neither the name of the Adam 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 ''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 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.SequenceDefinition; +import net.runelite.cache.io.InputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SequenceLoader +{ + private static final Logger logger = LoggerFactory.getLogger(SequenceLoader.class); + + public SequenceDefinition load(int id, InputStream stream) + { + SequenceDefinition def = new SequenceDefinition(id); + + while (true) + { + int opcode = stream.readUnsignedByte(); + if (opcode == 0) + { + break; + } + + this.decodeValues(opcode, def, stream); + } + + return def; + } + + private void decodeValues(int opcode, SequenceDefinition def, InputStream stream) + { + int var3; + int var4; + if (opcode == 1) + { + var3 = stream.readUnsignedShort(); + def.frameLenghts = new int[var3]; + + for (var4 = 0; var4 < var3; ++var4) + { + def.frameLenghts[var4] = stream.readUnsignedShort(); + } + + def.frameIDs = new int[var3]; + + for (var4 = 0; var4 < var3; ++var4) + { + def.frameIDs[var4] = stream.readUnsignedShort(); + } + + for (var4 = 0; var4 < var3; ++var4) + { + def.frameIDs[var4] += stream.readUnsignedShort() << 16; + } + } + else if (opcode == 2) + { + def.frameStep = stream.readUnsignedShort(); + } + else if (opcode == 3) + { + var3 = stream.readUnsignedByte(); + def.interleaveLeave = new int[1 + var3]; + + for (var4 = 0; var4 < var3; ++var4) + { + def.interleaveLeave[var4] = stream.readUnsignedByte(); + } + + def.interleaveLeave[var3] = 9999999; + } + else if (opcode == 4) + { + def.stretches = true; + } + else if (opcode == 5) + { + def.forcedPriority = stream.readUnsignedByte(); + } + else if (opcode == 6) + { + def.leftHandItem = stream.readUnsignedShort(); + } + else if (opcode == 7) + { + def.rightHandItem = stream.readUnsignedShort(); + } + else if (opcode == 8) + { + def.maxLoops = stream.readUnsignedByte(); + } + else if (opcode == 9) + { + def.precedenceAnimating = stream.readUnsignedByte(); + } + else if (opcode == 10) + { + def.priority = stream.readUnsignedByte(); + } + else if (opcode == 11) + { + def.replyMode = stream.readUnsignedByte(); + } + else if (opcode == 12) + { + var3 = stream.readUnsignedByte(); + def.field3048 = new int[var3]; + + for (var4 = 0; var4 < var3; ++var4) + { + def.field3048[var4] = stream.readUnsignedShort(); + } + + for (var4 = 0; var4 < var3; ++var4) + { + def.field3048[var4] += stream.readUnsignedShort() << 16; + } + } + else if (opcode == 13) + { + var3 = stream.readUnsignedByte(); + def.field3056 = new int[var3]; + + for (var4 = 0; var4 < var3; ++var4) + { + def.field3056[var4] = stream.read24BitInt(); + } + } + + } +} diff --git a/cache/src/test/java/net/runelite/cache/SequenceDumper.java b/cache/src/test/java/net/runelite/cache/SequenceDumper.java new file mode 100644 index 0000000000..73ce84da35 --- /dev/null +++ b/cache/src/test/java/net/runelite/cache/SequenceDumper.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam + * 4. Neither the name of the Adam 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 ''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 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 java.nio.charset.Charset; +import net.runelite.cache.definitions.SequenceDefinition; +import net.runelite.cache.definitions.loaders.SequenceLoader; +import net.runelite.cache.fs.Archive; +import net.runelite.cache.fs.File; +import net.runelite.cache.fs.Index; +import net.runelite.cache.fs.Store; +import net.runelite.cache.io.InputStream; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SequenceDumper +{ + private static final Logger logger = LoggerFactory.getLogger(SequenceDumper.class); + + @Rule + public TemporaryFolder folder = StoreLocation.getTemporaryFolder(); + + private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + @Test + public void extract() throws IOException + { + java.io.File base = StoreLocation.LOCATION, + outDir = folder.newFile(); + + int count = 0; + + try (Store store = new Store(base)) + { + store.load(); + + Index index = store.getIndex(IndexType.CONFIGS); + Archive archive = index.getArchive(ConfigType.SEQUENCE.getId()); + + for (File file : archive.getFiles()) + { + SequenceLoader loader = new SequenceLoader(); + SequenceDefinition seq = loader.load(file.getFileId(), new InputStream(file.getContents())); + + Files.write(gson.toJson(seq), new java.io.File(outDir, file.getFileId() + ".json"), Charset.defaultCharset()); + ++count; + } + } + + logger.info("Dumped {} sequences to {}", count, outDir); + } +}