use of net.runelite.cache.definitions.ScriptDefinition in project runelite by runelite.
the class DisassemblerTest method test.
@Test
public void test() throws IOException {
File outDir = folder.newFolder();
int count = 0;
try (Store store = new Store(StoreLocation.LOCATION)) {
store.load();
Storage storage = store.getStorage();
Index index = store.getIndex(IndexType.CLIENTSCRIPT);
ScriptLoader loader = new ScriptLoader();
for (Archive archive : index.getArchives()) {
byte[] contents = archive.decompress(storage.loadArchive(archive));
if (contents == null) {
continue;
}
ScriptDefinition script = loader.load(0, contents);
File outFile = new File(outDir, archive.getArchiveId() + ".rs2asm");
Disassembler disassembler = new Disassembler();
String out = disassembler.disassemble(script);
Files.write(out.getBytes(), outFile);
++count;
}
}
logger.info("Dumped {} scripts to {}", count, outDir);
}
use of net.runelite.cache.definitions.ScriptDefinition in project runelite by runelite.
the class ScriptLoader method load.
public ScriptDefinition load(int id, byte[] b) {
ScriptDefinition def = new ScriptDefinition();
InputStream in = new InputStream(b);
in.setOffset(in.getLength() - 2);
int switchLength = in.readUnsignedShort();
// 2 for switchLength + the switch data + 12 for the param/vars/stack data
int endIdx = in.getLength() - 2 - switchLength - 12;
in.setOffset(endIdx);
int numOpcodes = in.readInt();
int localIntCount = in.readUnsignedShort();
int localStringCount = in.readUnsignedShort();
int intStackCount = in.readUnsignedShort();
int stringStackCount = in.readUnsignedShort();
int numSwitches = in.readUnsignedByte();
if (numSwitches > 0) {
Map<Integer, Integer>[] switches = new Map[numSwitches];
def.setSwitches(switches);
for (int i = 0; i < numSwitches; ++i) {
switches[i] = new HashMap<>();
int count = in.readUnsignedShort();
while (count-- > 0) {
// int from stack is compared to this
int key = in.readInt();
// pc jumps by this
int pcOffset = in.readInt();
switches[i].put(key, pcOffset);
}
}
}
def.setLocalIntCount(localIntCount);
def.setLocalStringCount(localStringCount);
def.setIntStackCount(intStackCount);
def.setStringStackCount(stringStackCount);
in.setOffset(0);
in.readStringOrNull();
int[] instructions = new int[numOpcodes];
int[] intOperands = new int[numOpcodes];
String[] stringOperands = new String[numOpcodes];
def.setInstructions(instructions);
def.setIntOperands(intOperands);
def.setStringOperands(stringOperands);
int opcode;
for (int i = 0; in.getOffset() < endIdx; instructions[i++] = opcode) {
opcode = in.readUnsignedShort();
if (opcode == LOAD_STRING) {
stringOperands[i] = in.readString();
} else if (opcode < 100 && opcode != RETURN && opcode != POP_INT && opcode != POP_STRING) {
intOperands[i] = in.readInt();
} else {
intOperands[i] = in.readUnsignedByte();
}
}
return def;
}
use of net.runelite.cache.definitions.ScriptDefinition in project runelite by runelite.
the class ScriptWriter method buildScript.
public ScriptDefinition buildScript() {
ScriptDefinition script = new ScriptDefinition();
script.setId(id);
script.setIntStackCount(intStackCount);
script.setStringStackCount(stringStackCount);
script.setLocalIntCount(localIntCount);
script.setLocalStringCount(localStringCount);
script.setInstructions(opcodes.stream().mapToInt(Integer::valueOf).toArray());
script.setIntOperands(iops.stream().map(i -> i == null ? 0 : i).mapToInt(Integer::valueOf).toArray());
script.setStringOperands(sops.toArray(new String[0]));
script.setSwitches(buildSwitches());
return script;
}
use of net.runelite.cache.definitions.ScriptDefinition in project runelite by runelite.
the class AssembleMojo method execute.
@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)) {
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
File hashFile = new File(scriptDirectory, Files.getNameWithoutExtension(scriptFile.getName()) + ".hash");
if (hashFile.exists()) {
Files.copy(hashFile, new File(scriptOut, Integer.toString(script.getId()) + ".hash"));
} else if (// Scripts >=10000 are RuneLite scripts, so they shouldn't have a .hash
script.getId() < 10000) {
throw new MojoExecutionException("Unable to find hash file for " + scriptFile);
}
++count;
} catch (IOException ex) {
throw new MojoFailureException("unable to open file", ex);
}
}
log.info("Assembled " + count + " scripts");
}
use of net.runelite.cache.definitions.ScriptDefinition in project runelite by runelite.
the class ScriptSaverTest method testSave.
@Test
public void testSave() throws IOException {
Instructions instructions = new Instructions();
instructions.init();
ScriptDefinition script = new Assembler(instructions).assemble(getClass().getResourceAsStream(SCRIPT_RESOURCE));
byte[] saved = new ScriptSaver().save(script);
ScriptDefinition loadedScripot = new ScriptLoader().load(42, saved);
assertEquals(script, loadedScripot);
}
Aggregations