Created
May 19, 2025 06:26
-
-
Save Lewiscowles1986/d509fce754bfa154659a2b8e98aeaa94 to your computer and use it in GitHub Desktop.
Forgecraft-manifest-downloader PHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function relativeDirectory($path) { | |
return __DIR__ . "/" . $path; | |
} | |
$manifestPath = relativeDirectory("manifest.json"); | |
$downloadDir = relativeDirectory("mods"); | |
$userAgent = "CurseForge/Downloader+1.0"; | |
$cookieFile = relativeDirectory("cookies.txt"); // Optional. Comment this line out if not using cookies. | |
if (!file_exists($manifestPath)) { | |
die("manifest.json not found\n"); | |
} | |
$manifest = json_decode(file_get_contents($manifestPath), true); | |
if (!is_array($manifest) || !isset($manifest['files'])) { | |
die("Invalid manifest.json format\n"); | |
} | |
// Create downloads directory | |
if (!is_dir($downloadDir)) { | |
mkdir($downloadDir, 0777, true); | |
} | |
foreach ($manifest['files'] as $file) { | |
$projectID = $file['projectID']; | |
$fileID = $file['fileID']; | |
$metaUrl = "https://www.curseforge.com/api/v1/mods/$projectID/files/$fileID"; | |
$downloadUrl = "https://www.curseforge.com/api/v1/mods/$projectID/files/$fileID/download"; | |
echo "Fetching metadata for project $projectID, file $fileID...\n"; | |
$meta = curlGetJson($metaUrl, $userAgent, $cookieFile); | |
if (!$meta || !isset($meta['data']['fileName'])) { | |
echo "Failed to retrieve fileName\n"; | |
continue; | |
} | |
$fileName = $meta['data']['fileName']; | |
$outputPath = "$downloadDir/$fileName"; | |
echo "Downloading $fileName...\n"; | |
$success = curlDownload($downloadUrl, $outputPath, $userAgent, $cookieFile); | |
if ($success) { | |
echo "Downloaded to $outputPath\n"; | |
} else { | |
echo "Failed to download $fileName\n"; | |
} | |
} | |
function curlGetJson($url, $userAgent, $cookieFile = null) | |
{ | |
$ch = curl_init($url); | |
curl_setopt_array($ch, [ | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_USERAGENT => $userAgent, | |
CURLOPT_FOLLOWLOCATION => true, | |
]); | |
if ($cookieFile) { | |
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); | |
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); | |
} | |
$response = curl_exec($ch); | |
curl_close($ch); | |
return json_decode($response, true); | |
} | |
function curlDownload($url, $savePath, $userAgent, $cookieFile = null) | |
{ | |
$fp = fopen($savePath, 'w'); | |
if (!$fp) return false; | |
$ch = curl_init($url); | |
curl_setopt_array($ch, [ | |
CURLOPT_FILE => $fp, | |
CURLOPT_USERAGENT => $userAgent, | |
CURLOPT_FOLLOWLOCATION => true, | |
]); | |
if ($cookieFile) { | |
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); | |
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); | |
} | |
$success = curl_exec($ch); | |
curl_close($ch); | |
fclose($fp); | |
return $success; | |
} |
2025 may php 8.4.7 used to test this on the all the mods 10-2.47 modpack
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
relativeDirectory could change.
What Might be a better option would be to build a separate script which can do the download, and then sub-process / thread that part... IDK, I like simplicity of a <100 line file today.