package net.scapeemulator.cache.tools; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.HashMap; import java.util.Map; import net.scapeemulator.cache.Cache; import net.scapeemulator.cache.Container; import net.scapeemulator.cache.FileStore; import net.scapeemulator.cache.ReferenceTable; import net.scapeemulator.cache.ReferenceTable.Entry; import net.scapeemulator.cache.def.ClientScript; public final class ClientScriptDumper { private static final Map<Integer, String> opcodes = new HashMap<>(); static { opcodes.put(0, "pushi"); opcodes.put(1, "pushi_cfg"); opcodes.put(2, "popi_cfg"); opcodes.put(3, "pushs"); opcodes.put(6, "goto"); opcodes.put(7, "if_ne"); opcodes.put(8, "if_eq"); opcodes.put(9, "if_lt"); opcodes.put(10, "if_gt"); opcodes.put(21, "return"); opcodes.put(25, "pushi_varbit"); opcodes.put(26, "popi_varbit"); opcodes.put(31, "if_lteq"); opcodes.put(32, "if_gteq"); opcodes.put(33, "loadi"); opcodes.put(34, "storei"); opcodes.put(35, "loads"); opcodes.put(36, "stores"); opcodes.put(37, "concat_str"); opcodes.put(38, "popi"); opcodes.put(39, "pops"); opcodes.put(40, "call"); opcodes.put(42, "loadi_global"); opcodes.put(43, "storei_global"); opcodes.put(44, "dim"); opcodes.put(45, "push_array"); opcodes.put(46, "pop_array"); opcodes.put(47, "loads_global"); opcodes.put(48, "stores_global"); opcodes.put(51, "switch"); opcodes.put(100, "new_dyn_comp"); opcodes.put(101, "dlt_dyn_comp"); opcodes.put(102, "dlt_dyn_comps"); opcodes.put(200, "set_active_component"); opcodes.put(404, "set_local_player_color"); opcodes.put(410, "set_local_player_gender"); opcodes.put(1000, "set_dyn_comp_position"); opcodes.put(1003, "set_dyn_comp_hidden"); opcodes.put(1005, "set_dyn_comp_image"); opcodes.put(1101, "set_dyn_comp_color"); opcodes.put(1103, "set_dyn_comp_alpha"); opcodes.put(1200, "display_item_on_dyn_comp"); opcodes.put(1205, "display_item_on_dyn_comp2"); opcodes.put(1300, "set_dyn_comp_option"); opcodes.put(1301, "set_dyn_comp_parent"); opcodes.put(1408, "set_dyn_comp_loop_script"); opcodes.put(2000, "set_static_comp_position"); opcodes.put(2003, "set_static_comp_hidden"); opcodes.put(2005, "set_static_comp_image"); opcodes.put(2101, "set_static_comp_color"); opcodes.put(2103, "set_static_comp_alpha"); opcodes.put(2200, "display_item_on_static_comp"); opcodes.put(2205, "display_item_on_static_comp2"); opcodes.put(2300, "set_static_comp_option"); opcodes.put(2301, "set_static_comp_parent"); opcodes.put(2408, "set_static_comp_loop_script"); opcodes.put(2704, "is_opened"); opcodes.put(2705, "is_opened"); // Client allows for two cases opcodes.put(3300, "pushi_lcycle"); opcodes.put(3301, "pushi_itemid"); opcodes.put(3302, "pushi_itemamt"); opcodes.put(3303, "pushi_amtincontainer"); opcodes.put(3304, "pushi_containersize"); opcodes.put(3313, "pushi_temp_itemid"); opcodes.put(3314, "pushi_temp_itemamt"); opcodes.put(3315, "pushi_temp_amtincontainer"); opcodes.put(3316, "pushi_rights"); opcodes.put(3400, "pushs_cs2constant"); opcodes.put(3408, "pusho_cs2constant"); opcodes.put(4000, "iadd"); opcodes.put(4001, "isub"); opcodes.put(4002, "imult"); opcodes.put(4003, "idiv"); opcodes.put(4106, "pushs_i2str"); opcodes.put(4200, "pushs_itemname"); } public static void main(String[] args) throws IOException { PrintStream newStream = new PrintStream(new FileOutputStream(new File("./data/game/dumps/scripts"))); System.setOut(newStream); try (Cache cache = new Cache(FileStore.open("./data/game/cache/"))) { ReferenceTable rt = ReferenceTable.decode(Container.decode(cache.getStore().read(255, 12)).getData()); for (int id = 0; id < rt.capacity(); id++) { Entry entry = rt.getEntry(id); if (entry == null) { continue; } ClientScript script = ClientScript.decode(cache.read(12, id).getData()); System.out.println("===== script " + id + " ======"); System.out.println("iargs: " + script.getIntStackDepth() + ", sargs: " + script.getStrStackDepth()); for (int op = 0; op < script.getLength(); op++) { int opcode = script.getOpcode(op); String str = script.getStrOperand(op); int val = script.getIntOperand(op); String name = opcodes.get(opcode); if (name == null) { name = "opcode: " + opcode; } String param = str != null ? str : Integer.toString(val); if (name.equals("pushi")) { switch (val) { case 0x80000001: param = "mouse_x"; break; case 0x80000002: param = "mouse_y"; break; case 0x80000003: param = "component_hash"; break; case 0x80000004: param = "option_id"; break; case 0x80000005: param = "component_dyn_id"; break; case 0x80000006: param = "secondary_comp_hash"; break; case 0x80000007: param = "secondary_comp_dynid"; break; case 0x80000008: param = "keycode"; break; case 0x80000009: param = "keychar"; break; default: if ((val >> 16) != 0 && (val & 0xffff) <= 256 && val != 0xffffffff) { param = "id: " + (val >> 16) + ", comp: " + (val & 0xffff) + ""; } break; } } System.out.println(op + " " + name + " " + param); } System.out.println(); } } } }