import requests import hashlib import os from concurrent.futures import ThreadPoolExecutor folder = 'vanilla' # source = 'https://launchermeta.mojang.com/mc/game/version_manifest.json' source = 'https://download.mcbbs.net/mc/game/version_manifest.json' # 先获取 Minecraft 的版本 versions = requests.get(source).json() # 计算要下载多少 print('Total ' + str(len(versions['versions'])) + ' versions') # 多线程异步下载 executor = ThreadPoolExecutor(max_workers=5) # 倒序 versions['versions'].reverse() # 下载所有版本的客户端 jar for version in versions['versions']: print('Downloading ' + version['id']) # 检测文件哈希 version_id = folder + '/' + version['id'] version_data = requests.get(version['url']).json() # 检测有没有 server if 'server' not in version_data['downloads']: print('Skip ' + version_id + ' (no server)') continue downloads = version_data['downloads']['server'] if os.path.exists(version_id + '.jar'): with open(version_id + '.jar', 'rb') as f: if hashlib.sha1(f.read()).hexdigest() == downloads['sha1']: print('Skip ' + version_id) continue # get file size # print(requests.head(downloads['url']).headers['Content-Length']) file_size = int(requests.head(downloads['url']).headers['Content-Length']) # print file size mb print('File size: ' + str(file_size / 1024 / 1024) + ' MB') # 多线程下载 # executor.submit(requests.get, downloads['url'], stream=True).add_done_callback( # lambda future: open(version_id + '.jar', 'wb').write(future.result().content) # ) # 单线程下载 with open(version_id + '.jar', 'wb') as f: f.write(requests.get(downloads['url'], stream=True).content) executor.shutdown()