A Bash script to download ROMs from Vimm's Lair with MD5 integrity verification intended for your RomM Library.
This script is intended only to download a game you like directly to your own server, because you do not have a graphical interface.
It is not meant to attack, scrape, automate in bulk, or otherwise hammer Vimm's API.
The current design, because of Vimm's bot protection and my own principles, only works with a valid session on a real browser, passing the bot protection in a legitimate way and getting the provided data.
Vimm's Lair serves ROMs through a vault page that points to a dedicated download server URL (dlX.vimm.net). This script automates the whole flow:
- Asks the user for the download server ID and the download server game ID.
- Resolves the download URL and reads the file name and size from the HTTP headers.
- Lets you pick a target platform from your local ROM library.
- Downloads the file with a progress bar.
- Streams the ROM files through a pipeline (never writing anything to disk) and verifies each one's MD5 against Vimm's official hash (multi-file ROMs like PSX .bin/.cue are fully supported) and keeps only the compressed file.
You have a ROM library organized by platform (e.g. /home/user/emu/library/roms/n64). You find the game you want on Vimm's Lair, inspect the download button and get the server and new game IDs:
<form action="//dl3.vimm.net/" method="POST" id="dl-form" onsubmit="return submitDL(this, 'dialog3')">
<input type="hidden" name="alt" value="0" disabled="">
<input type="hidden" name="mediaId" value="3329">
<button type="submit" style="width:100%">Download</button>
</form>In this case
3and3329
Then run:
./vimm-downloader.shThe script will:
╔═══════════════════════════════════╗
║ Vimm's Downloader ║
╚═══════════════════════════════════╝
# Input download server ID: 3
# Input download server game ID: 30832
# Does the game have different formats? (y/n): y
# Input the format number selected (0, 1, 2...): 2
# Format 2 selected
# Fetching game information from https://dl3.vimm.net/?alt=2&mediaId=30832...
# Legend of Zelda, The - The Wind Waker (Europe) (En,Fr,De,Es,It).7z 718MiB
# These are your current platforms:
3ds gb gba n64
nds nes new-nintendo-3ds ngc
nintendo-dsi ps2 psx switch
# Select the platform: ngc
# Downloading Legend of Zelda, The - The Wind Waker (Europe) (En,Fr,De,Es,It).7z...
718MiB/718MiB [==========================================>] 100% [8.46MiB/s]
# Calculating hash for Legend of Zelda, The - The Wind Waker (Europe) (En,Fr,De,Es,It).rvz...
# Calculated hash is 5395ed04c9441e86c2237a64cc41c352
# Expected hash is empty
# They don't match!
# Bye bye!
For Game Cube games the provided hash is for the .iso file so, in this case, they do not match.
The script relies on the following programs being installed and available in PATH, most of them are preinstalled:
| Tool | Used for |
|---|---|
curl |
Fetching pages, headers and downloading. |
grep |
Extracting headers, hashes and formatting lines. |
7z |
Reading .7z and .zip files. |
numfmt |
Formatting file size in human-readable units (MiB). |
pv |
Progress bar during the download. |
md5sum |
Computing the MD5 hash of the extracted ROM. |
cut |
Isolating the MD5 value from md5sum output. |
tail |
Splitting the HTTP code from the response dump. |
sed / xargs |
Output formatting. |
ls |
Listing directories to show available platforms. |
Note:
grepmust support the-Poption.
Edit the variable at the top of the script to point to your ROM library:
BASE_DIR="/path/to/library/roms"The script is tailored to Vimm's Lair as it exists today. It assumes:
- Hash file format is strict:
MD5:followed by 32 hex characters on the same line, inside theVimm's Lair.txtfile that ships with the archive. Variations likemd5:,MD5 =are not supported as they are not expected. - No session cookie required: the download server answers without any session cookie.
- Only for .zip and .7z:
7zis used and does not test for other filetypes. - One MD5 entry per media file: Vimm's Lair.txt lists (sometimes it does, sometimes it doesn't) the MD5 of each file inside the archive.
- Designed for a RomM library: the script assumes the RomM server folder structure:
BASE_DIRcontains one subdirectory per platform (RomM collection) and the names of these platforms contain no spaces. BASE_DIRexists and is writable: both it and its platform subdirectories require read/write permissions (of course right?).