From b96619e2d8305aee28512455d0cdfd77e9883bab Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 7 May 2017 15:34:27 -0400 Subject: [PATCH] cache: add script attrs to assembler and disassembler --- .../runelite/cache/script/assembler/rs2asm.g4 | 8 ++- .../cache/script/assembler/Attribute.java | 62 +++++++++++++++++++ .../cache/script/assembler/ScriptWriter.java | 58 +++++++++++++++++ .../script/disassembler/Disassembler.java | 29 +++++++++ .../cache/script/assembler/AssemblerTest.java | 14 +---- .../cache/script/assembler/395.rs2asm | 2 + 6 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 cache/src/main/java/net/runelite/cache/script/assembler/Attribute.java diff --git a/cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4 b/cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4 index fdd89213f6..0633ef370f 100644 --- a/cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4 +++ b/cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4 @@ -24,7 +24,13 @@ */ grammar rs2asm; -prog: (line NEWLINE)+ ; +prog: (attr NEWLINE)* (line NEWLINE)+ ; + +attr: '.attr ' attr_idx ' ' attr_key ' ' attr_value ; +attr_idx: INT ; +attr_key: INT ; +attr_value: INT ; + line: instruction | label ; instruction: instruction_name instruction_operand ; label: 'LABEL' INT ':' ; diff --git a/cache/src/main/java/net/runelite/cache/script/assembler/Attribute.java b/cache/src/main/java/net/runelite/cache/script/assembler/Attribute.java new file mode 100644 index 0000000000..688fdb2a75 --- /dev/null +++ b/cache/src/main/java/net/runelite/cache/script/assembler/Attribute.java @@ -0,0 +1,62 @@ +/* + * 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.script.assembler; + +public class Attribute +{ + private int idx; + private int key; + private int value; + + public int getIdx() + { + return idx; + } + + public void setIdx(int idx) + { + this.idx = idx; + } + + public int getKey() + { + return key; + } + + public void setKey(int key) + { + this.key = key; + } + + public int getValue() + { + return value; + } + + public void setValue(int value) + { + this.value = value; + } +} diff --git a/cache/src/main/java/net/runelite/cache/script/assembler/ScriptWriter.java b/cache/src/main/java/net/runelite/cache/script/assembler/ScriptWriter.java index 119afe155a..aeb5ca9129 100644 --- a/cache/src/main/java/net/runelite/cache/script/assembler/ScriptWriter.java +++ b/cache/src/main/java/net/runelite/cache/script/assembler/ScriptWriter.java @@ -25,7 +25,9 @@ package net.runelite.cache.script.assembler; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import net.runelite.cache.definitions.ScriptDefinition; import net.runelite.cache.script.Instruction; import net.runelite.cache.script.Instructions; @@ -42,12 +44,45 @@ public class ScriptWriter extends rs2asmBaseListener private List opcodes = new ArrayList<>(); private List iops = new ArrayList<>(); private List sops = new ArrayList<>(); + private List attrs = new ArrayList<>(); public ScriptWriter(LabelVisitor labelVisitor) { this.labelVisitor = labelVisitor; } + @Override + public void exitAttr_idx(rs2asmParser.Attr_idxContext ctx) + { + String text = ctx.getText(); + int idx = Integer.parseInt(text); + + Attribute attr = new Attribute(); + attr.setIdx(idx); + + attrs.add(attr); + } + + @Override + public void exitAttr_key(rs2asmParser.Attr_keyContext ctx) + { + String text = ctx.getText(); + int key = Integer.parseInt(text); + + Attribute attr = attrs.get(attrs.size() - 1); + attr.setKey(key); + } + + @Override + public void exitAttr_value(rs2asmParser.Attr_valueContext ctx) + { + String text = ctx.getText(); + int value = Integer.parseInt(text); + + Attribute attr = attrs.get(attrs.size() - 1); + attr.setValue(value); + } + @Override public void exitInstruction(rs2asmParser.InstructionContext ctx) { @@ -127,6 +162,29 @@ public class ScriptWriter extends rs2asmBaseListener .mapToInt(Integer::valueOf) .toArray()); script.setStringOperands(sops.toArray(new String[0])); + script.setAttributes(buildAttributes()); return script; } + + private Map[] buildAttributes() + { + if (attrs == null || attrs.isEmpty()) + { + return null; + } + + Map[] maps = new Map[attrs.stream().map(attr -> attr.getIdx()).max(Integer::compare).get() + 1]; + for (Attribute attr : attrs) + { + Map map = maps[attr.getIdx()]; + if (map == null) + { + map = new HashMap<>(); + maps[attr.getIdx()] = map; + } + + map.put(attr.getKey(), attr.getValue()); + } + return maps; + } } diff --git a/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java b/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java index fd8910a247..a70f47bc4c 100644 --- a/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java +++ b/cache/src/main/java/net/runelite/cache/script/disassembler/Disassembler.java @@ -25,6 +25,8 @@ package net.runelite.cache.script.disassembler; import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; import net.runelite.cache.definitions.ScriptDefinition; import net.runelite.cache.script.Instruction; import net.runelite.cache.script.Instructions; @@ -84,6 +86,8 @@ public class Disassembler { StringBuilder writer = new StringBuilder(); + writeAttributes(script, writer); + int[] instructions = script.getInstructions(); int[] iops = script.getIntOperands(); String[] sops = script.getStringOperands(); @@ -144,4 +148,29 @@ public class Disassembler return writer.toString(); } + + private void writeAttributes(ScriptDefinition script, StringBuilder writer) + { + Map[] attributes = script.getAttributes(); + if (attributes == null) + { + return; + } + + int index = -1; + for (Map map : attributes) + { + ++index; + + if (map == null) + { + continue; + } + + for (Entry entry : map.entrySet()) + { + writer.append(".attr ").append(index).append(" ").append(entry.getKey()).append(" ").append(entry.getValue()).append("\n"); + } + } + } } diff --git a/cache/src/test/java/net/runelite/cache/script/assembler/AssemblerTest.java b/cache/src/test/java/net/runelite/cache/script/assembler/AssemblerTest.java index 8623974bdc..cbad86bec9 100644 --- a/cache/src/test/java/net/runelite/cache/script/assembler/AssemblerTest.java +++ b/cache/src/test/java/net/runelite/cache/script/assembler/AssemblerTest.java @@ -30,21 +30,13 @@ import net.runelite.cache.script.disassembler.Disassembler; import org.apache.commons.compress.utils.IOUtils; import org.junit.Assert; import org.junit.Test; -import org.junit.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.impl.SimpleLogger; public class AssemblerTest { private static final Logger logger = LoggerFactory.getLogger(AssemblerTest.class); - @Before - public void before() - { - System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "DEBUG"); - } - @Test public void testAssemble() throws Exception { @@ -63,9 +55,9 @@ public class AssemblerTest String original = new String(IOUtils.toByteArray(in)); - logger.debug(original); - logger.debug("-----------------------"); - logger.debug(out); + logger.info(original); + logger.info("-----------------------"); + logger.info(out); Assert.assertEquals(original, out); } diff --git a/cache/src/test/resources/net/runelite/cache/script/assembler/395.rs2asm b/cache/src/test/resources/net/runelite/cache/script/assembler/395.rs2asm index c6f8b3b88a..d1411a5e6a 100644 --- a/cache/src/test/resources/net/runelite/cache/script/assembler/395.rs2asm +++ b/cache/src/test/resources/net/runelite/cache/script/assembler/395.rs2asm @@ -1,3 +1,5 @@ +.attr 4 8 15 +.attr 16 23 42 033 get_boostedskilllevels int_to_string