From edabf9ea71181acded5aa20a3190e96d6d42243c Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 27 Jan 2018 13:04:38 -0500 Subject: [PATCH] Add script assembler plugin for packing scripts at build time --- pom.xml | 1 + runelite-script-assembler-plugin/pom.xml | 79 ++++++++++++++ .../net/runelite/script/AssembleMojo.java | 101 ++++++++++++++++++ .../java/net/runelite/script/IndexMojo.java | 86 +++++++++++++++ .../runelite/script/RuneLiteInstructions.java | 38 +++++++ 5 files changed, 305 insertions(+) create mode 100644 runelite-script-assembler-plugin/pom.xml create mode 100644 runelite-script-assembler-plugin/src/main/java/net/runelite/script/AssembleMojo.java create mode 100644 runelite-script-assembler-plugin/src/main/java/net/runelite/script/IndexMojo.java create mode 100644 runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java diff --git a/pom.xml b/pom.xml index 9e3b4a79f0..7680458c37 100644 --- a/pom.xml +++ b/pom.xml @@ -119,6 +119,7 @@ runelite-api runelite-client runelite-mixins + runelite-script-assembler-plugin runescape-api runescape-client runescape-client-injector diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml new file mode 100644 index 0000000000..865d8e9875 --- /dev/null +++ b/runelite-script-assembler-plugin/pom.xml @@ -0,0 +1,79 @@ + + + + 4.0.0 + + + net.runelite + runelite-parent + 1.2.14-SNAPSHOT + + + net.runelite + script-assembler-plugin + Script Assembler Plugin + maven-plugin + + + + net.runelite + cache + ${project.version} + + + net.runelite + api + ${project.version} + + + + org.apache.maven + maven-plugin-api + 3.0.5 + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.4 + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.4 + + + default-descriptor + process-classes + + + + + + diff --git a/runelite-script-assembler-plugin/src/main/java/net/runelite/script/AssembleMojo.java b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/AssembleMojo.java new file mode 100644 index 0000000000..9ee058d690 --- /dev/null +++ b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/AssembleMojo.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, 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.script; + +import com.google.common.io.Files; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import net.runelite.cache.IndexType; +import net.runelite.cache.definitions.ScriptDefinition; +import net.runelite.cache.definitions.savers.ScriptSaver; +import net.runelite.cache.script.assembler.Assembler; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +@Mojo( + name = "assemble", + defaultPhase = LifecyclePhase.GENERATE_RESOURCES +) +public class AssembleMojo extends AbstractMojo +{ + @Parameter(required = true) + private File scriptDirectory; + + @Parameter(required = true) + private File outputDirectory; + + private final Log log = getLog(); + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + RuneLiteInstructions instructions = new RuneLiteInstructions(); + instructions.init(); + + Assembler assembler = new Assembler(instructions); + ScriptSaver saver = new ScriptSaver(); + + int count = 0; + File scriptOut = new File(outputDirectory, Integer.toString(IndexType.CLIENTSCRIPT.getNumber())); + scriptOut.mkdirs(); + + for (File scriptFile : scriptDirectory.listFiles((dir, name) -> name.endsWith(".rs2asm"))) + { + log.debug("Assembling " + scriptFile); + + try (FileInputStream fin = new FileInputStream(scriptFile)) + { + File hashFile = new File(scriptDirectory, Files.getNameWithoutExtension(scriptFile.getName()) + ".hash"); + if (!hashFile.exists()) + { + throw new MojoExecutionException("Unable to find hash file for " + scriptFile); + } + + ScriptDefinition script = assembler.assemble(fin); + byte[] packedScript = saver.save(script); + + File targetFile = new File(scriptOut, Integer.toString(script.getId())); + Files.write(packedScript, targetFile); + + // Copy hash file + Files.copy(hashFile, new File(scriptOut, Integer.toString(script.getId()) + ".hash")); + + ++count; + } + catch (IOException ex) + { + throw new MojoFailureException("unable to open file", ex); + } + } + + log.info("Assembled " + count + " scripts"); + } +} diff --git a/runelite-script-assembler-plugin/src/main/java/net/runelite/script/IndexMojo.java b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/IndexMojo.java new file mode 100644 index 0000000000..fa41a2f064 --- /dev/null +++ b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/IndexMojo.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018, 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.script; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import static java.lang.Integer.parseInt; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +@Mojo( + name = "build-index", + defaultPhase = LifecyclePhase.GENERATE_RESOURCES +) +public class IndexMojo extends AbstractMojo +{ + @Parameter(required = true) + private File archiveOverlayDirectory; + + @Parameter(required = true) + private File indexFile; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + try (DataOutputStream fout = new DataOutputStream(new FileOutputStream(indexFile))) + { + for (File indexFolder : archiveOverlayDirectory.listFiles()) + { + if (indexFolder.isDirectory()) + { + int indexId = parseInt(indexFolder.getName()); + for (File archiveFile : indexFolder.listFiles()) + { + int archiveId; + try + { + archiveId = parseInt(archiveFile.getName()); + } + catch (NumberFormatException ex) + { + continue; + } + + fout.writeInt(indexId << 16 | archiveId); + } + } + } + + fout.writeInt(-1); + } + catch (IOException ex) + { + throw new MojoExecutionException("error build index file", ex); + } + } + +} diff --git a/runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java new file mode 100644 index 0000000000..654e5e407c --- /dev/null +++ b/runelite-script-assembler-plugin/src/main/java/net/runelite/script/RuneLiteInstructions.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, 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.script; + +import static net.runelite.api.Opcodes.RUNELITE_EXECUTE; +import net.runelite.cache.script.Instructions; + +public class RuneLiteInstructions extends Instructions +{ + @Override + public void init() + { + super.init(); + add(RUNELITE_EXECUTE, "runelite_callback", 0, 0, 1, 0); + } +}