diff options
| author | Sefa Eyeoglu <contact@scrumplex.net> | 2022-04-02 19:35:02 +0200 |
|---|---|---|
| committer | Sefa Eyeoglu <contact@scrumplex.net> | 2022-04-05 14:35:07 +0200 |
| commit | 2ca56cafdf767c32fd8397bc4089c1e8513272d5 (patch) | |
| tree | 42daeedfe76da8dec9d7e92f9e74076ef5c82d7a | |
| parent | 5895e5accfbb1268500f9dd35003abf207a548c8 (diff) | |
| download | Project-Tick-2ca56cafdf767c32fd8397bc4089c1e8513272d5.tar.gz Project-Tick-2ca56cafdf767c32fd8397bc4089c1e8513272d5.zip | |
refactor: move generateMojang to pydantic models
| -rwxr-xr-x | generateMojang.py | 379 | ||||
| -rwxr-xr-x | index.py | 3 | ||||
| -rw-r--r-- | meta/common/__init__.py | 5 | ||||
| -rw-r--r-- | meta/common/mojang.py | 6 | ||||
| -rw-r--r-- | meta/metautil.py | 169 | ||||
| -rw-r--r-- | meta/model/__init__.py | 42 | ||||
| -rw-r--r-- | meta/model/mojang.py | 140 | ||||
| -rw-r--r-- | static/mojang/minecraft-experiments.json | 40 | ||||
| -rw-r--r-- | static/mojang/minecraft-legacy-override.json (renamed from static/minecraft.json) | 0 | ||||
| -rwxr-xr-x | updateMojang.py | 32 |
10 files changed, 397 insertions, 419 deletions
diff --git a/generateMojang.py b/generateMojang.py index dd3b712cd7..9cd17ff969 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -1,24 +1,31 @@ import copy import hashlib +import os from collections import defaultdict, namedtuple -from operator import itemgetter +from operator import attrgetter from pprint import pprint +from typing import Optional -from meta.metautil import * from meta.common import ensure_component_dir, polymc_path, upstream_path +from meta.common.mojang import VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, LWJGL_COMPONENT, \ + STATIC_OVERRIDES_FILE, VERSIONS_DIR +from meta.model import MetaVersionFile, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ + MetaPackageData, MojangRules +from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersionFile, LegacyOverrideIndex +from updateMojang import STATIC_DIR PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() -ensure_component_dir("net.minecraft") -ensure_component_dir("org.lwjgl") -ensure_component_dir("org.lwjgl") +ensure_component_dir(MINECRAFT_COMPONENT) +ensure_component_dir(LWJGL_COMPONENT) +ensure_component_dir(LWJGL3_COMPONENT) def map_log4j_artifact(version): if version == "2.0-beta9": - return ("2.0-beta9-fixed", "https://polymc.github.io/files/maven/%s") - return ("2.17.1", "https://repo1.maven.org/maven2/%s") # This is the only version that's patched (as of 2022/02/19) + return "2.0-beta9-fixed", "https://polymc.github.io/files/maven/%s" + return "2.17.1", "https://repo1.maven.org/maven2/%s" # This is the only version that's patched (as of 2022/02/19) LOG4J_HASHES = { @@ -49,55 +56,48 @@ LOG4J_HASHES = { } # LWJGL versions we want -passVariants = [ - "41d3ed7a755d15ad9e2f5a8aea51481858d60763", # 3.2.2 (2021-12-10 03:36:38+00:00) - "57455f0bb479e07e5b554766f9f0310a6c245e10", # 3.1.2 (2018-06-21 12:57:11+00:00) - "abfbb7905498983ab3300ae2b897ccd3c11ab8bb", # 2.9.0 (2013-10-21 16:34:47+00:00) - "47fd9d3677d7a0bcdb280453a7e7ac1fdbdab70d", # 2.9.4-nightly-20150209 (2016-12-20 14:05:34+00:00) - "8ee2407d76c3af7882ab897b6ef25392839d2ab0", # 3.1.6 (2019-04-18 11:05:19+00:00) - "428282d96ee546aae07d0717fef71ab8213d1176", # 3.2.1 (2019-04-18 11:05:19+00:00) - "c7a84795ac3197bb476949665f3eda9c79436cf7", # 2.9.1 (2014-05-22 14:44:33+00:00) - "66a60d78abe20960f1befd0fd5819a8855100055", # 2.9.1-nightly-20131120 (2013-12-06 13:55:34+00:00) - "15a92ddad26186e720117fc0e318c6ddb8bae14e", # 2.9.3 (2015-01-30 11:58:24+00:00) +PASS_VARIANTS = [ + "d986df9598fa2bcf4a5baab5edf044548e66d011", # 3.2.2 (2021-12-10 03:36:38+00:00) + "5a006b7c72a080ac673fff02b259f3127c376655", # 3.1.2 (2018-06-21 12:57:11+00:00) + "f04052162b50fa1433f67e1a90bc79466c4ab776", # 2.9.0 (2013-10-21 16:34:47+00:00) + "a3f254df5a63a0a1635755733022029e8cfae1b3", # 2.9.4-nightly-20150209 (2016-12-20 14:05:34+00:00) + "65b2ce1f2b869bf98b8dd7ec0bc6956967d04811", # 3.1.6 (2019-04-18 11:05:19+00:00) + "8bde129ef334023c365bd7f57512a4bf5e72a378", # 3.2.1 (2019-04-18 11:05:19+00:00) + "8d4951d00253dfaa36a0faf1c8be541431861c30", # 2.9.1 (2014-05-22 14:44:33+00:00) + "cf58c9f92fed06cb041a7244c6b4b667e6d544cc", # 2.9.1-nightly-20131120 (2013-12-06 13:55:34+00:00) + "879be09c0bd0d4bafc2ea4ea3d2ab8607a0d976c", # 2.9.3 (2015-01-30 11:58:24+00:00) ] # LWJGL versions we def. don't want! -badVariants = [ - "089446ef48f6ac70a3e2bc4a02cd1f34060d31bd", # 3.2.2 (2021-08-25 14:41:57+00:00) - "6a0aaa55846ebccae9cf69e1ac2e284b3f0d81d0", # 3.2.2 (2019-07-19 09:25:47+00:00) - "e3ecb31817e009ebfb3a8ed41b7b779d31e55b43", # 3.2.2 (2019-07-04 14:41:05+00:00) - "2d0b7aa8397278c5b5f7e9cd025544af5e820072", # 2.9.0 (2013-09-06 12:31:58+00:00) - "905c3a9d80a804c2d03a577775b75f45c1837263", # 2.9.0 (2011-03-30 22:00:00+00:00) - "d889b127fbabd3493115beb228730146072549a4", # 3.1.6 (2018-11-29 13:11:38+00:00) - "0034e86cec334f9142ca4ace843c91eb649017fd", # 3.2.1 (2019-02-13 16:12:08+00:00) +BAD_VARIANTS = [ + "4b73fccb9e5264c2068bdbc26f9651429abbf21a", # 3.2.2 (2021-08-25 14:41:57+00:00) + "ab463e9ebc6a36abf22f2aa27b219dd372ff5069", # 3.2.2 (2019-07-19 09:25:47+00:00) + "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) + "27dcadcba29a1a7127880ca1a77efa9ece866f24", # 2.9.0 (2013-09-06 12:31:58+00:00) + "6442fc475f501fbd0fc4244fd1c38c02d9ebaf7e", # 2.9.0 (2011-03-30 22:00:00+00:00) + "7ed2372097dbd635f5aef3137711141ce91c4ee9", # 3.1.6 (2018-11-29 13:11:38+00:00) + "8e1f89b96c6f583a0e494949c75115ed13412ba1", # 3.2.1 (2019-02-13 16:12:08+00:00) ] -def addOrGetBucket(buckets, rules): - ruleHash = None +def add_or_get_bucket(buckets, rules: Optional[MojangRules]) -> MetaVersionFile: + rule_hash = None if rules: - ruleHash = hash(json.dumps(rules.to_json())) + rule_hash = hash(rules.json()) - bucket = None - if ruleHash in buckets: - bucket = buckets[ruleHash] + if rule_hash in buckets: + bucket = buckets[rule_hash] else: - bucket = PolyMCVersionFile( - { - "name": "LWJGL", - "version": "undetermined", - "uid": "org.lwjgl" - } - ) + bucket = MetaVersionFile(name="LWJGL", version="undetermined", uid=LWJGL_COMPONENT) bucket.type = "release" - buckets[ruleHash] = bucket + buckets[rule_hash] = bucket return bucket -def hashVersion(lwjgl): - lwjglObjectCopy = copy.deepcopy(lwjgl) - lwjglObjectCopy.releaseTime = datetime.datetime.fromtimestamp(0) - return hashlib.sha1(json.dumps(lwjglObjectCopy.to_json(), sort_keys=True).encode("utf-8", "strict")).hexdigest() +def hash_lwjgl_version(lwjgl: MetaVersionFile): + lwjgl_copy = copy.deepcopy(lwjgl) + lwjgl_copy.release_time = None + return hashlib.sha1(lwjgl_copy.json().encode("utf-8", "strict")).hexdigest() def sort_libs_by_name(library): @@ -109,30 +109,30 @@ LWJGLEntry = namedtuple('LWJGLEntry', ('version', 'sha1')) lwjglVersionVariants = defaultdict(list) -def addLWJGLVersion(versionVariants, lwjglObject): - lwjglObjectCopy = copy.deepcopy(lwjglObject) - libraries = list(lwjglObjectCopy.libraries) +def add_lwjgl_version(variants, lwjgl): + lwjgl_copy = copy.deepcopy(lwjgl) + libraries = list(lwjgl_copy.libraries) libraries.sort(key=sort_libs_by_name) - lwjglObjectCopy.libraries = libraries + lwjgl_copy.libraries = libraries - lwjglVersion = lwjglObjectCopy.version - lwjglObjectHash = hashVersion(lwjglObjectCopy) + version = lwjgl_copy.version + current_hash = hash_lwjgl_version(lwjgl_copy) found = False - for variant in versionVariants[lwjglVersion]: + for variant in variants[version]: existingHash = variant.sha1 - if lwjglObjectHash == existingHash: + if current_hash == existingHash: found = True break if not found: - print("!!! New variant for LWJGL version %s" % (lwjglVersion)) - versionVariants[lwjglVersion].append(LWJGLEntry(version=lwjglObjectCopy, sha1=lwjglObjectHash)) + print("!!! New variant for LWJGL version %s" % (version)) + variants[version].append(LWJGLEntry(version=lwjgl_copy, sha1=current_hash)) def removePathsFromLib(lib): - if pmcLib.downloads.artifact: - pmcLib.downloads.artifact.path = None - if pmcLib.downloads.classifiers: - for key, value in pmcLib.downloads.classifiers.items(): + if lib.downloads.artifact: + lib.downloads.artifact.path = None + if lib.downloads.classifiers: + for key, value in lib.downloads.classifiers.items(): value.path = None @@ -157,50 +157,97 @@ def adaptNewStyleArguments(arguments): return ' '.join(outarr) -def isOnlyMacOS(rules, specifier): - allowsOSX = False - allowsAll = False +def is_macos_only(rules: Optional[MojangRules], specifier): + allows_osx = False + allows_all = False # print("Considering", specifier, "rules", rules) if rules: for rule in rules: if rule.action == "allow" and rule.os and rule.os.name == "osx": - allowsOSX = True + allows_osx = True if rule.action == "allow" and not rule.os: - allowsAll = True - if allowsOSX and not allowsAll: + allows_all = True + if allows_osx and not allows_all: return True return False -# get the local version list -staticVersionlist = None -with open("static/minecraft.json", 'r', encoding='utf-8') as legacyIndexFile: - staticVersionlist = LegacyOverrideIndex(json.load(legacyIndexFile)) +def process_single_variant(lwjgl_variant: MetaVersionFile): + lwjglVersion = lwjgl_variant.version + versionObj = copy.deepcopy(lwjgl_variant) + if lwjglVersion[0] == '2': + filename = os.path.join(PMC_DIR, LWJGL_COMPONENT, f"{lwjglVersion}.json") + versionObj.name = 'LWJGL 2' + versionObj.uid = LWJGL_COMPONENT + versionObj.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] + elif lwjglVersion[0] == '3': + filename = os.path.join(PMC_DIR, LWJGL3_COMPONENT, f"{lwjglVersion}.json") + versionObj.name = 'LWJGL 3' + versionObj.uid = LWJGL3_COMPONENT + versionObj.conflicts = [Dependency(uid=LWJGL_COMPONENT)] + # remove jutils and jinput from LWJGL 3 + # this is a dependency that Mojang kept in, but doesn't belong there anymore + filteredLibraries = list( + filter(lambda lib: not lib.name.artifact in ["jutils", "jinput"], versionObj.libraries)) + versionObj.libraries = filteredLibraries + else: + raise Exception("LWJGL version not recognized: %s" % versionObj.version) + + versionObj.volatile = True + versionObj.order = -1 + good = True + for lib in versionObj.libraries: + if not lib.natives: + continue + checkedDict = {'linux', 'windows', 'osx'} + if not checkedDict.issubset(lib.natives.keys()): + print("Missing system classifier!", versionObj.version, lib.name, lib.natives.keys()) + good = False + break + if lib.downloads: + for entry in checkedDict: + bakedEntry = lib.natives[entry] + if not bakedEntry in lib.downloads.classifiers: + print("Missing download for classifier!", versionObj.version, lib.name, bakedEntry, + lib.downloads.classifiers.keys()) + good = False + break + if good: + versionObj.write(filename) + else: + print("Skipped LWJGL", versionObj.version) + + +def main(): + # get the local version list + override_index = LegacyOverrideIndex.parse_file(os.path.join(STATIC_DIR, STATIC_OVERRIDES_FILE)) -found_any_lwjgl3 = False + found_any_lwjgl3 = False -for filename in os.listdir(UPSTREAM_DIR + '/mojang/versions'): - with open(UPSTREAM_DIR + "/mojang/versions/" + filename) as json_file: + for filename in os.listdir(os.path.join(UPSTREAM_DIR, VERSIONS_DIR)): + input_file = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, filename) + if not input_file.endswith(".json"): + # skip non JSON files + continue print("Processing", filename) - mojangVersionFile = MojangVersionFile(json.load(json_file)) - versionFile = MojangToPolyMC(mojangVersionFile, "Minecraft", "net.minecraft", mojangVersionFile.id) + mojangVersionFile = MojangVersionFile.parse_file(input_file) + versionFile = mojangVersionFile.to_meta_version("Minecraft", MINECRAFT_COMPONENT, mojangVersionFile.id) libs_minecraft = [] is_lwjgl_3 = False buckets = {} - for lib in versionFile.libraries: - pmcLib = PolyMCLibrary(lib.to_json()) + for pmcLib in versionFile.libraries: removePathsFromLib(pmcLib) specifier = pmcLib.name ruleHash = None - if specifier.isLwjgl(): + if specifier.is_lwjgl(): rules = None if pmcLib.rules: rules = pmcLib.rules pmcLib.rules = None - if isOnlyMacOS(rules, specifier): + if is_macos_only(rules, specifier): print("Candidate library ", specifier, " is only for macOS and is therefore ignored.") continue - bucket = addOrGetBucket(buckets, rules) + bucket = add_or_get_bucket(buckets, rules) if specifier.group == "org.lwjgl.lwjgl" and specifier.artifact == "lwjgl": bucket.version = specifier.version if specifier.group == "org.lwjgl" and specifier.artifact == "lwjgl": @@ -210,10 +257,10 @@ for filename in os.listdir(UPSTREAM_DIR + '/mojang/versions'): if not bucket.libraries: bucket.libraries = [] bucket.libraries.append(pmcLib) - bucket.releaseTime = versionFile.releaseTime + bucket.release_time = versionFile.release_time else: # FIXME: workaround for insane log4j nonsense from December 2021. Probably needs adjustment. - if pmcLib.name.isLog4j(): + if pmcLib.name.is_log4j(): versionOverride, mavenOverride = map_log4j_artifact(pmcLib.name.version) if versionOverride not in LOG4J_HASHES: @@ -222,33 +269,38 @@ for filename in os.listdir(UPSTREAM_DIR + '/mojang/versions'): if pmcLib.name.artifact not in LOG4J_HASHES[versionOverride]: raise Exception("ERROR: unhandled log4j artifact %s!" % pmcLib.name.artifact) - replacementLib = PolyMCLibrary(name=GradleSpecifier( - "org.apache.logging.log4j:%s:%s" % (pmcLib.name.artifact, versionOverride))) - replacementLib.downloads = MojangLibraryDownloads() - replacementLib.downloads.artifact = MojangArtifact() - replacementLib.downloads.artifact.url = mavenOverride % (replacementLib.name.getPath()) - replacementLib.downloads.artifact.sha1 = LOG4J_HASHES[versionOverride][pmcLib.name.artifact]["sha1"] - replacementLib.downloads.artifact.size = LOG4J_HASHES[versionOverride][pmcLib.name.artifact]["size"] + replacement_name = GradleSpecifier( + "org.apache.logging.log4j:%s:%s" % (pmcLib.name.artifact, versionOverride)) + artifact = MojangArtifact( + url=mavenOverride % (replacement_name.path()), + sha1=LOG4J_HASHES[versionOverride][pmcLib.name.artifact]["sha1"], + size=LOG4J_HASHES[versionOverride][pmcLib.name.artifact]["size"] + ) + + replacementLib = Library( + name=replacement_name, + downloads=MojangLibraryDownloads(artifact=artifact) + ) libs_minecraft.append(replacementLib) else: libs_minecraft.append(pmcLib) if len(buckets) == 1: for key in buckets: keyBucket = buckets[key] - keyBucket.libraries = sorted(keyBucket.libraries, key=itemgetter('name')) - addLWJGLVersion(lwjglVersionVariants, keyBucket) + keyBucket.libraries = sorted(keyBucket.libraries, key=attrgetter("name")) + add_lwjgl_version(lwjglVersionVariants, keyBucket) print("Found only candidate LWJGL", keyBucket.version, key) else: # multiple buckets for LWJGL. [None] is common to all, other keys are for different sets of rules for key in buckets: - if key == None: + if key is None: continue keyBucket = buckets[key] if None in buckets: - keyBucket.libraries = sorted(keyBucket.libraries + buckets[None].libraries, key=itemgetter('name')) + keyBucket.libraries = sorted(keyBucket.libraries + buckets[None].libraries, key=attrgetter("name")) else: - keyBucket.libraries = sorted(keyBucket.libraries, key=itemgetter('name')) - addLWJGLVersion(lwjglVersionVariants, keyBucket) + keyBucket.libraries = sorted(keyBucket.libraries, key=attrgetter('name')) + add_lwjgl_version(lwjglVersionVariants, keyBucket) print("Found candidate LWJGL", keyBucket.version, key) # remove the common bucket... if None in buckets: @@ -257,12 +309,13 @@ for filename in os.listdir(UPSTREAM_DIR + '/mojang/versions'): depentry = None if is_lwjgl_3: - depentry = DependencyEntry(uid='org.lwjgl3') + depentry = Dependency(uid=LWJGL3_COMPONENT) else: - depentry = DependencyEntry(uid='org.lwjgl') + depentry = Dependency(uid=LWJGL_COMPONENT) if len(buckets) == 1: suggestedVersion = next(iter(buckets.values())).version - # HACK: forcing hard dependencies here for now... the UI doesn't know how to filter by this and it looks odd, but it works + # HACK: forcing hard dependencies here for now... + # the UI doesn't know how to filter by this and it looks odd, but it works if is_lwjgl_3: depentry.suggests = suggestedVersion depentry.equals = suggestedVersion @@ -284,105 +337,61 @@ for filename in os.listdir(UPSTREAM_DIR + '/mojang/versions'): # if it uses LWJGL 3, add the trait that enables starting on first thread on macOS if is_lwjgl_3: - if not versionFile.addTraits: - versionFile.addTraits = [] - versionFile.addTraits.append("FirstThreadOnMacOS") + if not versionFile.additional_traits: + versionFile.additional_traits = [] + versionFile.additional_traits.append("FirstThreadOnMacOS") versionFile.requires = [depentry] versionFile.order = -2 # process 1.13 arguments into previous version if not mojangVersionFile.minecraftArguments and mojangVersionFile.arguments: - versionFile.minecraftArguments = adaptNewStyleArguments(mojangVersionFile.arguments) - filenameOut = PMC_DIR + "/net.minecraft/%s.json" % versionFile.version - if versionFile.version in staticVersionlist.versions: - ApplyLegacyOverride(versionFile, staticVersionlist.versions[versionFile.version]) - with open(filenameOut, 'w') as outfile: - json.dump(versionFile.to_json(), outfile, sort_keys=True, indent=4) - - -def processSingleVariant(lwjglVariant): - lwjglVersion = lwjglVariant.version - versionObj = copy.deepcopy(lwjglVariant) - if lwjglVersion[0] == '2': - filename = PMC_DIR + "/org.lwjgl/%s.json" % lwjglVersion - versionObj.name = 'LWJGL 2' - versionObj.uid = 'org.lwjgl' - versionObj.conflicts = [DependencyEntry(uid='org.lwjgl3')] - elif lwjglVersion[0] == '3': - filename = PMC_DIR + "/org.lwjgl3/%s.json" % lwjglVersion - versionObj.name = 'LWJGL 3' - versionObj.uid = 'org.lwjgl3' - versionObj.conflicts = [DependencyEntry(uid='org.lwjgl')] - # remove jutils and jinput from LWJGL 3 -- this is a dependency that Mojang kept in, but doesn't belong there anymore - filteredLibraries = list( - filter(lambda lib: not lib.name.artifact in ["jutils", "jinput"], versionObj.libraries)) - versionObj.libraries = filteredLibraries - else: - raise Exception("LWJGL version not recognized: %s" % versionObj.version) - - versionObj.volatile = True - versionObj.order = -1 - good = True - for lib in versionObj.libraries: - if not lib.natives: - continue - checkedDict = {'linux', 'windows', 'osx'} - if not checkedDict.issubset(lib.natives.keys()): - print("Missing system classifier!", versionObj.version, lib.name, lib.natives.keys()) - good = False - break - if lib.downloads: - for entry in checkedDict: - bakedEntry = lib.natives[entry] - if not bakedEntry in lib.downloads.classifiers: - print("Missing download for classifier!", versionObj.version, lib.name, bakedEntry, - lib.downloads.classifiers.keys()) - good = False - break - if good: - with open(filename, 'w') as outfile: - json.dump(versionObj.to_json(), outfile, sort_keys=True, indent=4) - else: - print("Skipped LWJGL", versionObj.version) - + versionFile.minecraft_arguments = adaptNewStyleArguments(mojangVersionFile.arguments) + out_filename = os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{versionFile.version}.json") + if versionFile.version in override_index.versions: + override = override_index.versions[versionFile.version] + override.apply_onto_meta_version(versionFile) + versionFile.write(out_filename) + + for lwjglVersionVariant in lwjglVersionVariants: + decidedVariant = None + passedVariants = 0 + unknownVariants = 0 + print("%d variant(s) for LWJGL %s:" % (len(lwjglVersionVariants[lwjglVersionVariant]), lwjglVersionVariant)) + + for variant in lwjglVersionVariants[lwjglVersionVariant]: + if variant.sha1 in BAD_VARIANTS: + print("Variant %s ignored because it's marked as bad." % (variant.sha1)) + continue + if variant.sha1 in PASS_VARIANTS: + print("Variant %s accepted." % (variant.sha1)) + decidedVariant = variant + passedVariants += 1 + continue -for lwjglVersionVariant in lwjglVersionVariants: - decidedVariant = None - passedVariants = 0 - unknownVariants = 0 - print("%d variant(s) for LWJGL %s:" % (len(lwjglVersionVariants[lwjglVersionVariant]), lwjglVersionVariant)) + print(f" \"{variant.sha1}\", # {lwjglVersionVariant} ({variant.version.release_time})") + unknownVariants += 1 + print("") - for variant in lwjglVersionVariants[lwjglVersionVariant]: - if variant.sha1 in badVariants: - print("Variant %s ignored because it's marked as bad." % (variant.sha1)) - continue - if variant.sha1 in passVariants: - print("Variant %s accepted." % (variant.sha1)) - decidedVariant = variant - passedVariants += 1 - continue + if decidedVariant and passedVariants == 1 and unknownVariants == 0: + process_single_variant(decidedVariant.version) + else: + raise Exception("No variant decided for version %s out of %d possible ones and %d unknown ones." % ( + lwjglVersionVariant, passedVariants, unknownVariants)) - print(f" \"{variant.sha1}\", # {lwjglVersionVariant} ({variant.version.releaseTime})") - unknownVariants += 1 - print("") + lwjglSharedData = MetaPackageData(uid=LWJGL_COMPONENT, name='LWJGL 2') + lwjglSharedData.recommended = ['2.9.4-nightly-20150209'] + lwjglSharedData.write(os.path.join(PMC_DIR, LWJGL_COMPONENT, "package.json")) - if decidedVariant and passedVariants == 1 and unknownVariants == 0: - processSingleVariant(decidedVariant.version) - else: - raise Exception("No variant decided for version %s out of %d possible ones and %d unknown ones." % ( - lwjglVersionVariant, passedVariants, unknownVariants)) + if found_any_lwjgl3: + lwjglSharedData = MetaPackageData(uid=LWJGL3_COMPONENT, name='LWJGL 3') + lwjglSharedData.recommended = ['3.1.2'] + lwjglSharedData.write(os.path.join(PMC_DIR, LWJGL3_COMPONENT, "package.json")) -lwjglSharedData = PolyMCSharedPackageData(uid='org.lwjgl', name='LWJGL 2') -lwjglSharedData.recommended = ['2.9.4-nightly-20150209'] -lwjglSharedData.write() + localVersionlist = MojangIndexWrap(MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE))) -if found_any_lwjgl3: - lwjglSharedData = PolyMCSharedPackageData(uid='org.lwjgl3', name='LWJGL 3') - lwjglSharedData.recommended = ['3.1.2'] - lwjglSharedData.write() + mcSharedData = MetaPackageData(uid=MINECRAFT_COMPONENT, name='Minecraft') + mcSharedData.recommended = [localVersionlist.latest.release] + mcSharedData.write(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, "package.json")) -with open(UPSTREAM_DIR + "/mojang/version_manifest_v2.json", 'r', encoding='utf-8') as localIndexFile: - localVersionlist = MojangIndexWrap(json.load(localIndexFile)) -mcSharedData = PolyMCSharedPackageData(uid='net.minecraft', name='Minecraft') -mcSharedData.recommended = [localVersionlist.latest['release']] -mcSharedData.write() +if __name__ == '__main__': + main() @@ -2,8 +2,9 @@ import hashlib from operator import itemgetter from meta.metautil import * +from meta.common import polymc_path -PMC_DIR = os.environ["PMC_DIR"] +PMC_DIR = polymc_path() # take the hash type (like hashlib.md5) and filename, return hex string of hash diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 478404362a..ce773e4e18 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -5,7 +5,10 @@ DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" def serialize_datetime(dt: datetime.datetime): - return dt.replace(tzinfo=datetime.timezone.utc).isoformat() + if dt.tzinfo is None: + dt.replace(tzinfo=datetime.timezone.utc).isoformat() + + return dt.isoformat() def polymc_path(): diff --git a/meta/common/mojang.py b/meta/common/mojang.py index 1c16afc885..3bf8281942 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -7,6 +7,8 @@ VERSIONS_DIR = join(BASE_DIR, "versions") ASSETS_DIR = join(BASE_DIR, "assets") STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") +STATIC_OVERRIDES_FILE = join(BASE_DIR, "minecraft-legacy-override.json") -MINECRAFT_COMPONENT = "" -LWJGL_COMPONENT = "" +MINECRAFT_COMPONENT = "net.minecraft" +LWJGL_COMPONENT = "org.lwjgl" +LWJGL3_COMPONENT = "org.lwjgl3" diff --git a/meta/metautil.py b/meta/metautil.py index 11c4009868..ee8994acb3 100644 --- a/meta/metautil.py +++ b/meta/metautil.py @@ -99,53 +99,6 @@ class GradleSpecifierProperty(JsonProperty): return value, value.toString() -''' -Mojang index files look like this: -{ - "latest": { - "release": "1.11.2", - "snapshot": "17w06a" - }, - "versions": [ - ... - { - "id": "17w06a", - "releaseTime": "2017-02-08T13:16:29+00:00", - "time": "2017-02-08T13:17:20+00:00", - "type": "snapshot", - "url": "https://launchermeta.mojang.com/mc/game/7db0c61afa278d016cf1dae2fba0146edfbf2f8e/17w06a.json" - }, - ... - ] -} -''' - - -class MojangIndexEntry(JsonObject): - id = StringProperty() - releaseTime = ISOTimestampProperty() - time = ISOTimestampProperty() - type = StringProperty() - url = StringProperty() - sha1 = StringProperty(exclude_if_none=True, default=None) - complianceLevel = IntegerProperty(exclude_if_none=True, default=None) - - -class MojangIndex(JsonObject): - latest = DictProperty(StringProperty) - versions = ListProperty(MojangIndexEntry) - - -class MojangIndexWrap: - def __init__(self, json): - self.index = MojangIndex.wrap(json) - self.latest = self.index.latest - versionsDict = {} - for version in self.index.versions: - versionsDict[version.id] = version - self.versions = versionsDict - - class MojangArtifactBase(JsonObject): sha1 = StringProperty(exclude_if_none=True, default=None) size = IntegerProperty(exclude_if_none=True, default=None) @@ -303,75 +256,11 @@ class PolyMCVersionFile(VersionedJsonObject): minecraftArguments = StringProperty(exclude_if_none=True, default=None) releaseTime = ISOTimestampProperty(exclude_if_none=True, default=None) type = StringProperty(exclude_if_none=True, default=None) - compatibleJavaMajors = ListProperty(int, exclude_if_none=True, default=None) addTraits = ListProperty(StringProperty, name="+traits", exclude_if_none=True, default=None) addTweakers = ListProperty(StringProperty, name="+tweakers", exclude_if_none=True, default=None) order = IntegerProperty(exclude_if_none=True, default=None) -class UnknownComplianceLevelException(Exception): - """Exception raised for unknown Mojang compliance level - - Attributes: - message -- explanation of the error - """ - - def __init__(self, message): - self.message = message - - -# Convert Mojang version file object to a PolyMC version file object -def MojangToPolyMC(file, name, uid, version): - pmcFile = PolyMCVersionFile( - { - "name": name, - "uid": uid, - "version": version - } - ) - pmcFile.assetIndex = file.assetIndex - pmcFile.libraries = file.libraries - pmcFile.mainClass = file.mainClass - if file.id: - mainJar = PolyMCLibrary( - { - "name": "com.mojang:minecraft:%s:client" % file.id, - } - ) - cldl = file.downloads['client'] - mainJar.downloads = MojangLibraryDownloads() - mainJar.downloads.artifact = MojangArtifact() - mainJar.downloads.artifact.path = None - mainJar.downloads.artifact.url = cldl.url - mainJar.downloads.artifact.sha1 = cldl.sha1 - mainJar.downloads.artifact.size = cldl.size - pmcFile.mainJar = mainJar - - pmcFile.minecraftArguments = file.minecraftArguments - pmcFile.releaseTime = file.releaseTime - # time should not be set. - pmcFile.type = file.type - - if file.javaVersion is not None: # some versions don't have this. TODO: maybe maintain manual overrides - major = file.javaVersion.majorVersion - pmcFile.compatibleJavaMajors = [major] - if major == 16: # TODO: deal with this somewhere else - pmcFile.compatibleJavaMajors.append(17) - - maxSupportedLevel = 1 - if file.complianceLevel: - if file.complianceLevel == 0: - pass - elif file.complianceLevel == 1: - if not pmcFile.addTraits: - pmcFile.addTraits = [] - pmcFile.addTraits.append("XR:Initial") - else: - raise UnknownComplianceLevelException("Unsupported Mojang compliance level: %d. Max supported is: %d" % ( - file.complianceLevel, maxSupportedLevel)) - return pmcFile - - class PolyMCSharedPackageData(VersionedJsonObject): name = StringProperty(required=True) uid = StringProperty(required=True) @@ -388,15 +277,6 @@ class PolyMCSharedPackageData(VersionedJsonObject): print("Error while trying to save shared packaged data for %s:" % self.uid, e) -def writeSharedPackageData(uid, name): - desc = PolyMCSharedPackageData({ - 'name': name, - 'uid': uid - }) - with open(PMC_DIR + "/%s/package.json" % uid, 'w') as file: - json.dump(desc.to_json(), file, sort_keys=True, indent=4) - - def readSharedPackageData(uid): with open(PMC_DIR + "/%s/package.json" % uid, 'r') as file: return PolyMCSharedPackageData(json.load(file)) @@ -427,52 +307,3 @@ class PolyMCPackageIndexEntry(JsonObject): class PolyMCPackageIndex(VersionedJsonObject): packages = ListProperty(PolyMCPackageIndexEntry) - - -''' -The PolyMC static override file for legacy looks like this: -{ - "versions": [ - ... - { - "id": "c0.0.13a", - "checksum": "3617fbf5fbfd2b837ebf5ceb63584908", - "releaseTime": "2009-05-31T00:00:00+02:00", - "type": "old_alpha", - "mainClass": "com.mojang.minecraft.Minecraft", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - ... - ] -} -''' - - -class LegacyOverrideEntry(JsonObject): - releaseTime = ISOTimestampProperty(exclude_if_none=True, default=None) - mainClass = StringProperty(exclude_if_none=True, default=None) - appletClass = StringProperty(exclude_if_none=True, default=None) - addTraits = ListProperty(StringProperty, name="+traits", exclude_if_none=True, default=None) - - -class LegacyOverrideIndex(JsonObject): - versions = DictProperty(LegacyOverrideEntry) - - -def ApplyLegacyOverride(pmcFile, legacyOverride): - # simply hard override classes - pmcFile.mainClass = legacyOverride.mainClass - pmcFile.appletClass = legacyOverride.appletClass - # if we have an updated release time (more correct than Mojang), use it - if legacyOverride.releaseTime != None: - pmcFile.releaseTime = legacyOverride.releaseTime - # add traits, if any - if legacyOverride.addTraits: - if not pmcFile.addTraits: - pmcFile.addTraits = [] - pmcFile.addTraits = pmcFile.addTraits + legacyOverride.addTraits - # remove all libraries - they are not needed for legacy - pmcFile.libraries = None - # remove minecraft arguments - we use our own hardcoded ones - pmcFile.minecraftArguments = None diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 3b343a4a02..73c1e80a42 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -1,4 +1,3 @@ -import os.path from datetime import datetime from typing import Optional, List, Dict, Any @@ -41,7 +40,8 @@ class MetaBase(pydantic.BaseModel): class Versioned(MetaBase): @validator("format_version") def format_version_must_be_supported(cls, v): - return v > META_FORMAT_VERSION + assert v > META_FORMAT_VERSION + return v format_version: int = Field(META_FORMAT_VERSION, alias="formatVersion") @@ -80,13 +80,14 @@ class MojangLibraryExtractRules(MetaBase): class MojangLibraryDownloads(MetaBase): artifact: Optional[MojangArtifact] - classifiers: Dict[Any, MojangArtifact] + classifiers: Optional[Dict[Any, MojangArtifact]] class OSRule(MetaBase): @validator("name") def name_must_be_os(cls, v): - return v in ["osx", "linux", "windows"] + assert v in ["osx", "linux", "windows"] + return v name: str version: Optional[str] @@ -95,21 +96,40 @@ class OSRule(MetaBase): class MojangRule(MetaBase): @validator("action") def action_must_be_allow_disallow(cls, v): - return v in ["allow", "disallow"] + assert v in ["allow", "disallow"] + return v action: str os: Optional[OSRule] +class MojangRules(MetaBase): + __root__: List[MojangRule] + + def __iter__(self): + return iter(self.__root__) + + def __getitem__(self, item): + return self.__root__[item] + + class MojangLibrary(MetaBase): + @validator("name") + def validate_name(cls, v): + if v is not GradleSpecifier: + return GradleSpecifier(v) + return v + extract: Optional[MojangLibraryExtractRules] name: GradleSpecifier downloads: Optional[MojangLibraryDownloads] natives: Optional[Dict[str, str]] - rules: Optional[List[MojangRule]] + rules: Optional[MojangRules] - class Config: - arbitrary_types_allowed = True + +class Library(MojangLibrary): + url: Optional[str] + mmcHint: Optional[AnyHttpUrl] = Field(None, alias="MMC-hint") class Dependency(MetaBase): @@ -118,11 +138,6 @@ class Dependency(MetaBase): suggests: Optional[str] -class Library(MojangLibrary): - url: Optional[str] - mmcHint: Optional[AnyHttpUrl] = Field(None, alias="MMC-hint") - - class MetaVersionFile(Versioned): name: str version: str @@ -141,6 +156,7 @@ class MetaVersionFile(Versioned): applet_class: Optional[str] = Field(alias="appletClass") minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") release_time: Optional[datetime] = Field(alias="releaseTime") + compatible_java_majors: Optional[List[int]] = Field(alias="compatibleJavaMajors") additional_traits: Optional[List[str]] = Field(alias="+traits") additional_tweakers: Optional[List[str]] = Field(alias="+tweakers") diff --git a/meta/model/mojang.py b/meta/model/mojang.py index fa00071dd7..1d739f4725 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -1,9 +1,13 @@ from datetime import datetime -from typing import Optional, List, Dict +from typing import Optional, List, Dict, Any -from pydantic import AnyHttpUrl +from pydantic import AnyHttpUrl, validator, Field -from . import MetaBase +from . import MetaBase, MojangArtifactBase, MojangAssets, MojangLibrary, MojangArtifact, MojangLibraryDownloads, \ + Library, MetaVersionFile, GradleSpecifier + +SUPPORTED_LAUNCHER_VERSION = 21 +SUPPORTED_COMPLIANCE_LEVEL = 1 ''' Mojang index files look like this: @@ -68,3 +72,133 @@ class ExperimentIndexWrap: def __init__(self, index: ExperimentIndex): self.index: ExperimentIndex = index self.versions: Dict[str, ExperimentEntry] = dict((x.id, x) for x in index.experiments) + + +class LegacyOverrideEntry(MetaBase): + main_class: Optional[str] = Field(alias="mainClass") + applet_class: Optional[str] = Field(alias="appletClass") + release_time: Optional[datetime] = Field(alias="releaseTime") + additional_traits: Optional[List[str]] = Field(alias="+traits") + + def apply_onto_meta_version(self, meta_version: MetaVersionFile, legacy: bool = True): + # simply hard override classes + meta_version.main_class = self.main_class + meta_version.applet_class = self.applet_class + # if we have an updated release time (more correct than Mojang), use it + if self.release_time: + meta_version.release_time = self.release_time + + # add traits, if any + if self.additional_traits: + if not meta_version.additional_traits: + meta_version.additional_traits = [] + meta_version.additional_traits = meta_version.additional_traits + self.additional_traits + + if legacy: + # remove all libraries - they are not needed for legacy + meta_version.libraries = None + # remove minecraft arguments - we use our own hardcoded ones + meta_version.minecraft_arguments = None + + +class LegacyOverrideIndex(MetaBase): + versions: Dict[str, LegacyOverrideEntry] + + +class MojangArguments(MetaBase): + game: Optional[List[Any]] # mixture of strings and objects + jvm: Optional[List[Any]] + + +class MojangLoggingArtifact(MojangArtifactBase): + id: str + + +class MojangLogging(MetaBase): + @validator("type") + def validate_type(cls, v): + assert v in ["log4j2-xml"] + return v + + file: MojangLoggingArtifact + argument: str + type: str + + +class JavaVersion(MetaBase): + component: str = "jre-legacy" + majorVersion: int = 8 + + +class MojangVersionFile(MetaBase): + @validator("minimumLauncherVersion") + def validate_minimum_launcher_version(cls, v): + assert v <= SUPPORTED_LAUNCHER_VERSION + return v + + @validator("complianceLevel") + def validate_compliance_level(cls, v): + assert v <= SUPPORTED_COMPLIANCE_LEVEL + return v + + id: str # TODO: optional? + arguments: Optional[MojangArguments] + assetIndex: Optional[MojangAssets] + assets: Optional[str] + downloads: Dict[str, MojangArtifactBase] # TODO improve this? + libraries: Optional[List[MojangLibrary]] # TODO: optional? + mainClass: Optional[str] + appletClass: Optional[str] + processArguments: Optional[str] + minecraftArguments: Optional[str] + minimumLauncherVersion: Optional[int] # TODO: validate validateSupportedMojangVersion + releaseTime: Optional[datetime] + time: Optional[datetime] + type: Optional[str] + inheritsFrom: Optional[str] + logging: Optional[Dict[str, MojangLogging]] # TODO improve this? + complianceLevel: Optional[int] + javaVersion: Optional[JavaVersion] + + def to_meta_version(self, name: str, uid: str, version: str) -> MetaVersionFile: + main_jar = None + addn_traits = None + new_type = self.type + compatible_java_majors = None + if self.id: + client_download = self.downloads['client'] + artifact = MojangArtifact(url=client_download.url, sha1=client_download.sha1, size=client_download.size) + downloads = MojangLibraryDownloads(artifact=artifact) + main_jar = Library(name=GradleSpecifier("com.mojang:minecraft:%s:client" % self.id), downloads=downloads) + + if not self.complianceLevel: # both == 0 and is None + pass + elif self.complianceLevel == 1: + if not addn_traits: + addn_traits = [] + addn_traits.append("XR:Initial") + else: + raise Exception(f"Unsupported compliance level {self.complianceLevel}") + + if self.javaVersion is not None: # some versions don't have this. TODO: maybe maintain manual overrides + major = self.javaVersion.major_version + compatible_java_majors = [major] + if major == 16: # TODO: deal with this somewhere else + compatible_java_majors.append(17) + + if new_type == "pending": # TODO: why wasn't this needed before large refactor + new_type = "experiment" + + return MetaVersionFile( + name=name, + uid=uid, + version=version, + asset_index=self.assetIndex, + libraries=self.libraries, + main_class=self.mainClass, + minecraft_arguments=self.minecraftArguments, + release_time=self.releaseTime, + type=new_type, + compatible_java_majors=compatible_java_majors, + additional_traits=addn_traits, + main_jar=main_jar) diff --git a/static/mojang/minecraft-experiments.json b/static/mojang/minecraft-experiments.json index 4b16b70601..a365eb4b11 100644 --- a/static/mojang/minecraft-experiments.json +++ b/static/mojang/minecraft-experiments.json @@ -1,102 +1,102 @@ { "experiments": [ { - "id": "1.19_deep_dark_experimental_snapshot-1", + "id": "1_19_deep_dark_experimental_snapshot-1", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Deep_Dark_Experimental_Snapshot_1", "url": "https://launcher.mojang.com/v1/objects/b1e589c1d6ed73519797214bc796e53f5429ac46/1_19_deep_dark_experimental_snapshot-1.zip" }, { - "id": "1.18_experimental-snapshot-7", + "id": "1_18_experimental-snapshot-7", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.18_Experimental_Snapshot_7", "url": "https://launcher.mojang.com/v1/objects/ab4ecebb133f56dd4c4c4c3257f030a947ddea84/1_18_experimental-snapshot-7.zip" }, { - "id": "1.18_experimental-snapshot-6", + "id": "1_18_experimental-snapshot-6", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.18_Experimental_Snapshot_6", "url": "https://launcher.mojang.com/v1/objects/4697c84c6a347d0b8766759d5b00bc5a00b1b858/1_18_experimental-snapshot-6.zip" }, { - "id": "1.18_experimental-snapshot-5", + "id": "1_18_experimental-snapshot-5", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.18_Experimental_Snapshot_5", "url": "https://launcher.mojang.com/v1/objects/d9cb7f6fb4e440862adfb40a385d83e3f8d154db/1_18_experimental-snapshot-5.zip" }, { - "id": "1.18_experimental-snapshot-4", + "id": "1_18_experimental-snapshot-4", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.18_Experimental_Snapshot_4", "url": "https://launcher.mojang.com/v1/objects/b92a360cbae2eb896a62964ad8c06c3493b6c390/1_18_experimental-snapshot-4.zip" }, { - "id": "1.18_experimental-snapshot-3", + "id": "1_18_experimental-snapshot-3", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.18_Experimental_Snapshot_3", "url": "https://launcher.mojang.com/v1/objects/846648ff9fe60310d584061261de43010e5c722b/1_18_experimental-snapshot-3.zip" }, { - "id": "1.18_experimental-snapshot-2", + "id": "1_18_experimental-snapshot-2", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.18_Experimental_Snapshot_2", "url": "https://launcher.mojang.com/v1/objects/0adfe4f321aa45248fc88ac888bed5556633e7fb/1_18_experimental-snapshot-2.zip" }, { - "id": "1.18_experimental-snapshot-1", + "id": "1_18_experimental-snapshot-1", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.18_Experimental_Snapshot_1", "url": "https://launcher.mojang.com/v1/objects/231bba2a21e18b8c60976e1f6110c053b7b93226/1_18_experimental-snapshot-1.zip" }, { - "id": "1.16_combat-6", + "id": "1_16_combat-6", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_8c", "url": "https://launcher.mojang.com/experiments/combat/ea08f7eb1f96cdc82464e27c0f95d23965083cfb/1_16_combat-6.zip" }, { - "id": "1.16_combat-5", + "id": "1_16_combat-5", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_8b", "url": "https://launcher.mojang.com/experiments/combat/9b2b984d635d373564b50803807225c75d7fd447/1_16_combat-5.zip" }, { - "id": "1.16_combat-4", + "id": "1_16_combat-4", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_8", "url": "https://cdn.discordapp.com/attachments/369990015096455168/947864881028272198/1_16_combat-4.zip" }, { - "id": "1.16_combat-3", + "id": "1_16_combat-3", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_7c", "url": "https://launcher.mojang.com/experiments/combat/2557b99d95588505e988886220779087d7d6b1e9/1_16_combat-3.zip" }, { - "id": "1.16_combat-2", + "id": "1_16_combat-2", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_7b", "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-2.zip" }, { - "id": "1.16_combat-1", + "id": "1_16_combat-1", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_7", "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-1.zip" }, { - "id": "1.16_combat-0", + "id": "1_16_combat-0", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_6", "url": "https://launcher.mojang.com/experiments/combat/5a8ceec8681ed96ab6ecb9607fb5d19c8a755559/1_16_combat-0.zip" }, { - "id": "1.15_combat-6", + "id": "1_15_combat-6", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_5", "url": "https://launcher.mojang.com/experiments/combat/52263d42a626b40c947e523128f7a195ec5af76a/1_15_combat-6.zip" }, { - "id": "1.15_combat-1", + "id": "1_15_combat-1", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_4", "url": "https://launcher.mojang.com/experiments/combat/ac11ea96f3bb2fa2b9b76ab1d20cacb1b1f7ef60/1_15_combat-1.zip" }, { - "id": "1.14_combat-3", + "id": "1_14_combat-3", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_3", "url": "https://launcher.mojang.com/experiments/combat/0f209c9c84b81c7d4c88b4632155b9ae550beb89/1_14_combat-3.zip" }, { - "id": "1.14_combat-0", + "id": "1_14_combat-0", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_2", "url": "https://launcher.mojang.com/experiments/combat/d164bb6ecc5fca9ac02878c85f11befae61ac1ca/1_14_combat-0.zip" }, { - "id": "1.14_combat-212796", + "id": "1_14_combat-212796", "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.14.3_-_Combat_Test", "url": "https://launcher.mojang.com/experiments/combat/610f5c9874ba8926d5ae1bcce647e5f0e6e7c889/1_14_combat-212796.zip" } diff --git a/static/minecraft.json b/static/mojang/minecraft-legacy-override.json index d30db4c10c..d30db4c10c 100644 --- a/static/minecraft.json +++ b/static/mojang/minecraft-legacy-override.json diff --git a/updateMojang.py b/updateMojang.py index 54d5d739be..98e2968646 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -1,5 +1,5 @@ import json -import os.path +import os import zipfile import requests @@ -22,14 +22,7 @@ forever_cache = FileCache('caches/http_cache', forever=True) sess = CacheControl(requests.Session(), forever_cache) -def fetch_version_file(path, url): - version_json = fetch_file(path, url) - asset_id = version_json["assetIndex"]["id"] - asset_url = version_json["assetIndex"]["url"] - return asset_id, asset_url - - -def fetch_zipped_version_file(path, url): +def fetch_zipped_version(path, url): zip_path = f"{path}.zip" download_binary_file(sess, zip_path, url) with zipfile.ZipFile(zip_path, 'r') as z: @@ -44,12 +37,10 @@ def fetch_zipped_version_file(path, url): with open(path, 'w', encoding='utf-8') as f: json.dump(version_json, f, sort_keys=True, indent=4) - asset_id = version_json["assetIndex"]["id"] - asset_url = version_json["assetIndex"]["url"] - return asset_id, asset_url + return version_json -def fetch_file(path, url): +def fetch_version(path, url): r = sess.get(url) r.raise_for_status() version_json = r.json() @@ -86,13 +77,10 @@ def main(): else: pending_ids = remote_ids - # update versions and the linked assets files - assets = {} for x in pending_ids: version = remote_versions.versions[x] - print("Updating " + version.id + " to timestamp " + version.releaseTime.strftime('%s')) - asset_id, asset_url = fetch_version_file(os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json"), version.url) - assets[asset_id] = asset_url + print("Updating " + version.id + " to timestamp " + version.release_time.strftime('%s')) + fetch_version(os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json"), version.url) # deal with experimental snapshots separately static_experiments_path = os.path.join(STATIC_DIR, STATIC_EXPERIMENTS_FILE) @@ -103,13 +91,7 @@ def main(): for x in experiment_ids: version = experiments.versions[x] print("Updating experiment " + version.id) - asset_id, asset_url = fetch_zipped_version_file(os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json"), - version.url) - assets[asset_id] = asset_url - - for asset_id, asset_url in assets.items(): - print("assets", asset_id, asset_url) - fetch_file(os.path.join(UPSTREAM_DIR, ASSETS_DIR, f"{asset_id}.json"), asset_url) + fetch_zipped_version(os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json"), version.url) remote_versions.index.write(version_manifest_path) |
