diff --git a/cache/src/main/java/net/runelite/cache/definitions/savers/InterfaceSaver.java b/cache/src/main/java/net/runelite/cache/definitions/savers/InterfaceSaver.java new file mode 100644 index 0000000000..64e3cae7eb --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/savers/InterfaceSaver.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import net.runelite.cache.definitions.InterfaceDefinition; +import net.runelite.cache.io.OutputStream; + +public class InterfaceSaver +{ + public byte[] save(InterfaceDefinition def) + { + if (def.hasScript) + { + return saveScript(def); + } + else + { + return saveNoScript(def); + } + } + + private byte[] saveScript(InterfaceDefinition def) + { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + private byte[] saveNoScript(InterfaceDefinition def) + { + OutputStream out = new OutputStream(); + out.writeByte(def.type); + out.writeByte(def.field2222); + out.writeShort(def.contentType); + out.writeShort(def.originalX); + out.writeShort(def.originalY); + out.writeShort(def.originalWidth); + out.writeShort(def.field2231); + out.writeByte(def.opacity); + out.writeShort(def.parentId); + out.writeShort(def.field2334); + if (def.tableActions != null) + { + out.writeByte(def.tableActions.length); + for (int i = 0; i < def.tableActions.length; ++i) + { + out.writeByte(def.tableActions[i]); + out.writeShort(def.field2333[i]); + } + } + else + { + out.writeByte(0); + } + if (def.dynamicValues != null) + { + out.writeByte(def.dynamicValues.length); + for (int i = 0; i < def.dynamicValues.length; ++i) + { + out.writeShort(def.dynamicValues[i].length); + for (int j = 0; j < def.dynamicValues[i].length; ++j) + { + out.writeShort(def.dynamicValues[i][j]); + } + } + } + else + { + out.writeByte(0); + } + if (def.type == 0) + { + out.writeShort(def.scrollHeight); + out.writeByte(def.isHidden ? 1 : 0); + } + if (def.type == 1) + { + out.writeShort(0); + out.writeByte(0); + } + if (def.type == 2) + { + out.writeByte((def.config & 268435456) != 0 ? 1 : 0); + out.writeByte((def.config & 1073741824) != 0 ? 1 : 0); + out.writeByte((def.config & Integer.MIN_VALUE) != 0 ? 1 : 0); + out.writeByte((def.config & 536870912) != 0 ? 1 : 0); + out.writeByte(def.paddingX); + out.writeByte(def.paddingY); + for (int i = 0; i < 20; ++i) + { + if (def.field2289[i] != -1) + { + out.writeByte(1); + out.writeShort(def.xSprites[i]); + out.writeShort(def.field2288[i]); + out.writeShort(def.field2289[i]); + } + else + { + out.writeByte(0); + } + } + for (int i = 0; i < 5; ++i) + { + if (def.configActions[i] != null) + { + out.writeString(def.configActions[i]); + } + else + { + out.writeString(""); + } + } + } + if (def.type == 3) + { + out.writeByte(def.field2267 ? 1 : 0); + } + if (def.type == 4 || def.type == 1) + { + out.writeByte(def.field2219); + out.writeByte(def.field2283); + out.writeByte(def.field2212); + out.writeShort(def.fontId); + out.writeByte(def.textShadowed ? 1 : 0); + } + if (def.type == 4) + { + out.writeString(def.text); + out.writeString(def.field2241); + } + if (def.type == 1 || def.type == 3 || def.type == 4) + { + out.writeInt(def.textColor); + } + if (def.type == 3 || def.type == 4) + { + out.writeInt(def.field2245); + out.writeInt(def.field2280); + out.writeInt(def.field2247); + } + if (def.type == 5) + { + out.writeInt(def.spriteId); + out.writeInt(def.field2332); + } + if (def.type == 6) + { + out.writeShort(def.modelId); + out.writeShort(def.field2265); + out.writeShort(def.field2266); + out.writeShort(def.field2276); + out.writeShort(def.modelZoom); + out.writeShort(def.rotationX); + out.writeShort(def.rotationZ); + } + if (def.type == 7) + { + out.writeByte(def.field2219); + out.writeShort(def.fontId); + out.writeByte(def.textShadowed ? 1 : 0); + out.writeInt(def.textColor); + out.writeShort(def.paddingX); + out.writeShort(def.paddingY); + out.writeByte((def.config & 1073741824) != 0 ? 1 : 0); + for (int i = 0; i < 5; ++i) + { + out.writeString(def.configActions[i]); + } + } + if (def.type == 8) + { + out.writeString(def.text); + } + if (def.field2222 == 2 || def.type == 2) + { + out.writeString(def.selectedAction); + out.writeString(def.field2335); + out.writeShort((def.config >>> 11) & 63); + } + if (def.field2222 == 1 || def.field2222 == 4 || def.field2222 == 5 || def.field2222 == 6) + { + out.writeString(def.tooltip); + } + return out.flip(); + } +} diff --git a/cache/src/main/java/net/runelite/cache/definitions/savers/ItemSaver.java b/cache/src/main/java/net/runelite/cache/definitions/savers/ItemSaver.java new file mode 100644 index 0000000000..baa9af3bea --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/savers/ItemSaver.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import java.util.Map.Entry; +import net.runelite.cache.definitions.ItemDefinition; +import net.runelite.cache.io.OutputStream; + +public class ItemSaver +{ + public byte[] save(ItemDefinition item) + { + OutputStream out = new OutputStream(); + if (item.inventoryModel != 0) + { + out.writeByte(1); + out.writeShort(item.inventoryModel); + } + if (item.name != null) + { + out.writeByte(2); + out.writeString(item.name); + } + out.writeByte(4); + out.writeShort(item.zoom2d); + out.writeByte(5); + out.writeShort(item.xan2d); + out.writeByte(6); + out.writeShort(item.yan2d); + out.writeByte(7); + out.writeShort(item.xOffset2d); + out.writeByte(8); + out.writeShort(item.yOffset2d); + if (item.stackable != 0) + { + out.writeByte(11); + } + out.writeByte(12); + out.writeInt(item.cost); + if (item.members) + { + out.writeByte(16); + } + if (item.maleModel0 != -1 || item.maleOffset != 0) + { + out.writeByte(23); + out.writeShort(item.maleModel0); + out.writeByte(item.maleOffset); + } + if (item.maleModel1 != -1) + { + out.writeByte(24); + out.writeShort(item.maleModel1); + } + if (item.femaleModel0 != -1 || item.femaleOffset != 0) + { + out.writeByte(25); + out.writeShort(item.femaleModel0); + out.writeByte(item.femaleOffset); + } + if (item.femaleModel1 != -1) + { + out.writeByte(26); + out.writeShort(item.femaleModel1); + } + for (int i = 0; i < 5; ++i) + { + if (item.options[i] != null) + { + out.writeByte(30 + i); + out.writeString(item.options[i]); + } + } + for (int i = 0; i < 5; ++i) + { + if (item.interfaceOptions[i] != null) + { + out.writeByte(35 + i); + out.writeString(item.interfaceOptions[i]); + } + } + if (item.colorFind != null && item.colorReplace != null) + { + out.writeByte(40); + out.writeByte(item.colorFind.length); + for (int i = 0; i < item.colorFind.length; ++i) + { + out.writeShort(item.colorFind[i]); + out.writeShort(item.colorReplace[i]); + } + } + if (item.textureFind != null && item.textureReplace != null) + { + out.writeByte(41); + out.writeByte(item.textureFind.length); + for (int i = 0; i < item.textureFind.length; ++i) + { + out.writeShort(item.textureFind[i]); + out.writeShort(item.textureReplace[i]); + } + } + out.writeByte(42); + out.writeByte(item.shiftClickDropIndex); + if (item.isTradeable) + { + out.writeByte(65); + } + if (item.maleModel2 != -1) + { + out.writeByte(78); + out.writeShort(item.maleModel2); + } + if (item.femaleModel2 != -1) + { + out.writeByte(79); + out.writeShort(item.femaleModel2); + } + if (item.maleHeadModel != -1) + { + out.writeByte(90); + out.writeShort(item.maleHeadModel); + } + if (item.femaleHeadModel != -1) + { + out.writeByte(91); + out.writeShort(item.femaleHeadModel); + } + if (item.maleHeadModel2 != -1) + { + out.writeByte(92); + out.writeShort(item.maleHeadModel2); + } + if (item.femaleHeadModel2 != -1) + { + out.writeByte(93); + out.writeShort(item.femaleHeadModel2); + } + out.writeByte(95); + out.writeShort(item.zan2d); + if (item.notedID != -1) + { + out.writeByte(97); + out.writeShort(item.notedID); + } + if (item.notedTemplate != -1) + { + out.writeByte(98); + out.writeShort(item.notedTemplate); + } + if (item.countObj != null) + { + for (int i = 0; i < 10; ++i) + { + out.writeByte(100 + i); + out.writeShort(item.countObj[i]); + out.writeShort(item.countCo[i]); + } + } + out.writeByte(110); + out.writeShort(item.resizeX); + out.writeByte(111); + out.writeShort(item.resizeY); + out.writeByte(112); + out.writeShort(item.resizeZ); + out.writeByte(113); + out.writeByte(item.ambient); + out.writeByte(114); + out.writeByte(item.contrast); + out.writeByte(115); + out.writeByte(item.team); + if (item.boughtId != -1) + { + out.writeByte(139); + out.writeShort(item.boughtId); + } + if (item.boughtTemplateId != -1) + { + out.writeByte(140); + out.writeShort(item.boughtTemplateId); + } + if (item.placeholderId != -1) + { + out.writeByte(148); + out.writeShort(item.placeholderId); + } + if (item.placeholderTemplateId != -1) + { + out.writeByte(149); + out.writeShort(item.placeholderTemplateId); + } + if (item.params != null) + { + out.writeByte(249); + out.writeByte(item.params.size()); + for (Entry entry : item.params.entrySet()) + { + out.writeByte(entry.getValue() instanceof String ? 1 : 0); + out.write24BitInt(entry.getKey()); + if (entry.getValue() instanceof String) + { + out.writeString((String) entry.getValue()); + } + else + { + out.writeInt((Integer) entry.getValue()); + } + } + } + out.writeByte(0); + + return out.flip(); + } +} diff --git a/cache/src/main/java/net/runelite/cache/definitions/savers/LocationSaver.java b/cache/src/main/java/net/runelite/cache/definitions/savers/LocationSaver.java new file mode 100644 index 0000000000..2086bd7e78 --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/savers/LocationSaver.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Multimap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import net.runelite.cache.definitions.LocationsDefinition; +import net.runelite.cache.io.OutputStream; +import net.runelite.cache.region.Location; + +public class LocationSaver +{ + public byte[] save(LocationsDefinition locs) + { + Multimap locById = LinkedListMultimap.create(); + List sortedLocs = new ArrayList<>(locs.getLocations()); + sortedLocs.sort((l1, l2) -> Integer.compare(l1.getId(), l2.getId())); + for (Location loc : sortedLocs) + { + locById.put(loc.getId(), loc); + } + OutputStream out = new OutputStream(); + int prevId = -1; + for (Integer id : locById.keySet()) + { + int diffId = id - prevId; + prevId = id; + + out.writeShortSmart(diffId); + + Collection locations = locById.get(id); + int position = 0; + for (Location loc : locations) + { + int packedPosition = (loc.getPosition().getZ() << 12) + | (loc.getPosition().getX() << 6) + | (loc.getPosition().getY()); + + int diffPos = packedPosition - position; + position = packedPosition; + + out.writeShortSmart(diffPos + 1); + + int packedAttributes = (loc.getType() << 2) | loc.getOrientation(); + out.writeByte(packedAttributes); + } + + out.writeShortSmart(0); + } + out.writeShortSmart(0); + return out.flip(); + } +} diff --git a/cache/src/main/java/net/runelite/cache/definitions/savers/NpcSaver.java b/cache/src/main/java/net/runelite/cache/definitions/savers/NpcSaver.java new file mode 100644 index 0000000000..d38ca582ad --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/savers/NpcSaver.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import java.util.Map; +import net.runelite.cache.definitions.NpcDefinition; +import net.runelite.cache.io.OutputStream; + +public class NpcSaver +{ + public byte[] save(NpcDefinition npc) + { + OutputStream out = new OutputStream(); + if (npc.models != null) + { + out.writeByte(1); + out.writeByte(npc.models.length); + for (int modelId : npc.models) + { + out.writeShort(modelId); + } + } + if (npc.name != null) + { + out.writeByte(2); + out.writeString(npc.name); + } + if (npc.tileSpacesOccupied != 1) + { + out.writeByte(12); + out.writeByte(npc.tileSpacesOccupied); + } + if (npc.stanceAnimation != -1) + { + out.writeByte(13); + out.writeShort(npc.stanceAnimation); + } + if (npc.walkAnimation != -1) + { + out.writeByte(14); + out.writeShort(npc.walkAnimation); + } + if (npc.anInt2165 != -1) + { + out.writeByte(15); + out.writeShort(npc.anInt2165); + } + if (npc.anInt2189 != -1) + { + out.writeByte(16); + out.writeShort(npc.anInt2189); + } + if (npc.rotate180Animation != -1 || npc.rotate90LeftAnimation != -1 || npc.rotate90RightAnimation != -1) + { + out.writeByte(17); + out.writeShort(npc.walkAnimation); + out.writeShort(npc.rotate180Animation); + out.writeShort(npc.rotate90RightAnimation); + out.writeShort(npc.rotate90LeftAnimation); + } + for (int i = 0; i < 5; ++i) + { + if (npc.options[i] != null) + { + out.writeByte(30 + i); + out.writeString(npc.options[i]); + } + } + if (npc.recolorToFind != null && npc.recolorToReplace != null) + { + out.writeByte(40); + out.writeByte(npc.recolorToFind.length); + for (int i = 0; i < npc.recolorToFind.length; ++i) + { + out.writeShort(npc.recolorToFind[i]); + out.writeShort(npc.recolorToReplace[i]); + } + } + if (npc.retextureToFind != null && npc.retextureToReplace != null) + { + out.writeByte(41); + out.writeByte(npc.retextureToFind.length); + for (int i = 0; i < npc.retextureToFind.length; ++i) + { + out.writeShort(npc.retextureToFind[i]); + out.writeShort(npc.retextureToReplace[i]); + } + } + if (npc.models_2 != null) + { + out.writeByte(60); + out.writeByte(npc.models_2.length); + for (int modelId : npc.models_2) + { + out.writeShort(modelId); + } + } + if (!npc.renderOnMinimap) + { + out.writeByte(93); + } + if (npc.combatLevel != -1) + { + out.writeByte(95); + out.writeShort(npc.combatLevel); + } + out.writeByte(97); + out.writeShort(npc.resizeX); + out.writeByte(98); + out.writeShort(npc.resizeY); + if (npc.hasRenderPriority) + { + out.writeByte(99); + } + out.writeByte(100); + out.writeByte(npc.ambient); + out.writeByte(101); + out.writeByte(npc.contrast); + if (npc.headIcon != -1) + { + out.writeByte(102); + out.writeShort(npc.headIcon); + } + out.writeByte(103); + out.writeShort(npc.anInt2156); + if (!npc.isClickable) + { + out.writeByte(107); + } + if (!npc.aBool2170) + { + out.writeByte(109); + } + if (npc.aBool2190) + { + out.writeByte(111); + } + if (npc.anIntArray2185 != null) + { + out.writeByte(118); + out.writeShort(npc.anInt2174); + out.writeShort(npc.anInt2187); + + int[] c = npc.anIntArray2185; + out.writeShort(c[c.length - 1]); + out.writeByte(c.length - 2); + for (int i = 0; i <= c.length - 2; ++i) + { + out.writeShort(c[i]); + } + } + if (npc.params != null) + { + out.writeByte(249); + out.writeByte(npc.params.size()); + for (Map.Entry entry : npc.params.entrySet()) + { + out.writeByte(entry.getValue() instanceof String ? 1 : 0); + out.write24BitInt(entry.getKey()); + if (entry.getValue() instanceof String) + { + out.writeString((String) entry.getValue()); + } + else + { + out.writeInt((Integer) entry.getValue()); + } + } + } + out.writeByte(0); + return out.flip(); + } +} diff --git a/cache/src/main/java/net/runelite/cache/definitions/savers/ObjectSaver.java b/cache/src/main/java/net/runelite/cache/definitions/savers/ObjectSaver.java new file mode 100644 index 0000000000..f5b7d42a6d --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/savers/ObjectSaver.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import java.util.Map; +import net.runelite.cache.definitions.ObjectDefinition; +import net.runelite.cache.io.OutputStream; + +public class ObjectSaver +{ + public byte[] save(ObjectDefinition obj) + { + OutputStream out = new OutputStream(); + if (obj.getObjectTypes() != null && obj.getObjectModels() != null) + { + out.writeByte(1); + out.writeByte(obj.getObjectTypes().length); + for (int i = 0; i < obj.getObjectTypes().length; ++i) + { + out.writeShort(obj.getObjectModels()[i]); + out.writeByte(obj.getObjectTypes()[i]); + } + } + if (obj.getName() != null) + { + out.writeByte(2); + out.writeString(obj.getName()); + } + if (obj.getObjectTypes() == null && obj.getObjectModels() != null) + { + out.writeByte(5); + out.writeByte(obj.getObjectModels().length); + for (int i = 0; i < obj.getObjectModels().length; ++i) + { + out.writeShort(obj.getObjectModels()[i]); + } + } + out.writeByte(14); + out.writeByte(obj.getSizeX()); + out.writeByte(15); + out.writeByte(obj.getSizeY()); + if (obj.getInteractType() == 0 && !obj.isBlocksProjectile()) + { + out.writeByte(17); + } + else if (!obj.isBlocksProjectile()) + { + out.writeByte(18); + } + if (obj.getAnInt2088() != -1) + { + out.writeByte(19); + out.writeByte(obj.getAnInt2088()); + } + if (obj.getAnInt2105() == 0) + { + out.writeByte(21); + } + if (!obj.isNonFlatShading()) + { + out.writeByte(22); + } + if (obj.isABool2111()) + { + out.writeByte(23); + } + if (obj.getAnimationID() != -1) + { + out.writeByte(24); + out.writeShort(obj.getAnimationID()); + } + if (obj.getInteractType() == 1) + { + out.writeByte(27); + } + out.writeByte(28); + out.writeByte(obj.getAnInt2069()); + out.writeByte(29); + out.writeByte(obj.getAmbient()); + out.writeByte(39); + out.writeByte(obj.getContrast()); + for (int i = 0; i < 5; ++i) + { + out.writeByte(30 + i); + String action = obj.getActions()[i]; + out.writeString(action != null ? action : "Hidden"); + } + if (obj.getRecolorToFind() != null && obj.getRecolorToReplace() != null) + { + out.writeByte(40); + out.writeByte(obj.getRecolorToFind().length); + for (int i = 0; i < obj.getRecolorToFind().length; ++i) + { + out.writeShort(obj.getRecolorToFind()[i]); + out.writeShort(obj.getRecolorToReplace()[i]); + } + } + if (obj.getRetextureToFind() != null && obj.getTextureToReplace() != null) + { + out.writeByte(41); + out.writeByte(obj.getRetextureToFind().length); + for (int i = 0; i < obj.getRetextureToFind().length; ++i) + { + out.writeShort(obj.getRetextureToFind()[i]); + out.writeShort(obj.getTextureToReplace()[i]); + } + } + if (obj.isRotated()) + { + out.writeByte(62); + } + if (!obj.isABool2097()) + { + out.writeByte(64); + } + out.writeByte(65); + out.writeShort(obj.getModelSizeX()); + out.writeByte(66); + out.writeShort(obj.getModelSizeHeight()); + out.writeByte(67); + out.writeShort(obj.getModelSizeY()); + if (obj.getMapSceneID() != -1) + { + out.writeByte(68); + out.writeShort(obj.getMapSceneID()); + } + out.writeByte(70); + out.writeShort(obj.getOffsetX()); + out.writeByte(71); + out.writeShort(obj.getOffsetHeight()); + out.writeByte(72); + out.writeShort(obj.getOffsetY()); + if (obj.isABool2104()) + { + out.writeByte(73); + } + if (obj.isSolid()) + { + out.writeByte(74); + } + if (obj.getAnInt2106() != -1) + { + out.writeByte(75); + out.writeByte(obj.getAnInt2106()); + } + if (obj.getAnInt2110() != -1) + { + out.writeByte(78); + out.writeShort(obj.getAnInt2110()); + out.writeByte(obj.getAnInt2083()); + } + if (obj.getAnIntArray2084() != null) + { + out.writeByte(79); + out.writeShort(obj.getAnInt2112()); + out.writeShort(obj.getAnInt2113()); + out.writeByte(obj.getAnInt2083()); + out.writeByte(obj.getAnIntArray2084().length); + for (int i : obj.getAnIntArray2084()) + { + out.writeShort(i); + } + } + if (obj.getAnInt2105() != -1) + { + out.writeByte(81); + out.writeByte(obj.getAnInt2105() / 256); + } + if (obj.getMapAreaId() != -1) + { + out.writeByte(82); + out.writeShort(obj.getMapAreaId()); + } + if (obj.getConfigChangeDest() != null) + { + out.writeByte(92); + out.writeShort(obj.getVarpID()); + out.writeShort(obj.getConfigId()); + + int[] c = obj.getConfigChangeDest(); + out.writeShort(c[c.length - 1]); + out.writeByte(c.length - 2); + for (int i = 0; i <= c.length - 2; ++i) + { + out.writeShort(c[i]); + } + } + if (obj.getParams() != null) + { + out.writeByte(249); + out.writeByte(obj.getParams().size()); + for (Map.Entry entry : obj.getParams().entrySet()) + { + out.writeByte(entry.getValue() instanceof String ? 1 : 0); + out.write24BitInt(entry.getKey()); + if (entry.getValue() instanceof String) + { + out.writeString((String) entry.getValue()); + } + else + { + out.writeInt((Integer) entry.getValue()); + } + } + } + out.writeByte(0); + return out.flip(); + } +} diff --git a/cache/src/main/java/net/runelite/cache/definitions/savers/ScriptSaver.java b/cache/src/main/java/net/runelite/cache/definitions/savers/ScriptSaver.java new file mode 100644 index 0000000000..c1fae2e995 --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/definitions/savers/ScriptSaver.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import java.util.Map; +import java.util.Map.Entry; +import net.runelite.cache.definitions.ScriptDefinition; +import net.runelite.cache.io.OutputStream; +import static net.runelite.cache.script.Opcodes.LOAD_STRING; +import static net.runelite.cache.script.Opcodes.POP_INT; +import static net.runelite.cache.script.Opcodes.POP_STRING; +import static net.runelite.cache.script.Opcodes.RETURN; + +public class ScriptSaver +{ + public byte[] save(ScriptDefinition script) + { + int[] instructions = script.getInstructions(); + int[] intOperands = script.getIntOperands(); + String[] stringOperands = script.getStringOperands(); + Map[] switches = script.getSwitches(); + + OutputStream out = new OutputStream(); + out.writeByte(0); // null string + for (int i = 0; i < instructions.length; ++i) + { + int opcode = instructions[i]; + out.writeShort(opcode); + if (opcode == LOAD_STRING) + { + out.writeString(stringOperands[i]); + } + else if (opcode < 100 && opcode != RETURN && opcode != POP_INT && opcode != POP_STRING) + { + out.writeInt(intOperands[i]); + } + else + { + out.writeByte(intOperands[i]); + } + } + out.writeInt(instructions.length); + out.writeShort(script.getLocalIntCount()); + out.writeShort(script.getLocalStringCount()); + out.writeShort(script.getIntStackCount()); + out.writeShort(script.getStringStackCount()); + int switchStart = out.getOffset(); + if (switches == null) + { + out.writeByte(0); + } + else + { + out.writeByte(switches.length); + for (Map s : switches) + { + out.writeShort(s.size()); + for (Entry e : s.entrySet()) + { + out.writeInt(e.getKey()); + out.writeInt(e.getValue()); + } + } + } + int switchLength = out.getOffset() - switchStart; + out.writeShort(switchLength); + return out.flip(); + } +} diff --git a/cache/src/test/java/net/runelite/cache/definitions/savers/InterfaceSaverTest.java b/cache/src/test/java/net/runelite/cache/definitions/savers/InterfaceSaverTest.java new file mode 100644 index 0000000000..cc4bf51a5c --- /dev/null +++ b/cache/src/test/java/net/runelite/cache/definitions/savers/InterfaceSaverTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import java.io.File; +import net.runelite.cache.IndexType; +import net.runelite.cache.StoreLocation; +import net.runelite.cache.definitions.InterfaceDefinition; +import net.runelite.cache.definitions.loaders.InterfaceLoader; +import net.runelite.cache.fs.Archive; +import net.runelite.cache.fs.ArchiveFiles; +import net.runelite.cache.fs.FSFile; +import net.runelite.cache.fs.Index; +import net.runelite.cache.fs.Storage; +import net.runelite.cache.fs.Store; +import static org.junit.Assert.assertArrayEquals; +import org.junit.Test; + +public class InterfaceSaverTest +{ + + @Test + public void testSave() throws Exception + { + File base = StoreLocation.LOCATION; + try (Store store = new Store(base)) + { + store.load(); + + Storage storage = store.getStorage(); + Index index = store.getIndex(IndexType.INTERFACES); + Archive archive = index.getArchive(149); + byte[] archiveData = storage.loadArchive(archive); + ArchiveFiles files = archive.getFiles(archiveData); + FSFile file = files.findFile(0); + byte[] contents = file.getContents(); + + InterfaceDefinition def = new InterfaceLoader().load(0, contents); + byte[] b = new InterfaceSaver().save(def); + assertArrayEquals(contents, b); + } + } + +} diff --git a/cache/src/test/java/net/runelite/cache/definitions/savers/ScriptSaverTest.java b/cache/src/test/java/net/runelite/cache/definitions/savers/ScriptSaverTest.java new file mode 100644 index 0000000000..c485016854 --- /dev/null +++ b/cache/src/test/java/net/runelite/cache/definitions/savers/ScriptSaverTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.cache.definitions.savers; + +import java.io.IOException; +import net.runelite.cache.definitions.ScriptDefinition; +import net.runelite.cache.definitions.loaders.ScriptLoader; +import net.runelite.cache.script.assembler.Assembler; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author Adam + */ +public class ScriptSaverTest +{ + private static final String SCRIPT_RESOURCE = "/net/runelite/cache/script/assembler/91.rs2asm"; + + @Test + public void testSave() throws IOException + { + ScriptDefinition script = new Assembler().assemble(getClass().getResourceAsStream(SCRIPT_RESOURCE)); + byte[] saved = new ScriptSaver().save(script); + ScriptDefinition loadedScripot = new ScriptLoader().load(42, saved); + assertEquals(script, loadedScripot); + } + +}