Originally a Voldeloom note

binpatches.pack.lzma

In 1.6, Forge stopped being a jarmod. Mojang was happy with this:

With the advent of the new launcher and other API stuff in the pipe, we expect the number of mods shipping base classes to drop significantly however, and Mojang has politely asked that FML and MinecraftForge, jointly the largest platform shipping base classes, to cease once the new launcher is established, a request with which I am happy to comply.

Instead, patches are done in a mildly less copyright-infringing way. The class cpw.mods.fml.common.patcher.ClassPatchManager handles the patches; setup loads them.

Overview

Unwrapping lzma

xz for Java can do it.1

Unwrapping pack200

pack200 is an obscure, complex, and highly domain-specific compression scheme for Java archives, dating back to the applet days when download sizes were a big concern. It has been removed from the jdk so you need a third party decompressor such as Apache Commons Compress.

It was not the best compression scheme to use. Most of its complexity is about ways to compress class files, not resource files like these .binpatches.

For a while commons-compress’s pack200 parser was broken, giving you errors like Failed to unpack Jar:org.apache.commons.compress.harmony.pack200.Pack200Exception: Expected to read 48873 bytes but read 3274. See https://github.com/apache/commons-compress/pull/360 . You can fix it by wrapping the input in an InputStream that returns false from markSupported, and returns any nonzero value from available, like this. The bug has been fixed so I removed the fix from voldeloom.

Unwrapping the jar

Forge reads all binpatches from ./binpatches/client/ on the physical client and ./binpatches/server on the physical server.

The other set of files is ignored.

Unwrapping the binpatch

The .binpatch file format is defined in terms of DataInputStream:

field read with
name readUTF
sourceClassName readUTF
targetClassName readUTF
exists readBoolean
checksum if “exists”, call readInt; else 0
patchLength readInt
patchBytes readFully into a buffer the size of patchLength

Applying binpatches

To apply binpatches statically, like Voldeloom does:

To apply binpatches at runtime:

Trivia

And the patch data?

It’s simply a gdiff file.


  1. Free download no virus↩︎