Loopback Success
I had one of those geekpride moments last night when trying to deal with a problem I was having with a Minecraft server running ModLoader. Modding Minecraft is not as easy as it could be, but since it is written in Java, it is not as hard as it could be either. A number of clever folks have built compatibility layers and wrappers to improve mod maintainability and compatibility. ModLoader is one of these wrappers widgets.
Its developer recently (well, somewhat recently anyway) added a feature that would merge zipped jar like class collections from a mods subdirectory into the classpath, preventing the need to edit minecraft_server.jar for each and every mod as you had to do in the past. It loads these in “random” order, which turns out to be alphabetical on some platforms, and in less easily manipulated order on others. Linux falls into the latter category, naturally.
When I looked to fix this, my first thought was to change ModLoader’s behavior so that it always loaded in alphabetical order. This would be trivial to do if I had the source for ModLoader, but less so without it. I don’t have much experience with Java decompilers and just didn’t feel like messing with that.
Instead, I implemented a fun easy hack that anyone running Linux can do. I created a small vfat loopback filesystem for the mods subfolder. This produced the expected alphabetical loading order and took a minute or two to set up. Here’s how you do it:
First, create a zeroed out virtual “disk” file to mount, using dd.
dd if=/dev/zero of=diskimage.100mb bs=1048576 count=100
dd stands for data description, but you don’t really need to know that. It looks more complicated than it is. The if and of parameters are “in file” and “out file.” Since we want a file filled with zeroes, we use /dev/zero (a convenience “device” that returns zero) as the “in file.” Next, we have bs, for which the snarky among you will instantly have a definition in mind. However! It is actually “block size,” and determines the size of each copy block, or step in bytes. As I wanted a file that was roughly 100MB, I used the size of a megabyte here. Lastly, we have count, which simply determines the number of “bs” blocks to write. (Yes, yes, BS blocks)
Now! We have a nice empty file to use. Let’s format it. This is super easy.
mkfs.vfat diskimage.100mb
We use vfat because it is fast, simple, and Windowsy. Also, it worked.
Last step! We need to mount it. In Linux, there are no pesky drive letters. One can mount a filesystem anywhere. Everything lives as a child of root, which is simply /. So let us assume our Minecraft server lives in /home/minecraft. The mods folder needs to be /home/minecraft/mods. So create the empty folder first. (Move your existing mods folder out of the way if needed.)
mv mods mods-old (if needed)
mkdir mods
And the mount: (You need to be able to run things as sudo/root to do this. Discussions about sudo are outside of the scope of this article.)
sudo mount diskimage.100mb /home/minecraft/mods -t vfat -o loop,owner,group,umask=000
The gist of this is probably obvious. The flags tell mount the type of the filesystem and to map all the files as 777 (readable and writeable by all) since vfat does not support these things natively. It’s fine for our needs, though not secure enough for some other situations, such as a folder accessible via the web, so make sure you understand the implications of this before you use it elsewhere.
Now, you are set! You can copy your mod zip files and rename them so that they are in the order you’d like and it will Just Work(TM). Hooray!
One last thing. If you want this to mount automatically, you will need to edit /etc/fstab, adding this: (all on one line)
/home/minecraft/diskimage.100mb /home/minecraft/mods vfat loop,owner,group,umask=000 0 0
I’ll leave the details of this to you to read about. Have fun!