/ Vertigo
Created 2019-04-19 Modified 2019-04-19

1062 Words

Saving Jagex’s Vertigo

Originally posted on 2019-04-19.

This week I was aiming to work on the actual code base of FPL and adding a new feature - a Save manager to backup and restore files. As I mentioned last time, the application is built on Electron, using Typescript and leveraging the use of React to deliver component-based modules.

Setting up FPL was very pleasant - it was primarily built by obelisk, the main mechanic on the Flashpoint team. I will keep mentioning the fact that I am an abused Windows developer until the end of time - FPL was primarily made for Windows so the development environment was much more favourable.

Some issues that arose:

  • The games didn’t show up anywhere. This was fixed by going into configs and pointing at a consumer installation of Flashpoint (Ultimate or Infinity)
  • The images and playlists didn’t show up. Had to change config.json to this:
"imageFolderPath": "Images",
"jsonFolderPath": "Data",
"logoFolderPath": "Logos",
"playlistFolderPath": "Playlists"
  • Redirector didn’t show up Fixed by copying services.json into the consumer Flashpoint’s Data folder

Side Tracking from the Save Manager

The internal documentation is still a Work in Progress. So, a lot of inferring and questioning needed to be done.

As I was resolving build issues, I would take a break and resume doing some curation. I haven’t mentioned all my curations (since Pebble’s Quarry, I’ve also resurrected Postopia adventure and was working with an FPL colleague to restore more of them). I also tried to resurrect Waffle boy’s mountain adventure, famously lost in our community. I managed to partially recreate the missing XML (that loads the separate Flash SWFs properly) to play the first level, but beyond that I couldn’t resolve it.

So, I decided to curate an old Java applet game from freearcade.com that I used to play back in the day. It was a game called Vertigo, from 1999, made by Andrew Gower of RuneScape fame. I mistakenly assumed that it would be as easy as the few that I did after my first one.

Issue:

Get Vertigo to work on Flashpoint since it no longer works on the browser.

Problems (If you want the solution, scroll down):

  • Going the traditional route of setting up the files ended with no Flashpoint redirector complaints. I needed something to error out so I would understand the problem, so I directly went to the JDK and used appletviewer.exe directly with my embedded html and class file. That threw me this error:
java.lang.ClassFormatError: Name index 0 in LocalVariableTable has bad constant type in class file vertigo
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at sun.applet.AppletClassLoader.findClass(AppletClassLoader.java:217)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.applet.AppletClassLoader.loadClass(AppletClassLoader.java:152)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at sun.applet.AppletClassLoader.loadCode(AppletClassLoader.java:626)
        at sun.applet.AppletPanel.createApplet(AppletPanel.java:799)
        at sun.applet.AppletPanel.runLoader(AppletPanel.java:728)
        at sun.applet.AppletPanel.run(AppletPanel.java:378)
        at java.lang.Thread.run(Thread.java:748)

Here’s where my detour started - everything I read online mentioned that it was incompatibility between an older version of Java versus a newer one. Using this command in Bash, I can get the major version (which tells the user which JDK version was used to compile the file):

$ od --format=d1 vertigo.class -j 7 -N 1
 0000007   45   0000010

The middle number (45) indicated the version. Here’s a table of JDK versions and their respective major versions:

Java Version Major Version
1.1 45
1.2 46
1.3 47
1.4 48
5 49
6 50
7 51
8 52
9 53
10 54
11 55

Clearly this game was made with one of the earliest possible JDKs - 1.1.

  • My approach went like this (which was incorrect) - Download JDK 1.1.X version from the Oracle archives.
  • Turns out the original JDK was a 16-bit program so installation was blocked by this error: Unsupported 16-Bit Application.
    That’s when I learned the Win10 x64 architecture completely dropped 16 bit support (another indication of how old programs lose support after some time). So:
  • Spun up a Windows 7 x32 virtual machine
  • Installed it successfully there
  • Sent the extracted files back to my host
  • Modified the startJava.bat located in Flashpoint to point at the new, ancient JDK and ran the game
  • Finally I was able to get useful asset GET requests through the redirector! I collected the files that way.
  • An issue with bad class file format showed up - apparently the wrapper.class was made with major version 48 instead of 45, so I re-hunted for the files via Wayback
  • Finally, after all of that hard work, this was the result:

Demo3

It was throwing an array out of bounds and pulling in the wrong assets.

  • The only lead I had there was after using javap to decompile the class files, there were errors with the encoding, and it gave me nonsense unicode

Encoding

  • At this point I was giving up - learning ancient encoding to translate the code into something that made sense was, the first cardinal sin of troubleshooters, going way too complicated for a solution

Solution:

  • Gave up and asked the Java experts on the Flashpoint discord
  • nosamu pointed me to Strawrat, a skilled Java expert who had reverse engineered Java applets before
  • Within ten minutes, the problem that had been plaguing me for days had been resolved

Instead, Strawrat started at that very first problem all the way back at the beginning -

java.lang.ClassFormatError: Name index 0 in LocalVariableTable has bad constant type in class file vertigo

Here’s how they did it:

  • Use a Java .class file editor - Dirty Joe This one in particular doesn’t crash with really old Java class files
  • Open the Vertigo asset classes in the program
  • Hit the Methods tab, it will show a list of methods in that class. The first one should be selected.
  • In the panel on the right that says Attributes, click on Code. That should open up a new window that has a bunch of stuff (Max Stack, Attributes, Exceptions, etc)
  • Right click on LocalVariableTable and select Delete Attribute
  • The close that window and save the class file

Here’s a demonstration:

demo4

Apparently LocalVariableTable in the class file was broken and needed to be deleted - it’s considered optional, similar to LineNumberTable.

This answer was so beyond my expertise that I knew I would have never figured it out on my own.

I’m very greatful to the FPL community for their expertise and wizard-like reverse-engineering.

You can see the game in FPL 6.0 or download Vertigo here!