A Weird Imagination

Extracting Tametsi puzzles in the browser

Posted in

The problem#

Previously, I figured out how to extract Tametsi's puzzles, but I wanted to make something user-friendly that made use of those puzzles, so I didn't want to require people to install something or run console commands. I had also figured out how to get Java programs running in a browser, so I figured it would be straightforward to combine the two. As you may have guessed from this paragraph being in the "the problem" section, it was not. Specifically, while the Java command-line will read tametsi.exe as a JAR file, Doppio gives the error

Invalid Zip file: Central directory record has invalid signature

The solution#

As a workaround, use a different library to unzip tametsi.exe. There's no need to present it as a JAR file instead of a directory, so no need to rezip it:

var fs = BrowserFS.BFSRequire("fs");

async function unzipToDirectory(zipfile, dir) {
  const z = new zip.fs.FS();
  await z.importBlob(zipfile);

  async function extract(z, dir) {
    fs.mkdir(dir, true)
    if (z.directory) {
      const childDir = z.name
        ? `${dir}/${z.name}`
        : dir;
      for (const child of z.children) {
        await extract(child, childDir);
      }
    } else {
      fs.writeFileSync(
        `${dir}/${z.name}`,
        new buffer(await (await z.getBlob()).arrayBuffer()));
    }
  }

  await extract(z.root, dir);
}

To call that, in the uploadFile() function, replace the reader.onload with

await unzipToDirectory(f, process.cwd() + '/tametsi');

The details#

Read more…

Running Java in JavaScript

Posted in

The problem#

Java and JavaScript are insufficiently easily confused. I had some code I wanted to run on the user's computer and not the server, and it specifically had to be in Java to reference a library written in Java. I found1 Doppio, a JVM written in TypeScript, but it had bitrotted enough that I was having trouble getting it to run, despite confirming it did what I wanted using the official demo, which provides an in-browser console-like interface.

The solution#

I was able to piece together a working simple page using Doppio, modified from the official example. It's in a repository on GitHub and should be straightforward to modify for your needs.

The details#

Read more…

Extracting Tametsi puzzles

The problem#

Tametsi (available on Steam1) is a great logic puzzle game that is a collection of Minesweeper puzzles that can be solved without guessing. The game consists of 100 puzzles plus 60 "bonus" puzzles. The bonus puzzles are in the game directory in an XML-based format that another player has documented well enough that they have even created some puzzles of their own and a viewer for those files. But the base 100 puzzles are nowhere to be found in the puzzle directory, and I had ideas for doing something with them.

The solution#

Given the file DumpPuzzles.java:

public class DumpPuzzles {
    public static void main(String[] args) {
        // Loading puzzles sets the graph on
        //  Game's MouseHandler, so it has to exist.
        game.Game.mh = new io.MouseHandler(null);

        for (int i = 1; i <= 111; i++) {
            puzzle.PuzzleOut.writePuzzle(
                new puzzle.Puzzle(i),
                String.format("puzzle_%03d.puz", i));
        }
    }
}

put it in the same directory as tametsi.exe2 and run

$ javac -classpath tametsi.exe DumpPuzzles.java 
$ java -classpath tametsi.exe:. DumpPuzzles

Then the puzzles/ directory will be full of files named puzzle_001.puz, etc.

The details#

Read more…