Skip to content

Instantly share code, notes, and snippets.

@Demindiro
Last active July 18, 2022 22:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Demindiro/7a65b70f4716bd59bb2a232ffb117f54 to your computer and use it in GitHub Desktop.
Save Demindiro/7a65b70f4716bd59bb2a232ffb117f54 to your computer and use it in GitHub Desktop.
Mods downloader for CurseForge modpacks. CC0 so dowhatever you want
# Hacky script because I can't be arsed with both CF's bullshit
# Instructions:
# - Download modpack from CurseForge's website
# - Unzip
# - Run this script in the unzipped folder (manifest.json and modlist.html should be present)
# - Copy mods/ (& overrides/ maybe) folder wherever
import json, os, cloudscraper
try:
os.mkdir('mods')
except:
pass
manifest = json.load(open("manifest.json"))
requests = cloudscraper.create_scraper() # Fuck you Cloudflare
for l in open("modlist.html").readlines():
if not 'href="' in l:
continue
url = l.split('href="')[1].split('">')[0] # Easier IMO
print('fetching', url)
r = requests.get(url)
if r.status_code != 200:
print('failed to fetch', url, 'code', r.status_code)
continue
for f in manifest['files']:
if 'data-project-id="' + str(f['projectID']) + '"' in r.text:
url += '/download/' + str(f['fileID']) + '/file'
print('downloading', url)
# https://stackoverflow.com/a/16696317
with requests.get(url, stream = True) as r:
file_url = r.history[-1].url
print('final url:', file_url)
file_name = file_url.split('?')[0].split('/')[-1]
print('filename :', file_name)
r.raise_for_status()
r_len = int(r.headers['content-length'])
r_dl = 0
with open('mods/' + file_name, 'wb') as f:
for c in r.iter_content(chunk_size = 1 << 18):
r_dl += len(c)
print('%d / %d (%.1f%%)' % (r_dl, r_len, r_dl * 100 / r_len))
f.write(c)
break
else:
print('no matching project ID found')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment