Skip to content

Commit

Permalink
Fetch CurseForge API key from Linux app, not macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
evan-goode committed Jun 25, 2024
1 parent c3bdc0f commit d1b018e
Showing 1 changed file with 16 additions and 18 deletions.
34 changes: 16 additions & 18 deletions launcher/net/FetchFlameAPIKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,31 @@

FetchFlameAPIKey::FetchFlameAPIKey(QObject* parent) : Task{ parent } {}

// Here, we fetch the API key from the files of the official CurseForge app. We
// use the macOS disk image (as opposed to the zipped Linux AppImage) since
// there is only one layer of DEFLATE decompression to get through. We
// range-request the specific ~500KiB zlib block from the archive.org mirror
// that contains the API key.
// Here, we fetch the official CurseForge API key from the files of the
// CurseForge app. We range-request the specific ~84KiB zlib block inside the
// AppImage's SquashFS that contains the API key and extract only that.

// Note: We need a direct link to the AppImage for this to work. The download
// link for the Linux app on CurseForge's website is to a zipped AppImage,
// which will not work here since (I think?) ZIP files typically have one
// non-chunked DEFLATE stream for each file, and there's no way to fetch a
// single, independent chunk to extract.

// See also https://git.sakamoto.pl/domi/curseme/src/commit/388ac991eb57dedd5d1aca45f418deb221d757d1/getToken.sh

const QUrl CURSEFORGE_APP_URL{
"https://web.archive.org/web/20240520233008if_/https://curseforge.overwolf.com/downloads/curseforge-latest.dmg"
"https://web.archive.org/web/20240625154807if_/https://curseforge.overwolf.com/electron/linux/CurseForge-0.198.1-21.AppImage"
};

// To find these offsets:
// 1. Download the disk image from CURSEFORGE_APP_URL and run
// dmg2img -V ./curseforge-latest.dmg
// 2. Use a hex editor to find the address of the string "cfCoreApiKey" inside
// curseforge-latest.img.
// 3. In the output of `dmg2img -V`, find the `in_addr`, the `in_size`, and the
// ` out_size` of the block that contains this address.

const uint32_t IN_ADDR{ 4640617 };
const uint32_t IN_SIZE{ 511977 };
const uint32_t OUT_SIZE{ 1048576 };
// Use https://github.com/unmojang/appimage-token-finder to find these offsets
const uint32_t IN_ADDR{ 82926761 };
const uint32_t IN_SIZE{ 84196 };
const uint32_t OUT_SIZE{ 131072 };

void FetchFlameAPIKey::executeTask()
{
QNetworkRequest req{ CURSEFORGE_APP_URL };
// Request only a single block of the disk image file
// Request only a single zlib block from inside the AppImage file
const auto& rangeHeader = QString("bytes=%1-%2").arg(IN_ADDR).arg(IN_ADDR + IN_SIZE);
req.setRawHeader("Range", rangeHeader.toUtf8());

Expand Down

0 comments on commit d1b018e

Please sign in to comment.