How to extract/download an in-memory object from running javascript

Discussion in 'Programming & Software Development' started by elvis, Aug 24, 2020.

  1. elvis

    elvis Old school old fool

    Joined:
    Jun 27, 2001
    Messages:
    42,789
    Location:
    Brisbane
    I have no idea if I'm even describing this problem clearly, or if this is the right place to ask, but here goes.

    I've compiled the software emulator MAME into its ECMAScript target, and am loading it in a web browser via Emularity: https://github.com/db48x/emularity

    This requires passing a number of files into cache for the emulator to run. Everything's working well. My emulated system fires up, all disk and tape images load, and the system runs as expected.

    Loading a tape image requires lengthy commands and a 3 minute wait for the emulated tape to run in realtime. What I want to do is take a "save state" which normally saves a file to disk. In this case, the file is saved to memory inside the browser, and doesn't even appear to flush to disk (digging through my browser's cache folder, I can't see it in amongst all of the other files that were downloaded and cached by the browser, which includes things like the emulated system BIOS, tape image wav file, and other things I load in at run time).

    I can do this on a locally compiled and run copy of MAME, however when I load that save state into the ECMAScript/browser version it complains the save state is corrupt. I can only assume the way the x86 compiled version and ECMAscript/JVM versions store this data are incompatible, hence what I'm trying to do here.

    I know the expected file name (it'll be called "1.sta"). How do I extract this from the browser's memory and save it locally as a file? I've jumped into the Chrome dev console and had a quick look around, and while I can see all of the .js files, I can't see any of the cached objects they're using. Is there a simple enough way to pluck these out?
     
  2. teej

    teej Member

    Joined:
    Sep 18, 2009
    Messages:
    72
    Have you had a look through the Application -> Storage section of Chrome's dev tools? It looks like it might be using IndexedDB.
     
    elvis likes this.
  3. OP
    OP
    elvis

    elvis Old school old fool

    Joined:
    Jun 27, 2001
    Messages:
    42,789
    Location:
    Brisbane
    Ah yup, I can see entries being added to the IndexedDB as I add new save states, and the byte array is about the expected size. Cool.

    Is there a way to retrieve these? They're binary information, so it would be good if I could grab an entry as-is. Chrome Dev tools guides suggest constructing a Snippet to write a query and pull that info out. Would that be the next step?
     
  4. teej

    teej Member

    Joined:
    Sep 18, 2009
    Messages:
    72
    I don't really know what the best approach is. I did have a poke at archive.org's install, and there the file system is exposed as a global under 'FS'. If that's not a modification specific to their setup, on the console tab of Chrome's dev tools you should be able to dump a file as base64 with:
    Code:
    btoa(Array.from(FS.readFile("/path/to/file")))
    
    Doing the reverse would be:
    Code:
    FS.writeFile("/path/to/file", atob(b64))
    
    Hopefully someone more familiar with the web platform can give you some better advice.
     
    elvis likes this.
  5. OP
    OP
    elvis

    elvis Old school old fool

    Joined:
    Jun 27, 2001
    Messages:
    42,789
    Location:
    Brisbane
    Thank you for the pointers, this lead me to where I wanted to go.

    The internal file system represents the file I want as "/emulator/1.sta". Using the above and some generic blob download code, this gets me the file I want, saved locally:

    Code:
    var sampleBytes = FS.readFile("/emulator/1.sta");
    var saveByteArray = (function () {
        var a = document.createElement("a");
        document.body.appendChild(a);
        a.style = "display: none";
        return function (data, name) {
            var blob = new Blob(data, {type: "octet/stream"}),
                url = window.URL.createObjectURL(blob);
            a.href = url;
            a.download = name;
            a.click();
            window.URL.revokeObjectURL(url);
        };
    }());
    saveByteArray([sampleBytes], '1.sta');
    
    Much appreciated!
     
    Last edited: Aug 28, 2020
    teej and yoink like this.
  6. OP
    OP
    elvis

    elvis Old school old fool

    Joined:
    Jun 27, 2001
    Messages:
    42,789
    Location:
    Brisbane
    In case anyone was wondering what the hell I was trying to achieve:

    This emulates a Sega SC-3000 home computer. Playing a game requires a 3 minute tape load with lots of complex commands. The above lets me load a memory save state so all you have to do is hit the enter key, and you're off and running.

    https://stickfreaks.com/emularity/sc3000_vortex_blaster.html
     
    teej likes this.

Share This Page

Advertisement: