""" This script prints a list of URLs required to download all the minecraft resources that the new launcher can access (jars, libraries, assets) Redirect stdout to a file to do something useful with it. Will store cached json indexes in versions.json versions/*.json assets/*.json Create those two directories. Deduplication: python mcresources.py | sort -t: -k2 | uniq > all_resources.txt """ import os import json import requests VERSIONS_JSON = "http://s3.amazonaws.com/Minecraft.Download/versions/versions.json" VERSION_JSON = "http://s3.amazonaws.com/Minecraft.Download/versions/%s/%s.json" ASSET_INDEX = "https://s3.amazonaws.com/Minecraft.Download/indexes/%s.json" CLIENT_JAR = "http://s3.amazonaws.com/Minecraft.Download/versions/%s/%s.jar" SERVER_JAR = "http://s3.amazonaws.com/Minecraft.Download/versions/%s/minecraft_server.%s.jar" SERVER_EXE = "http://s3.amazonaws.com/Minecraft.Download/versions/%s/minecraft_server.%s.exe" LIBRARY_JAR = "https://libraries.minecraft.net/%s/%s/%s/%s-%s.jar" NATIVE_JAR = "https://libraries.minecraft.net/%s/%s/%s/%s-%s-%s.jar" ASSET_DOWNLOAD = "http://resources.download.minecraft.net/%s/%s" ALL_OS = ['osx', 'linux', 'windows'] def print_sha(url): print(url) print(url + ".sha1") def fetch_json(url, filename): print(url) if os.path.exists(filename): return json.load(open(filename)) else: response = requests.get(url) open(filename, "w").write(response.content) return response.json() def parse_rules(rules): if not rules: return set(ALL_OS) allowed_os = set() for rule in rules: action = rule['action'] change = set() if 'os' in rule: # when filtering out versions if not (action == 'disallow' and 'version' in rule['os']): change.add(rule['os']['name']) else: change = set(ALL_OS) if action == 'allow': allowed_os |= change else: allowed_os -= change return allowed_os def parse_libraries(libs): for lib in libs: package, name, version = lib['name'].split(":") package = package.replace(".", "/") jar = LIBRARY_JAR % (package, name, version, name, version) if 'natives' in lib: allowed_os = parse_rules(lib.get('rules', [])) for os_name, value in lib['natives'].items(): if os_name not in allowed_os: continue jar = (NATIVE_JAR % (package, name, version, name, version, value)) if '${arch}' in value: for arch in ("32", "64"): jar_arch = jar.replace("${arch}", arch) print_sha(jar_arch) else: print_sha(jar) else: print_sha(jar) def get_assets(asset_types): for asset_type in asset_types: index = fetch_json( ASSET_INDEX % asset_type, "assets/%s.json" % asset_type) for i in index['objects'].values(): print(ASSET_DOWNLOAD % (i['hash'][:2], i['hash'])) def main(): all_versions_json = fetch_json(VERSIONS_JSON, "versions.json") versions = [x['id'] for x in all_versions_json['versions']] asset_types = set() for version in versions: print(CLIENT_JAR % (version, version)) print(SERVER_JAR % (version, version)) print(SERVER_EXE % (version, version)) version_json = fetch_json( VERSION_JSON % (version, version), "versions/%s.json" % version) parse_libraries(version_json['libraries']) asset_types.add(version_json.get('assets', 'legacy')) get_assets(asset_types) if __name__ == '__main__': main()