From a8babf42c5176fc7c86d60caa2fc56c0abbf2e04 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 21 Mar 2022 21:34:52 +0100 Subject: refactor: move utils into package --- meta/__init__.py | 1 + meta/common.py | 19 ++ meta/fabricutil.py | 32 +++ meta/forgeutil.py | 323 +++++++++++++++++++++++++ meta/jsonobject/__init__.py | 17 ++ meta/jsonobject/api.py | 53 +++++ meta/jsonobject/base.py | 394 ++++++++++++++++++++++++++++++ meta/jsonobject/base_properties.py | 320 +++++++++++++++++++++++++ meta/jsonobject/containers.py | 252 ++++++++++++++++++++ meta/jsonobject/exceptions.py | 10 + meta/jsonobject/properties.py | 155 ++++++++++++ meta/jsonobject/utils.py | 57 +++++ meta/liteloaderutil.py | 118 +++++++++ meta/metautil.py | 477 +++++++++++++++++++++++++++++++++++++ 14 files changed, 2228 insertions(+) create mode 100644 meta/__init__.py create mode 100644 meta/common.py create mode 100644 meta/fabricutil.py create mode 100644 meta/forgeutil.py create mode 100644 meta/jsonobject/__init__.py create mode 100644 meta/jsonobject/api.py create mode 100644 meta/jsonobject/base.py create mode 100644 meta/jsonobject/base_properties.py create mode 100644 meta/jsonobject/containers.py create mode 100644 meta/jsonobject/exceptions.py create mode 100644 meta/jsonobject/properties.py create mode 100644 meta/jsonobject/utils.py create mode 100644 meta/liteloaderutil.py create mode 100644 meta/metautil.py (limited to 'meta') diff --git a/meta/__init__.py b/meta/__init__.py new file mode 100644 index 0000000000..05cee3e7d7 --- /dev/null +++ b/meta/__init__.py @@ -0,0 +1 @@ +"""Meta package of meta""" diff --git a/meta/common.py b/meta/common.py new file mode 100644 index 0000000000..5454f517f3 --- /dev/null +++ b/meta/common.py @@ -0,0 +1,19 @@ +import os + + +def polymc_path(): + if "PMC_DIR" in os.environ: + return os.environ["PMC_DIR"] + return "polymc" + + +def upstream_path(): + if "UPSTREAM_DIR" in os.environ: + return os.environ["UPSTREAM_DIR"] + return "upstream" + + +def ensure_component_dir(component_id): + path = os.path.join(polymc_path(), component_id) + if not os.path.exists(path): + os.makedirs(path) diff --git a/meta/fabricutil.py b/meta/fabricutil.py new file mode 100644 index 0000000000..2f38f8f051 --- /dev/null +++ b/meta/fabricutil.py @@ -0,0 +1,32 @@ +from .metautil import * + + +class FabricInstallerArguments(JsonObject): + client = ListProperty(StringProperty) + common = ListProperty(StringProperty) + server = ListProperty(StringProperty) + + +class FabricInstallerLaunchwrapper(JsonObject): + tweakers = ObjectProperty(FabricInstallerArguments, required=True) + + +class FabricInstallerLibraries(JsonObject): + client = ListProperty(PolyMCLibrary) + common = ListProperty(PolyMCLibrary) + server = ListProperty(PolyMCLibrary) + + +class FabricInstallerDataV1(JsonObject): + version = IntegerProperty(required=True) + libraries = ObjectProperty(FabricInstallerLibraries, required=True) + mainClass = DefaultProperty() + arguments = ObjectProperty(FabricInstallerArguments, required=False) + launchwrapper = ObjectProperty(FabricInstallerLaunchwrapper, required=False) + + +class FabricJarInfo(JsonObject): + releaseTime = ISOTimestampProperty() + size = IntegerProperty() + sha256 = StringProperty() + sha1 = StringProperty() diff --git a/meta/forgeutil.py b/meta/forgeutil.py new file mode 100644 index 0000000000..4c2615cb8d --- /dev/null +++ b/meta/forgeutil.py @@ -0,0 +1,323 @@ +from collections import namedtuple + +from .metautil import * + + +# A post-processed entry constructed from the reconstructed Forge version index +class ForgeVersion: + def __init__(self, entry): + self.build = entry.build + self.rawVersion = entry.version + self.mcversion = entry.mcversion + self.mcversion_sane = self.mcversion.replace("_pre", "-pre", 1) + self.branch = entry.branch + self.installer_filename = None + self.installer_url = None + self.universal_filename = None + self.universal_url = None + self.changelog_url = None + self.longVersion = "%s-%s" % (self.mcversion, self.rawVersion) + if self.branch != None: + self.longVersion = self.longVersion + "-%s" % (self.branch) + for classifier, fileentry in entry.files.items(): + extension = fileentry.extension + checksum = fileentry.hash + filename = fileentry.filename(self.longVersion) + url = fileentry.url(self.longVersion) + if (classifier == "installer") and (extension == "jar"): + self.installer_filename = filename + self.installer_url = url + if (classifier == "universal" or classifier == "client") and (extension == "jar" or extension == "zip"): + self.universal_filename = filename + self.universal_url = url + if (classifier == "changelog") and (extension == "txt"): + self.changelog_url = url + + def name(self): + return "Forge %d" % (self.build) + + def usesInstaller(self): + if self.installer_url == None: + return False + if self.mcversion == "1.5.2": + return False + return True + + def filename(self): + if self.usesInstaller(): + return self.installer_filename + else: + return self.universal_filename + + def url(self): + if self.usesInstaller(): + return self.installer_url + else: + return self.universal_url + + def isSupported(self): + if self.url() == None: + return False + + versionElements = self.rawVersion.split('.') + if len(versionElements) < 1: + return False + + majorVersionStr = versionElements[0] + if not majorVersionStr.isnumeric(): + return False + + # majorVersion = int(majorVersionStr) + # if majorVersion >= 37: + # return False + + return True + + +class ForgeFile(JsonObject): + classifier = StringProperty(required=True) + hash = StringProperty(required=True) + extension = StringProperty(required=True) + + def filename(self, longversion): + return "%s-%s-%s.%s" % ("forge", longversion, self.classifier, self.extension) + + def url(self, longversion): + return "https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s/%s" % ( + longversion, self.filename(longversion)) + + +class ForgeEntry(JsonObject): + longversion = StringProperty(required=True) + mcversion = StringProperty(required=True) + version = StringProperty(required=True) + build = IntegerProperty(required=True) + branch = StringProperty() + latest = BooleanProperty() + recommended = BooleanProperty() + files = DictProperty(ForgeFile) + + +class ForgeMcVersionInfo(JsonObject): + latest = StringProperty() + recommended = StringProperty() + versions = ListProperty(StringProperty()) + + +class DerivedForgeIndex(JsonObject): + versions = DictProperty(ForgeEntry) + by_mcversion = DictProperty(ForgeMcVersionInfo) + + +''' +FML library mappings - these are added to legacy Forge versions because Forge no longer can download these +by itself - the locations have changed and some of this has to be rehosted on PolyMC servers. +''' + +FMLLib = namedtuple('FMLLib', ('filename', 'checksum', 'ours')) + +fmlLibsMapping = {} + +fmlLibsMapping["1.3.2"] = [ + FMLLib("argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", False), + FMLLib("guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", False), + FMLLib("asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", False) +] + +fml14 = [ + FMLLib("argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", False), + FMLLib("guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", False), + FMLLib("asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", False), + FMLLib("bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", False) +] +fmlLibsMapping["1.4"] = fml14; +fmlLibsMapping["1.4.1"] = fml14; +fmlLibsMapping["1.4.2"] = fml14; +fmlLibsMapping["1.4.3"] = fml14; +fmlLibsMapping["1.4.4"] = fml14; +fmlLibsMapping["1.4.5"] = fml14; +fmlLibsMapping["1.4.6"] = fml14; +fmlLibsMapping["1.4.7"] = fml14; + +fmlLibsMapping["1.5"] = [ + FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", False), + FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", False), + FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", False), + FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", True), + FMLLib("deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", False), + FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", True) +] + +fmlLibsMapping["1.5.1"] = [ + FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", False), + FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", False), + FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", False), + FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", True), + FMLLib("deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", False), + FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", True) +] + +fmlLibsMapping["1.5.2"] = [ + FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", False), + FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", False), + FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", False), + FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", True), + FMLLib("deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", False), + FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", True) +] + +''' +"install": { + "profileName": "Forge", + "target":"Forge8.9.0.753", + "path":"net.minecraftforge:minecraftforge:8.9.0.753", + "version":"Forge 8.9.0.753", + "filePath":"minecraftforge-universal-1.6.1-8.9.0.753.jar", + "welcome":"Welcome to the simple Forge installer.", + "minecraft":"1.6.1", + "logo":"/big_logo.png", + "mirrorList": "http://files.minecraftforge.net/mirror-brand.list" +}, +"install": { + "profileName": "forge", + "target":"1.11-forge1.11-13.19.0.2141", + "path":"net.minecraftforge:forge:1.11-13.19.0.2141", + "version":"forge 1.11-13.19.0.2141", + "filePath":"forge-1.11-13.19.0.2141-universal.jar", + "welcome":"Welcome to the simple forge installer.", + "minecraft":"1.11", + "mirrorList" : "http://files.minecraftforge.net/mirror-brand.list", + "logo":"/big_logo.png", + "modList":"none" +}, +''' + + +class ForgeInstallerProfileInstallSection(JsonObject): + profileName = StringProperty(required=True) + target = StringProperty(required=True) + path = GradleSpecifierProperty(required=True) + version = StringProperty(required=True) + filePath = StringProperty(required=True) + welcome = StringProperty(required=True) + minecraft = StringProperty(required=True) + logo = StringProperty(required=True) + mirrorList = StringProperty(required=True) + modList = StringProperty(exclude_if_none=True, default=None) + + +class ForgeLibrary(MojangLibrary): + url = StringProperty(exclude_if_none=True) + serverreq = BooleanProperty(exclude_if_none=True, default=None) + clientreq = BooleanProperty(exclude_if_none=True, default=None) + checksums = ListProperty(StringProperty) + comment = StringProperty() + + +class ForgeVersionFile(MojangVersionFile): + libraries = ListProperty(ForgeLibrary, exclude_if_none=True, default=None) # overrides Mojang libraries + inheritsFrom = StringProperty() + jar = StringProperty() + + +''' +"optionals": [ + { + "name": "Mercurius", + "client": true, + "server": true, + "default": true, + "inject": true, + "desc": "A mod that collects statistics about Minecraft and your system.
Useful for Forge to understand how Minecraft/Forge are used.", + "url": "http://www.minecraftforge.net/forum/index.php?topic=43278.0", + "artifact": "net.minecraftforge:MercuriusUpdater:1.11.2", + "maven": "http://files.minecraftforge.net/maven/" + } +] +''' + + +class ForgeOptional(JsonObject): + name = StringProperty() + client = BooleanProperty() + server = BooleanProperty() + default = BooleanProperty() + inject = BooleanProperty() + desc = StringProperty() + url = StringProperty() + artifact = GradleSpecifierProperty() + maven = StringProperty() + + +class ForgeInstallerProfile(JsonObject): + install = ObjectProperty(ForgeInstallerProfileInstallSection, required=True) + versionInfo = ObjectProperty(ForgeVersionFile, required=True) + optionals = ListProperty(ForgeOptional) + + +class ForgeLegacyInfo(JsonObject): + releaseTime = ISOTimestampProperty() + size = IntegerProperty() + sha256 = StringProperty() + sha1 = StringProperty() + + +class ForgeLegacyInfoList(JsonObject): + number = DictProperty(ForgeLegacyInfo) + + +class DataSpec(JsonObject): + client = StringProperty() + server = StringProperty() + + +class ProcessorSpec(JsonObject): + jar = StringProperty() + classpath = ListProperty(StringProperty) + args = ListProperty(StringProperty) + outputs = DictProperty(StringProperty) + sides = ListProperty(StringProperty, exclude_if_none=True, default=None) + + +# Note: This is only used in one version (1.12.2-14.23.5.2851) and we don't even use the installer profile in it. +# It's here just so it parses and we can continue... +class ForgeInstallerProfileV1_5(JsonObject): + _comment = ListProperty(StringProperty) + spec = IntegerProperty() + profile = StringProperty() + version = StringProperty() + icon = StringProperty() + json = StringProperty() + path = GradleSpecifierProperty() + logo = StringProperty() + minecraft = StringProperty() + welcome = StringProperty() + # We don't know what 'data' actually is in this one. It's an empty array + data = ListProperty(StringProperty) + processors = ListProperty(ProcessorSpec) + libraries = ListProperty(MojangLibrary) + mirrorList = StringProperty(exclude_if_none=True, default=None) + + +class ForgeInstallerProfileV2(JsonObject): + _comment = ListProperty(StringProperty) + spec = IntegerProperty() + profile = StringProperty() + version = StringProperty() + icon = StringProperty() + json = StringProperty() + path = GradleSpecifierProperty() + logo = StringProperty() + minecraft = StringProperty() + welcome = StringProperty() + data = DictProperty(DataSpec) + processors = ListProperty(ProcessorSpec) + libraries = ListProperty(MojangLibrary) + mirrorList = StringProperty(exclude_if_none=True, default=None) + serverJarPath = StringProperty(exclude_if_none=True, default=None) + + +class InstallerInfo(JsonObject): + sha1hash = StringProperty() + sha256hash = StringProperty() + size = IntegerProperty() diff --git a/meta/jsonobject/__init__.py b/meta/jsonobject/__init__.py new file mode 100644 index 0000000000..83f41913c4 --- /dev/null +++ b/meta/jsonobject/__init__.py @@ -0,0 +1,17 @@ +# TODO: maybe move to pydantic in the future? + +from __future__ import absolute_import +from .base import JsonObjectMeta +from .containers import JsonArray +from .properties import * +from .base_properties import * +from .api import JsonObject + +__all__ = [ + 'IntegerProperty', 'FloatProperty', 'DecimalProperty', + 'StringProperty', 'BooleanProperty', + 'DateProperty', 'DateTimeProperty', 'TimeProperty', + 'ObjectProperty', 'ListProperty', 'DictProperty', 'SetProperty', + 'JsonObject', 'JsonArray', 'AbstractDateProperty', 'JsonProperty', + 'DefaultProperty' +] diff --git a/meta/jsonobject/api.py b/meta/jsonobject/api.py new file mode 100644 index 0000000000..8b9c4767c1 --- /dev/null +++ b/meta/jsonobject/api.py @@ -0,0 +1,53 @@ +from __future__ import absolute_import +from .base import JsonObjectBase, _LimitedDictInterfaceMixin + +import six +import decimal +import datetime + +from . import properties +import re + +re_date = re.compile(r'^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])$') +re_time = re.compile( + r'^([01]\d|2[0-3])\D?([0-5]\d)\D?([0-5]\d)?\D?(\d{3,6})?$') +re_datetime = re.compile( + r'^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])' + r'(\D?([01]\d|2[0-3])\D?([0-5]\d)\D?([0-5]\d)?\D?(\d{3,6})?' + r'([zZ]|([\+-])([01]\d|2[0-3])\D?([0-5]\d)?)?)?$' +) +re_decimal = re.compile('^(\d+)\.(\d+)$') +if six.PY3: + unicode = str + long = int + + +class JsonObject(JsonObjectBase, _LimitedDictInterfaceMixin): + def __getstate__(self): + return self.to_json() + + def __setstate__(self, dct): + self.__init__(dct) + + class Meta(object): + properties = { + decimal.Decimal: properties.DecimalProperty, + datetime.datetime: properties.DateTimeProperty, + datetime.date: properties.DateProperty, + datetime.time: properties.TimeProperty, + str: properties.StringProperty, + unicode: properties.StringProperty, + bool: properties.BooleanProperty, + int: properties.IntegerProperty, + long: properties.IntegerProperty, + float: properties.FloatProperty, + list: properties.ListProperty, + dict: properties.DictProperty, + set: properties.SetProperty, + } + string_conversions = ( + (re_date, datetime.date), + (re_time, datetime.time), + (re_datetime, datetime.datetime), + (re_decimal, decimal.Decimal), + ) diff --git a/meta/jsonobject/base.py b/meta/jsonobject/base.py new file mode 100644 index 0000000000..90a5f44c6a --- /dev/null +++ b/meta/jsonobject/base.py @@ -0,0 +1,394 @@ +from __future__ import absolute_import +from collections import namedtuple, OrderedDict +import copy +import six +import inspect +from .exceptions import ( + DeleteNotAllowed, + WrappingAttributeError, +) +from .base_properties import JsonProperty, DefaultProperty +from .utils import check_type + +JsonObjectClassSettings = namedtuple('JsonObjectClassSettings', ['type_config']) + +CLASS_SETTINGS_ATTR = '_$_class_settings' + + +def get_settings(cls): + return getattr(cls, CLASS_SETTINGS_ATTR, + JsonObjectClassSettings(type_config=TypeConfig())) + + +def set_settings(cls, settings): + setattr(cls, CLASS_SETTINGS_ATTR, settings) + + +class TypeConfig(object): + """ + This class allows the user to configure dynamic + type handlers and string conversions for their JsonObject. + + properties is a map from python types to JsonProperty subclasses + string_conversions is a list or tuple of (regex, python type)-tuples + + This class is used to store the configuration but is not part of the API. + To configure: + + class Foo(JsonObject): + # property definitions go here + # ... + + class Meta(object): + update_properties = { + datetime.datetime: MySpecialDateTimeProperty + } + # this is already set by default + # but you can override with your own modifications + string_conversions = ((date_re, datetime.date), + (datetime_re, datetime.datetime), + (time_re, datetime.time), + (decimal_re, decimal.Decimal)) + + If you now do + + foo = Foo() + foo.timestamp = datetime.datetime(1988, 7, 7, 11, 8, 0) + + timestamp will be governed by a MySpecialDateTimeProperty + instead of the default. + + """ + + def __init__(self, properties=None, string_conversions=None): + self._properties = properties if properties is not None else {} + + self._string_conversions = ( + OrderedDict(string_conversions) if string_conversions is not None + else OrderedDict() + ) + # cache this + self.string_conversions = self._get_string_conversions() + self.properties = self._properties + + def replace(self, properties=None, string_conversions=None): + return TypeConfig( + properties=(properties if properties is not None + else self._properties), + string_conversions=(string_conversions if string_conversions is not None + else self._string_conversions) + ) + + def updated(self, properties=None, string_conversions=None): + """ + update properties and string_conversions with the paramenters + keeping all non-mentioned items the same as before + returns a new TypeConfig with these changes + (does not modify original) + + """ + _properties = self._properties.copy() + _string_conversions = self.string_conversions[:] + if properties: + _properties.update(properties) + if string_conversions: + _string_conversions.extend(string_conversions) + return TypeConfig( + properties=_properties, + string_conversions=_string_conversions, + ) + + def _get_string_conversions(self): + result = [] + for pattern, conversion in self._string_conversions.items(): + conversion = ( + conversion if conversion not in self._properties + else self._properties[conversion](type_config=self).to_python + ) + result.append((pattern, conversion)) + return result + + +META_ATTRS = ('properties', 'string_conversions', 'update_properties') + + +class JsonObjectMeta(type): + class Meta(object): + pass + + def __new__(mcs, name, bases, dct): + cls = super(JsonObjectMeta, mcs).__new__(mcs, name, bases, dct) + + cls.__configure(**{key: value + for key, value in cls.Meta.__dict__.items() + if key in META_ATTRS}) + cls_settings = get_settings(cls) + + properties = {} + properties_by_name = {} + for key, value in dct.items(): + if isinstance(value, JsonProperty): + properties[key] = value + elif key.startswith('_'): + continue + elif type(value) in cls_settings.type_config.properties: + property_ = cls_settings.type_config.properties[type(value)](default=value) + properties[key] = dct[key] = property_ + setattr(cls, key, property_) + + for key, property_ in properties.items(): + property_.init_property(default_name=key, + type_config=cls_settings.type_config) + assert property_.name is not None, property_ + assert property_.name not in properties_by_name, \ + 'You can only have one property named {0}'.format( + property_.name) + properties_by_name[property_.name] = property_ + + for base in bases: + if getattr(base, '_properties_by_attr', None): + for key, value in base._properties_by_attr.items(): + if key not in properties: + properties[key] = value + properties_by_name[value.name] = value + + cls._properties_by_attr = properties + cls._properties_by_key = properties_by_name + return cls + + def __configure(cls, properties=None, string_conversions=None, + update_properties=None): + super_settings = get_settings(super(cls, cls)) + assert not properties or not update_properties, \ + "{} {}".format(properties, update_properties) + type_config = super_settings.type_config + if update_properties is not None: + type_config = type_config.updated(properties=update_properties) + elif properties is not None: + type_config = type_config.replace(properties=properties) + if string_conversions is not None: + type_config = type_config.replace( + string_conversions=string_conversions) + set_settings(cls, super_settings._replace(type_config=type_config)) + return cls + + +class _JsonObjectPrivateInstanceVariables(object): + + def __init__(self, dynamic_properties=None): + self.dynamic_properties = dynamic_properties or {} + + +@six.add_metaclass(JsonObjectMeta) +class JsonObjectBase(object): + _allow_dynamic_properties = False + _validate_required_lazily = False + + _properties_by_attr = None + _properties_by_key = None + + _string_conversions = () + + def __init__(self, _obj=None, **kwargs): + setattr(self, '_$', _JsonObjectPrivateInstanceVariables()) + + self._obj = check_type(_obj, dict, + 'JsonObject must wrap a dict or None') + self._wrapped = {} + + for key, value in self._obj.items(): + try: + self.set_raw_value(key, value) + except AttributeError: + raise WrappingAttributeError( + "can't set attribute corresponding to {key!r} " + "on a {cls} while wrapping {data!r}".format( + cls=self.__class__, + key=key, + data=_obj, + ) + ) + + for attr, value in kwargs.items(): + try: + setattr(self, attr, value) + except AttributeError: + raise WrappingAttributeError( + "can't set attribute {key!r} " + "on a {cls} while wrapping {data!r}".format( + cls=self.__class__, + key=attr, + data=_obj, + ) + ) + + for key, value in self._properties_by_key.items(): + if key not in self._obj: + try: + d = value.default() + except TypeError: + d = value.default(self) + self[key] = d + + def set_raw_value(self, key, value): + wrapped = self.__wrap(key, value) + if key in self._properties_by_key: + self[key] = wrapped + else: + setattr(self, key, wrapped) + + @classmethod + def properties(cls): + return cls._properties_by_attr.copy() + + @property + def __dynamic_properties(self): + return getattr(self, '_$').dynamic_properties + + @classmethod + def wrap(cls, obj): + self = cls(obj) + return self + + def validate(self, required=True): + for key, value in self._wrapped.items(): + self.__get_property(key).validate(value, required=required) + + def to_json(self): + self.validate() + return copy.deepcopy(self._obj) + + def __get_property(self, key): + try: + return self._properties_by_key[key] + except KeyError: + return DefaultProperty(type_config=get_settings(self).type_config) + + def __wrap(self, key, value): + property_ = self.__get_property(key) + + if value is None: + return None + + return property_.wrap(value) + + def __unwrap(self, key, value): + property_ = self.__get_property(key) + try: + property_.validate( + value, + required=not self._validate_required_lazily, + recursive=False, + ) + except TypeError: + property_.validate( + value, + required=not self._validate_required_lazily, + ) + if value is None: + return None, None + + return property_.unwrap(value) + + def __setitem__(self, key, value): + wrapped, unwrapped = self.__unwrap(key, value) + self._wrapped[key] = wrapped + if self.__get_property(key).exclude(unwrapped): + self._obj.pop(key, None) + else: + self._obj[key] = unwrapped + if key not in self._properties_by_key: + assert key not in self._properties_by_attr + self.__dynamic_properties[key] = wrapped + super(JsonObjectBase, self).__setattr__(key, wrapped) + + def __is_dynamic_property(self, name): + return ( + name not in self._properties_by_attr and + not name.startswith('_') and + not inspect.isdatadescriptor(getattr(self.__class__, name, None)) + ) + + def __setattr__(self, name, value): + if self.__is_dynamic_property(name): + if self._allow_dynamic_properties: + self[name] = value + else: + raise AttributeError( + "{0!r} is not defined in schema " + "(not a valid property)".format(name) + ) + else: + super(JsonObjectBase, self).__setattr__(name, value) + + def __delitem__(self, key): + if key in self._properties_by_key: + raise DeleteNotAllowed(key) + else: + if not self.__is_dynamic_property(key): + raise KeyError(key) + del self._obj[key] + del self._wrapped[key] + del self.__dynamic_properties[key] + super(JsonObjectBase, self).__delattr__(key) + + def __delattr__(self, name): + if name in self._properties_by_attr: + raise DeleteNotAllowed(name) + elif self.__is_dynamic_property(name): + del self[name] + else: + super(JsonObjectBase, self).__delattr__(name) + + def __repr__(self): + name = self.__class__.__name__ + predefined_properties = self._properties_by_attr.keys() + predefined_property_keys = set(self._properties_by_attr[p].name + for p in predefined_properties) + dynamic_properties = (set(self._wrapped.keys()) + - predefined_property_keys) + properties = sorted(predefined_properties) + sorted(dynamic_properties) + return u'{name}({keyword_args})'.format( + name=name, + keyword_args=', '.join('{key}={value!r}'.format( + key=key, + value=getattr(self, key) + ) for key in properties), + ) + + +class _LimitedDictInterfaceMixin(object): + """ + mindlessly farms selected dict methods out to an internal dict + + really only a separate class from JsonObject + to keep this mindlessness separate from the methods + that need to be more carefully understood + + """ + _wrapped = None + + def keys(self): + return self._wrapped.keys() + + def items(self): + return self._wrapped.items() + + def iteritems(self): + return self._wrapped.iteritems() + + def __contains__(self, item): + return item in self._wrapped + + def __getitem__(self, item): + return self._wrapped[item] + + def __iter__(self): + return iter(self._wrapped) + + def __len__(self): + return len(self._wrapped) + + +def get_dynamic_properties(obj): + return getattr(obj, '_$').dynamic_properties.copy() diff --git a/meta/jsonobject/base_properties.py b/meta/jsonobject/base_properties.py new file mode 100644 index 0000000000..b43b1d44e2 --- /dev/null +++ b/meta/jsonobject/base_properties.py @@ -0,0 +1,320 @@ +from __future__ import absolute_import +import six +import inspect +from .exceptions import BadValueError + +function_name = None +if six.PY3: + def function_name(f): + return f.__name__ +else: + def function_name(f): + return f.func_name + + +class JsonProperty(object): + default = None + type_config = None + + def __init__(self, default=Ellipsis, name=None, choices=None, + required=False, exclude_if_none=False, validators=None, + verbose_name=None, type_config=None): + validators = validators or () + self.name = name + if default is Ellipsis: + default = self.default + if callable(default): + self.default = default + else: + self.default = lambda: default + self.choices = choices + self.choice_keys = [] + if choices: + for choice in choices: + if isinstance(choice, tuple): + choice, _ = choice + self.choice_keys.append(choice) + self.required = required + self.exclude_if_none = exclude_if_none + self._validators = validators + self.verbose_name = verbose_name + if type_config: + self.type_config = type_config + + def init_property(self, default_name, type_config): + self.name = self.name or default_name + self.type_config = self.type_config or type_config + + def wrap(self, obj): + raise NotImplementedError() + + def unwrap(self, obj): + """ + must return tuple of (wrapped, unwrapped) + + If obj is already a fully wrapped object, + it must be returned as the first element. + + For an example where the first element is relevant see ListProperty + + """ + raise NotImplementedError() + + def to_json(self, value): + _, unwrapped = self.unwrap(value) + return unwrapped + + def to_python(self, value): + return self.wrap(value) + + def __get__(self, instance, owner): + if instance: + assert self.name in instance + return instance[self.name] + else: + return self + + def __set__(self, instance, value): + instance[self.name] = value + + def __call__(self, method): + """ + use a property as a decorator to set its default value + + class Document(JsonObject): + @StringProperty() + def doc_type(self): + return self.__class__.__name__ + """ + assert self.default() is None + self.default = method + self.name = self.name or function_name(method) + return self + + def exclude(self, value): + return self.exclude_if_none and value == None + + def empty(self, value): + return value is None + + def validate(self, value, required=True, recursive=True): + if (self.choice_keys and value not in self.choice_keys + and value is not None): + raise BadValueError( + '{0!r} not in choices: {1!r}'.format(value, self.choice_keys) + ) + + if not self.empty(value): + self._custom_validate(value) + elif required and self.required: + raise BadValueError( + 'Property {0} is required.'.format(self.name) + ) + if recursive and hasattr(value, 'validate'): + value.validate(required=required) + + def _custom_validate(self, value): + if self._validators: + if hasattr(self._validators, '__iter__'): + for validator in self._validators: + validator(value) + else: + self._validators(value) + + +class JsonContainerProperty(JsonProperty): + _type = default = None + container_class = None + + def __init__(self, item_type=None, **kwargs): + self._item_type_deferred = item_type + super(JsonContainerProperty, self).__init__(**kwargs) + + def init_property(self, **kwargs): + super(JsonContainerProperty, self).init_property(**kwargs) + if not inspect.isfunction(self._item_type_deferred): + # trigger validation + self.item_type + + def set_item_type(self, item_type): + from meta.jsonobject.base import JsonObjectMeta + if hasattr(item_type, '_type'): + item_type = item_type._type + if isinstance(item_type, tuple): + # this is for the case where item_type = (int, long) + item_type = item_type[0] + allowed_types = set(self.type_config.properties.keys()) + if isinstance(item_type, JsonObjectMeta) \ + or not item_type or item_type in allowed_types: + self._item_type = item_type + else: + raise ValueError("item_type {0!r} not in {1!r}".format( + item_type, + allowed_types, + )) + + @property + def item_type(self): + if hasattr(self, '_item_type_deferred'): + if inspect.isfunction(self._item_type_deferred): + self.set_item_type(self._item_type_deferred()) + else: + self.set_item_type(self._item_type_deferred) + del self._item_type_deferred + return self._item_type + + def empty(self, value): + return not value + + def wrap(self, obj): + wrapper = self.type_to_property(self.item_type) if self.item_type else None + return self.container_class(obj, wrapper=wrapper, + type_config=self.type_config) + + def type_to_property(self, item_type): + map_types_properties = self.type_config.properties + from .properties import ObjectProperty + from .base import JsonObjectBase + if issubclass(item_type, JsonObjectBase): + return ObjectProperty(item_type, type_config=self.type_config) + elif item_type in map_types_properties: + return map_types_properties[item_type](type_config=self.type_config) + else: + for key, value in map_types_properties.items(): + if issubclass(item_type, key): + return value(type_config=self.type_config) + raise TypeError('Type {0} not recognized'.format(item_type)) + + def unwrap(self, obj): + if not isinstance(obj, self._type): + raise BadValueError( + '{0!r} is not an instance of {1!r}'.format( + obj, self._type.__name__) + ) + if isinstance(obj, self.container_class): + return obj, obj._obj + else: + wrapped = self.wrap(self._type()) + self._update(wrapped, obj) + return self.unwrap(wrapped) + + def _update(self, container, extension): + raise NotImplementedError() + + +class DefaultProperty(JsonProperty): + + def wrap(self, obj): + assert self.type_config.string_conversions is not None + value = self.value_to_python(obj) + property_ = self.value_to_property(value) + + if property_: + return property_.wrap(obj) + + def unwrap(self, obj): + property_ = self.value_to_property(obj) + if property_: + return property_.unwrap(obj) + else: + return obj, None + + def value_to_property(self, value): + map_types_properties = self.type_config.properties + if value is None: + return None + elif type(value) in map_types_properties: + return map_types_properties[type(value)]( + type_config=self.type_config) + else: + for value_type, prop_class in map_types_properties.items(): + if isinstance(value, value_type): + return prop_class(type_config=self.type_config) + else: + raise BadValueError( + 'value {0!r} not in allowed types: {1!r}'.format( + value, map_types_properties.keys()) + ) + + def value_to_python(self, value): + """ + convert encoded string values to the proper python type + + ex: + >>> DefaultProperty().value_to_python('2013-10-09T10:05:51Z') + datetime.datetime(2013, 10, 9, 10, 5, 51) + + other values will be passed through unmodified + Note: containers' items are NOT recursively converted + + """ + if isinstance(value, six.string_types): + convert = None + for pattern, _convert in self.type_config.string_conversions: + if pattern.match(value): + convert = _convert + break + + if convert is not None: + try: + # sometimes regex fail so return value + value = convert(value) + except Exception: + pass + return value + + +class AssertTypeProperty(JsonProperty): + _type = None + + def assert_type(self, obj): + if not isinstance(obj, self._type): + raise BadValueError( + '{0!r} not of type {1!r}'.format(obj, self._type) + ) + + def selective_coerce(self, obj): + return obj + + def wrap(self, obj): + obj = self.selective_coerce(obj) + self.assert_type(obj) + return obj + + def unwrap(self, obj): + obj = self.selective_coerce(obj) + self.assert_type(obj) + return obj, obj + + +class AbstractDateProperty(JsonProperty): + _type = None + + def __init__(self, exact=False, *args, **kwargs): + super(AbstractDateProperty, self).__init__(*args, **kwargs) + self.exact = exact + + def wrap(self, obj): + try: + if not isinstance(obj, six.string_types): + raise ValueError() + return self._wrap(obj) + except ValueError: + raise BadValueError('{0!r} is not a {1}-formatted string'.format( + obj, + self._type.__name__, + )) + + def unwrap(self, obj): + if not isinstance(obj, self._type): + raise BadValueError('{0!r} is not a {1} object'.format( + obj, + self._type.__name__, + )) + return self._unwrap(obj) + + def _wrap(self, obj): + raise NotImplementedError() + + def _unwrap(self, obj): + raise NotImplementedError() diff --git a/meta/jsonobject/containers.py b/meta/jsonobject/containers.py new file mode 100644 index 0000000000..1150ab9d23 --- /dev/null +++ b/meta/jsonobject/containers.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import +from .base_properties import DefaultProperty +from .utils import check_type, SimpleDict +import copy + + +class JsonArray(list): + def __init__(self, _obj=None, wrapper=None, type_config=None): + super(JsonArray, self).__init__() + self._obj = check_type(_obj, list, + 'JsonArray must wrap a list or None') + + assert type_config is not None + self._type_config = type_config + self._wrapper = ( + wrapper or + DefaultProperty(type_config=self._type_config) + ) + for item in self._obj: + super(JsonArray, self).append(self._wrapper.wrap(item)) + + def validate(self, required=True): + for obj in self: + self._wrapper.validate(obj, required=required) + + def to_json(self): + self.validate() + return copy.deepcopy(self._obj) + + def append(self, wrapped): + wrapped, unwrapped = self._wrapper.unwrap(wrapped) + self._obj.append(unwrapped) + super(JsonArray, self).append(wrapped) + + def __delitem__(self, i): + super(JsonArray, self).__delitem__(i) + del self._obj[i] + + def __setitem__(self, i, wrapped): + wrapped, unwrapped = self._wrapper.unwrap(wrapped) + self._obj[i] = unwrapped + super(JsonArray, self).__setitem__(i, wrapped) + + def extend(self, wrapped_list): + if wrapped_list: + wrapped_list, unwrapped_list = zip( + *map(self._wrapper.unwrap, wrapped_list) + ) + else: + unwrapped_list = [] + self._obj.extend(unwrapped_list) + super(JsonArray, self).extend(wrapped_list) + + def insert(self, index, wrapped): + wrapped, unwrapped = self._wrapper.unwrap(wrapped) + self._obj.insert(index, unwrapped) + super(JsonArray, self).insert(index, wrapped) + + def remove(self, value): + i = self.index(value) + super(JsonArray, self).remove(value) + self._obj.pop(i) + + def pop(self, index=-1): + self._obj.pop(index) + return super(JsonArray, self).pop(index) + + def sort(self, cmp=None, key=None, reverse=False): + zipped = zip(self, self._obj) + if key: + new_key = lambda pair: key(pair[0]) + zipped.sort(key=new_key, reverse=reverse) + elif cmp: + new_cmp = lambda pair1, pair2: cmp(pair1[0], pair2[0]) + zipped.sort(cmp=new_cmp, reverse=reverse) + else: + zipped.sort(reverse=reverse) + + wrapped_list, unwrapped_list = zip(*zipped) + while self: + self.pop() + super(JsonArray, self).extend(wrapped_list) + self._obj.extend(unwrapped_list) + + def reverse(self): + self._obj.reverse() + super(JsonArray, self).reverse() + + def __fix_slice(self, i, j): + length = len(self) + if j < 0: + j += length + if i < 0: + i += length + if i > length: + i = length + if j > length: + j = length + return i, j + + def __setslice__(self, i, j, sequence): + i, j = self.__fix_slice(i, j) + for _ in range(j - i): + self.pop(i) + for k, wrapped in enumerate(sequence): + self.insert(i + k, wrapped) + + def __delslice__(self, i, j): + i, j = self.__fix_slice(i, j) + for _ in range(j - i): + self.pop(i) + + +class JsonDict(SimpleDict): + + def __init__(self, _obj=None, wrapper=None, type_config=None): + super(JsonDict, self).__init__() + self._obj = check_type(_obj, dict, 'JsonDict must wrap a dict or None') + assert type_config is not None + self._type_config = type_config + self._wrapper = ( + wrapper or + DefaultProperty(type_config=self._type_config) + ) + for key, value in self._obj.items(): + self[key] = self.__wrap(key, value) + + def validate(self, required=True): + for obj in self.values(): + self._wrapper.validate(obj, required=required) + + def __wrap(self, key, unwrapped): + return self._wrapper.wrap(unwrapped) + + def __unwrap(self, key, wrapped): + return self._wrapper.unwrap(wrapped) + + def __setitem__(self, key, value): + if isinstance(key, int): + key = str(key) + + wrapped, unwrapped = self.__unwrap(key, value) + self._obj[key] = unwrapped + super(JsonDict, self).__setitem__(key, wrapped) + + def __delitem__(self, key): + del self._obj[key] + super(JsonDict, self).__delitem__(key) + + def __getitem__(self, key): + if isinstance(key, int): + key = str(key) + return super(JsonDict, self).__getitem__(key) + + +class JsonSet(set): + def __init__(self, _obj=None, wrapper=None, type_config=None): + super(JsonSet, self).__init__() + if isinstance(_obj, set): + _obj = list(_obj) + self._obj = check_type(_obj, list, 'JsonSet must wrap a list or None') + assert type_config is not None + self._type_config = type_config + self._wrapper = ( + wrapper or + DefaultProperty(type_config=self._type_config) + ) + for item in self._obj: + super(JsonSet, self).add(self._wrapper.wrap(item)) + + def validate(self, required=True): + for obj in self: + self._wrapper.validate(obj, required=required) + + def add(self, wrapped): + wrapped, unwrapped = self._wrapper.unwrap(wrapped) + if wrapped not in self: + self._obj.append(unwrapped) + super(JsonSet, self).add(wrapped) + + def remove(self, wrapped): + wrapped, unwrapped = self._wrapper.unwrap(wrapped) + if wrapped in self: + self._obj.remove(unwrapped) + super(JsonSet, self).remove(wrapped) + else: + raise KeyError(wrapped) + + def discard(self, wrapped): + try: + self.remove(wrapped) + except KeyError: + pass + + def pop(self): + # get first item + for wrapped in self: + break + else: + raise KeyError() + wrapped_, unwrapped = self._wrapper.unwrap(wrapped) + assert wrapped is wrapped_ + self.remove(unwrapped) + return wrapped + + def clear(self): + while self: + self.pop() + + def __ior__(self, other): + for wrapped in other: + self.add(wrapped) + return self + + def update(self, *args): + for wrapped_list in args: + self |= set(wrapped_list) + + union_update = update + + def __iand__(self, other): + for wrapped in list(self): + if wrapped not in other: + self.remove(wrapped) + return self + + def intersection_update(self, *args): + for wrapped_list in args: + self &= set(wrapped_list) + + def __isub__(self, other): + for wrapped in list(self): + if wrapped in other: + self.remove(wrapped) + return self + + def difference_update(self, *args): + for wrapped_list in args: + self -= set(wrapped_list) + + def __ixor__(self, other): + removed = set() + for wrapped in list(self): + if wrapped in other: + self.remove(wrapped) + removed.add(wrapped) + self.update(other - removed) + return self + + def symmetric_difference_update(self, *args): + for wrapped_list in args: + self ^= set(wrapped_list) diff --git a/meta/jsonobject/exceptions.py b/meta/jsonobject/exceptions.py new file mode 100644 index 0000000000..a42022e120 --- /dev/null +++ b/meta/jsonobject/exceptions.py @@ -0,0 +1,10 @@ +class DeleteNotAllowed(Exception): + pass + + +class BadValueError(Exception): + """raised when a value can't be validated or is required""" + + +class WrappingAttributeError(AttributeError): + pass diff --git a/meta/jsonobject/properties.py b/meta/jsonobject/properties.py new file mode 100644 index 0000000000..05bba86da9 --- /dev/null +++ b/meta/jsonobject/properties.py @@ -0,0 +1,155 @@ +# DateTimeProperty, DateProperty, and TimeProperty +# include code copied from couchdbkit +from __future__ import absolute_import +import sys +import datetime +import time +import decimal +from .base_properties import ( + AbstractDateProperty, + AssertTypeProperty, + JsonContainerProperty, + JsonProperty, + DefaultProperty, +) +from .containers import JsonArray, JsonDict, JsonSet + +if sys.version > '3': + unicode = str + long = int + + +class StringProperty(AssertTypeProperty): + _type = (unicode, str) + + def selective_coerce(self, obj): + if isinstance(obj, str): + obj = unicode(obj) + return obj + + +class BooleanProperty(AssertTypeProperty): + _type = bool + + +class IntegerProperty(AssertTypeProperty): + _type = (int, long) + + +class FloatProperty(AssertTypeProperty): + _type = float + + def selective_coerce(self, obj): + if isinstance(obj, (int, long)): + obj = float(obj) + return obj + + +class DecimalProperty(JsonProperty): + + def wrap(self, obj): + return decimal.Decimal(obj) + + def unwrap(self, obj): + if isinstance(obj, (int, long)): + obj = decimal.Decimal(obj) + elif isinstance(obj, float): + # python 2.6 doesn't allow a float to Decimal + obj = decimal.Decimal(unicode(obj)) + assert isinstance(obj, decimal.Decimal) + return obj, unicode(obj) + + +class DateProperty(AbstractDateProperty): + _type = datetime.date + + def _wrap(self, value): + fmt = '%Y-%m-%d' + try: + return datetime.date(*time.strptime(value, fmt)[:3]) + except ValueError as e: + raise ValueError('Invalid ISO date {0!r} [{1}]'.format(value, e)) + + def _unwrap(self, value): + return value, value.isoformat() + + +class DateTimeProperty(AbstractDateProperty): + _type = datetime.datetime + + def _wrap(self, value): + if not self.exact: + value = value.split('.', 1)[0] # strip out microseconds + value = value[0:19] # remove timezone + fmt = '%Y-%m-%dT%H:%M:%S' + else: + fmt = '%Y-%m-%dT%H:%M:%S.%fZ' + try: + return datetime.datetime.strptime(value, fmt) + except ValueError as e: + raise ValueError( + 'Invalid ISO date/time {0!r} [{1}]'.format(value, e)) + + def _unwrap(self, value): + if not self.exact: + value = value.replace(microsecond=0) + padding = '' + else: + padding = '' if value.microsecond else '.000000' + return value, value.isoformat() + padding + 'Z' + + +class TimeProperty(AbstractDateProperty): + _type = datetime.time + + def _wrap(self, value): + if not self.exact: + value = value.split('.', 1)[0] # strip out microseconds + fmt = '%H:%M:%S' + else: + fmt = '%H:%M:%S.%f' + try: + return datetime.time(*time.strptime(value, fmt)[3:6]) + except ValueError as e: + raise ValueError('Invalid ISO time {0!r} [{1}]'.format(value, e)) + + def _unwrap(self, value): + if not self.exact: + value = value.replace(microsecond=0) + return value, value.isoformat() + + +class ObjectProperty(JsonContainerProperty): + default = lambda self: self.item_type() + + def wrap(self, obj, string_conversions=None): + return self.item_type.wrap(obj) + + def unwrap(self, obj): + assert isinstance(obj, self.item_type), \ + '{0} is not an instance of {1}'.format(obj, self.item_type) + return obj, obj._obj + + +class ListProperty(JsonContainerProperty): + _type = default = list + container_class = JsonArray + + def _update(self, container, extension): + container.extend(extension) + + +class DictProperty(JsonContainerProperty): + _type = default = dict + container_class = JsonDict + + def _update(self, container, extension): + container.update(extension) + + +class SetProperty(JsonContainerProperty): + _type = default = set + container_class = JsonSet + + def _update(self, container, extension): + container.update(extension) diff --git a/meta/jsonobject/utils.py b/meta/jsonobject/utils.py new file mode 100644 index 0000000000..9ee8569801 --- /dev/null +++ b/meta/jsonobject/utils.py @@ -0,0 +1,57 @@ +from __future__ import absolute_import +from .exceptions import BadValueError + + +def check_type(obj, item_type, message): + if obj is None: + return item_type() + elif not isinstance(obj, item_type): + raise BadValueError('{}. Found object of type: {}'.format(message, type(obj))) + else: + return obj + + +class SimpleDict(dict): + """ + Re-implements destructive methods of dict + to use only setitem and getitem and delitem + """ + + def update(self, E=None, **F): + for dct in (E, F): + if dct: + for key, value in dct.items(): + self[key] = value + + def clear(self): + for key in list(self.keys()): + del self[key] + + def pop(self, key, *args): + if len(args) > 1: + raise TypeError('pop expected at most 2 arguments, got 3') + try: + val = self[key] + del self[key] + return val + except KeyError: + try: + return args[0] + except IndexError: + raise KeyError(key) + + def popitem(self): + try: + arbitrary_key = list(self.keys())[0] + except IndexError: + raise KeyError('popitem(): dictionary is empty') + val = self[arbitrary_key] + del self[arbitrary_key] + return (arbitrary_key, val) + + def setdefault(self, key, default=None): + try: + return self[key] + except KeyError: + self[key] = default + return default diff --git a/meta/liteloaderutil.py b/meta/liteloaderutil.py new file mode 100644 index 0000000000..dce6cb19d4 --- /dev/null +++ b/meta/liteloaderutil.py @@ -0,0 +1,118 @@ +from .metautil import * + +''' + "repo":{ + "stream":"RELEASE", + "type":"m2", + "url":"http:\/\/dl.liteloader.com\/repo\/", + "classifier":"" + }, +''' + + +class LiteloaderRepo(JsonObject): + stream = StringProperty(required=True) + type = StringProperty(required=True) + url = StringProperty(required=True) + classifier = StringProperty(required=True) + + +''' + "53639d52340479ccf206a04f5e16606f":{ + "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", + "libraries":[ + { + "name":"net.minecraft:launchwrapper:1.5" + }, + { + "name":"net.sf.jopt-simple:jopt-simple:4.5" + }, + { + "name":"org.ow2.asm:asm-all:4.1" + } + ], + "stream":"RELEASE", + "file":"liteloader-1.5.2_01.jar", + "version":"1.5.2_01", + "md5":"53639d52340479ccf206a04f5e16606f", + "timestamp":"1367366420" + }, +''' + + +class LiteloaderArtefact(JsonObject): + tweakClass = StringProperty(required=True) + libraries = ListProperty(PolyMCLibrary, required=True) + stream = StringProperty(required=True) + file = StringProperty(required=True) + version = StringProperty(required=True) + build = StringProperty(default=None, exclude_if_none=True) + md5 = StringProperty(required=True) + timestamp = StringProperty(required=True) + srcJar = StringProperty(default=None, exclude_if_none=True) + mcpJar = StringProperty(default=None, exclude_if_none=True) + + +class LiteloaderDev(JsonObject): + fgVersion = StringProperty(default=None, exclude_if_none=True) + mappings = StringProperty(required=None, exclude_if_none=True) + mcp = StringProperty(default=None, exclude_if_none=True) + + +class LiteloaderArtefacts(JsonObject): + liteloader = DictProperty(LiteloaderArtefact, name="com.mumfrey:liteloader", required=True) + + +class LiteloaderSnapshot(LiteloaderArtefact): + lastSuccessfulBuild = IntegerProperty() + + +class LiteloaderSnapshots(JsonObject): + libraries = ListProperty(PolyMCLibrary, required=True) + liteloader = DictProperty(LiteloaderSnapshot, name="com.mumfrey:liteloader", required=True) + + +''' + "1.10.2":{ + "dev": { ... }, + "repo":{ ... }, + "artefacts":{ + "com.mumfrey:liteloader":{ }, + ... + }, + "snapshots":{ + ... + } +''' + + +class LiteloaderEntry(JsonObject): + dev = ObjectProperty(LiteloaderDev, default=None, exclude_if_none=True) + repo = ObjectProperty(LiteloaderRepo, required=True) + artefacts = ObjectProperty(LiteloaderArtefacts, default=None, exclude_if_none=True) + snapshots = ObjectProperty(LiteloaderSnapshots, default=None, exclude_if_none=True) + + +''' + "meta":{ + "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", + "authors":"Mumfrey", + "url":"http:\/\/dl.liteloader.com", + "updated":"2017-02-22T11:34:07+00:00", + "updatedTime":1487763247 + }, +''' + + +class LiteloaderMeta(JsonObject): + description = StringProperty(required=True) + authors = StringProperty(required=True) + url = StringProperty(required=True) + updated = ISOTimestampProperty(required=True) + updatedTime = IntegerProperty(required=True) + + +# The raw Forge version index +class LiteloaderIndex(JsonObject): + meta = ObjectProperty(LiteloaderMeta, required=True) + versions = DictProperty(LiteloaderEntry) diff --git a/meta/metautil.py b/meta/metautil.py new file mode 100644 index 0000000000..e417bd6e65 --- /dev/null +++ b/meta/metautil.py @@ -0,0 +1,477 @@ +import datetime +import json +import os + +import iso8601 +from .jsonobject import * + +PMC_DIR = os.environ["PMC_DIR"] + + +class ISOTimestampProperty(AbstractDateProperty): + _type = datetime.datetime + + def _wrap(self, value): + try: + return iso8601.parse_date(value) + except ValueError as e: + raise ValueError( + 'Invalid ISO date/time {0!r} [{1}]'.format(value, e)) + + def _unwrap(self, value): + return value, value.isoformat() + + +class GradleSpecifier: + ''' + A gradle specifier - a maven coordinate. Like one of these: + "org.lwjgl.lwjgl:lwjgl:2.9.0" + "net.java.jinput:jinput:2.0.5" + "net.minecraft:launchwrapper:1.5" + ''' + + def __init__(self, name): + atSplit = name.split('@') + + components = atSplit[0].split(':') + self.group = components[0] + self.artifact = components[1] + self.version = components[2] + + self.extension = 'jar' + if len(atSplit) == 2: + self.extension = atSplit[1] + + if len(components) == 4: + self.classifier = components[3] + else: + self.classifier = None + + def toString(self): + extensionStr = '' + if self.extension != 'jar': + extensionStr = "@%s" % self.extension + if self.classifier: + return "%s:%s:%s:%s%s" % (self.group, self.artifact, self.version, self.classifier, extensionStr) + else: + return "%s:%s:%s%s" % (self.group, self.artifact, self.version, extensionStr) + + def getFilename(self): + if self.classifier: + return "%s-%s-%s.%s" % (self.artifact, self.version, self.classifier, self.extension) + else: + return "%s-%s.%s" % (self.artifact, self.version, self.extension) + + def getBase(self): + return "%s/%s/%s/" % (self.group.replace('.', '/'), self.artifact, self.version) + + def getPath(self): + return self.getBase() + self.getFilename() + + def __repr__(self): + return "GradleSpecifier('" + self.toString() + "')" + + def isLwjgl(self): + return self.group in ("org.lwjgl", "org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils") + + def isLog4j(self): + return self.group == "org.apache.logging.log4j" + + def __lt__(self, other): + return self.toString() < other.toString() + + def __eq__(self, other): + return self.group == other.group and self.artifact == other.artifact and self.version == other.version and self.classifier == other.classifier + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return self.toString().__hash__() + + +class GradleSpecifierProperty(JsonProperty): + def wrap(self, value): + return GradleSpecifier(value) + + def unwrap(self, value): + 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) + url = StringProperty() + + +class MojangArtifact(MojangArtifactBase): + path = StringProperty(exclude_if_none=True, default=None) + + +class MojangAssets(MojangArtifactBase): + id = StringProperty() + totalSize = IntegerProperty() + + +class MojangLibraryDownloads(JsonObject): + artifact = ObjectProperty(MojangArtifact, exclude_if_none=True, default=None) + classifiers = DictProperty(MojangArtifact, exclude_if_none=True, default=None) + + +class MojangLibraryExtractRules(JsonObject): + exclude = ListProperty(StringProperty) + + +''' + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + } + ] +''' + + +class OSRule(JsonObject): + name = StringProperty(choices=["osx", "linux", "windows"], required=True) + version = StringProperty(exclude_if_none=True, default=None) + + +class MojangRule(JsonObject): + action = StringProperty(choices=["allow", "disallow"], required=True) + os = ObjectProperty(OSRule, exclude_if_none=True, default=None) + + +class MojangLibrary(JsonObject): + extract = ObjectProperty(MojangLibraryExtractRules, exclude_if_none=True, default=None) + name = GradleSpecifierProperty(required=True) + downloads = ObjectProperty(MojangLibraryDownloads, exclude_if_none=True, default=None) + natives = DictProperty(StringProperty, exclude_if_none=True, default=None) + rules = ListProperty(MojangRule, exclude_if_none=True, default=None) + + +class MojangLoggingArtifact(MojangArtifactBase): + id = StringProperty() + + +class MojangLogging(JsonObject): + file = ObjectProperty(MojangLoggingArtifact, required=True) + argument = StringProperty(required=True) + type = StringProperty(required=True, choices=["log4j2-xml"]) + + +class MojangArguments(JsonObject): + game = ListProperty(exclude_if_none=True, default=None) + jvm = ListProperty(exclude_if_none=True, default=None) + + +class JavaVersion(JsonObject): + component = StringProperty(default="jre-legacy") + majorVersion = IntegerProperty(default=8) + + +class UnknownVersionException(Exception): + """Exception raised for unknown Mojang version file format versions. + + Attributes: + message -- explanation of the error + """ + + def __init__(self, message): + self.message = message + + +def validateSupportedMojangVersion(version): + supportedVersion = 21 + if version > supportedVersion: + raise UnknownVersionException( + "Unsupported Mojang format version: %d. Max supported is: %d" % (version, supportedVersion)) + + +class MojangVersionFile(JsonObject): + arguments = ObjectProperty(MojangArguments, exclude_if_none=True, default=None) + assetIndex = ObjectProperty(MojangAssets, exclude_if_none=True, default=None) + assets = StringProperty(exclude_if_none=True, default=None) + downloads = DictProperty(MojangArtifactBase, exclude_if_none=True, default=None) + id = StringProperty(exclude_if_none=True, default=None) + libraries = ListProperty(MojangLibrary, exclude_if_none=True, default=None) + mainClass = StringProperty(exclude_if_none=True, default=None) + processArguments = StringProperty(exclude_if_none=True, default=None) + minecraftArguments = StringProperty(exclude_if_none=True, default=None) + minimumLauncherVersion = IntegerProperty(exclude_if_none=True, default=None, + validators=validateSupportedMojangVersion) + releaseTime = ISOTimestampProperty(exclude_if_none=True, default=None) + time = ISOTimestampProperty(exclude_if_none=True, default=None) + type = StringProperty(exclude_if_none=True, default=None) + inheritsFrom = StringProperty(exclude_if_none=True, default=None) + logging = DictProperty(MojangLogging, exclude_if_none=True, default=None) + complianceLevel = IntegerProperty(exclude_if_none=True, default=None) + javaVersion = ObjectProperty(JavaVersion, exclude_if_none=True, default=None) + + +CurrentPolyMCFormatVersion = 1 + + +def validateSupportedPolyMCVersion(version): + if version > CurrentPolyMCFormatVersion: + raise UnknownVersionException( + "Unsupported PolyMC format version: %d. Max supported is: %d" % (version, CurrentPolyMCFormatVersion)) + + +class PolyMCLibrary(MojangLibrary): + url = StringProperty(exclude_if_none=True, default=None) + mmcHint = StringProperty(name="MMC-hint", exclude_if_none=True, default=None) # this is supposed to be MMC-hint! + + +class VersionedJsonObject(JsonObject): + formatVersion = IntegerProperty(default=CurrentPolyMCFormatVersion, validators=validateSupportedPolyMCVersion) + + +class DependencyEntry(JsonObject): + uid = StringProperty(required=True) + equals = StringProperty(exclude_if_none=True, default=None) + suggests = StringProperty(exclude_if_none=True, default=None) + + +class PolyMCVersionFile(VersionedJsonObject): + name = StringProperty(required=True) + version = StringProperty(required=True) + uid = StringProperty(required=True) + requires = ListProperty(DependencyEntry, exclude_if_none=True, default=None) + conflicts = ListProperty(DependencyEntry, exclude_if_none=True, default=None) + volatile = BooleanProperty(exclude_if_none=True, default=None) + assetIndex = ObjectProperty(MojangAssets, exclude_if_none=True, default=None) + libraries = ListProperty(PolyMCLibrary, exclude_if_none=True, default=None) + mavenFiles = ListProperty(PolyMCLibrary, exclude_if_none=True, default=None) + mainJar = ObjectProperty(PolyMCLibrary, exclude_if_none=True, default=None) + jarMods = ListProperty(PolyMCLibrary, exclude_if_none=True, default=None) + mainClass = StringProperty(exclude_if_none=True, default=None) + appletClass = StringProperty(exclude_if_none=True, default=None) + 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) + recommended = ListProperty(StringProperty, exclude_if_none=True, default=None) + authors = ListProperty(StringProperty, exclude_if_none=True, default=None) + description = StringProperty(exclude_if_none=True, default=None) + projectUrl = StringProperty(exclude_if_none=True, default=None) + + def write(self): + try: + with open(PMC_DIR + "/%s/package.json" % self.uid, 'w') as file: + json.dump(self.to_json(), file, sort_keys=True, indent=4) + except EnvironmentError as e: + 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)) + + +class PolyMCVersionIndexEntry(JsonObject): + version = StringProperty() + type = StringProperty(exclude_if_none=True, default=None) + releaseTime = ISOTimestampProperty() + requires = ListProperty(DependencyEntry, exclude_if_none=True, default=None) + conflicts = ListProperty(DependencyEntry, exclude_if_none=True, default=None) + recommended = BooleanProperty(exclude_if_none=True, default=None) + volatile = BooleanProperty(exclude_if_none=True, default=None) + sha256 = StringProperty() + + +class PolyMCVersionIndex(VersionedJsonObject): + name = StringProperty() + uid = StringProperty() + versions = ListProperty(PolyMCVersionIndexEntry) + + +class PolyMCPackageIndexEntry(JsonObject): + name = StringProperty() + uid = StringProperty() + sha256 = StringProperty() + + +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 -- cgit 0.0.5-2-1-g0f52 From 1ad5b5950182beff0dd16a2c8df48f2de28d05fe Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 21 Mar 2022 22:25:21 +0100 Subject: refactor: improve fabric scripts --- generateFabric.py | 177 +++++++++++++++++++++++++----------------------- meta/common.py | 19 ------ meta/common/__init__.py | 31 +++++++++ meta/common/fabric.py | 10 +++ meta/metautil.py | 3 +- updateFabric.py | 75 ++++++++++---------- 6 files changed, 175 insertions(+), 140 deletions(-) delete mode 100644 meta/common.py create mode 100644 meta/common/__init__.py create mode 100644 meta/common/fabric.py (limited to 'meta') diff --git a/generateFabric.py b/generateFabric.py index 2f897a5b8c..333145cace 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -1,5 +1,6 @@ from meta.fabricutil import * -from meta.common import ensure_component_dir, polymc_path, upstream_path +from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key +from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() @@ -7,91 +8,101 @@ UPSTREAM_DIR = upstream_path() ensure_component_dir("net.fabricmc.fabric-loader") ensure_component_dir("net.fabricmc.intermediary") -# turn loader versions into packages -loaderRecommended = [] -loaderVersions = [] -intermediaryRecommended = [] -intermediaryVersions = [] - -def loadJarInfo(mavenKey): - with open(UPSTREAM_DIR + "/fabric/jars/" + mavenKey.replace(":", ".") + ".json", 'r', +def load_jar_info(artifact_key): + with open(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json"), 'r', encoding='utf-8') as jarInfoFile: return FabricJarInfo(json.load(jarInfoFile)) -def processLoaderVersion(loaderVersion, it, loaderData): - verStable = it["stable"] - if (len(loaderRecommended) < 1) and verStable: - loaderRecommended.append(loaderVersion) - versionJarInfo = loadJarInfo(it["maven"]) - version = PolyMCVersionFile(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=loaderVersion) - version.releaseTime = versionJarInfo.releaseTime - version.requires = [DependencyEntry(uid='net.fabricmc.intermediary')] - version.order = 10 - version.type = "release" - if isinstance(loaderData.mainClass, dict): - version.mainClass = loaderData.mainClass["client"] +def load_installer_info(version): + with open(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json"), 'r', + encoding='utf-8') as loaderVersionFile: + data = json.load(loaderVersionFile) + return FabricInstallerDataV1(data) + + +def process_loader_version(entry) -> PolyMCVersionFile: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + installer_info = load_installer_info(entry["version"]) + + v = PolyMCVersionFile(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"]) + v.releaseTime = jar_info.releaseTime + v.requires = [DependencyEntry(uid='net.fabricmc.intermediary')] + v.order = 10 + v.type = "release" + if isinstance(installer_info.mainClass, dict): + v.mainClass = installer_info.mainClass["client"] else: - version.mainClass = loaderData.mainClass - version.libraries = [] - version.libraries.extend(loaderData.libraries.common) - version.libraries.extend(loaderData.libraries.client) - loaderLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.fabricmc.net") - version.libraries.append(loaderLib) - loaderVersions.append(version) - - -def processIntermediaryVersion(it): - intermediaryRecommended.append(it["version"]) - versionJarInfo = loadJarInfo(it["maven"]) - version = PolyMCVersionFile(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=it["version"]) - version.releaseTime = versionJarInfo.releaseTime - version.requires = [DependencyEntry(uid='net.minecraft', equals=it["version"])] - version.order = 11 - version.type = "release" - version.libraries = [] - version.volatile = True - mappingLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.fabricmc.net") - version.libraries.append(mappingLib) - intermediaryVersions.append(version) - - -with open(UPSTREAM_DIR + "/fabric/meta-v2/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile: - loaderVersionIndex = json.load(loaderVersionIndexFile) - for it in loaderVersionIndex: - version = it["version"] - with open(UPSTREAM_DIR + "/fabric/loader-installer-json/" + version + ".json", 'r', - encoding='utf-8') as loaderVersionFile: - ldata = json.load(loaderVersionFile) - ldata = FabricInstallerDataV1(ldata) - processLoaderVersion(version, it, ldata) - -with open(UPSTREAM_DIR + "/fabric/meta-v2/intermediary.json", 'r', encoding='utf-8') as intermediaryVersionIndexFile: - intermediaryVersionIndex = json.load(intermediaryVersionIndexFile) - for it in intermediaryVersionIndex: - processIntermediaryVersion(it) - -for version in loaderVersions: - outFilepath = PMC_DIR + "/net.fabricmc.fabric-loader/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) - -sharedData = PolyMCSharedPackageData(uid='net.fabricmc.fabric-loader', name='Fabric Loader') -sharedData.recommended = loaderRecommended -sharedData.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." -sharedData.projectUrl = "https://fabricmc.net" -sharedData.authors = ["Fabric Developers"] -sharedData.write() - -for version in intermediaryVersions: - outFilepath = PMC_DIR + "/net.fabricmc.intermediary/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) - -sharedData = PolyMCSharedPackageData(uid='net.fabricmc.intermediary', name='Intermediary Mappings') -sharedData.recommended = intermediaryRecommended -sharedData.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." -sharedData.projectUrl = "https://fabricmc.net" -sharedData.authors = ["Fabric Developers"] -sharedData.write() + v.mainClass = installer_info.mainClass + v.libraries = [] + v.libraries.extend(installer_info.libraries.common) + v.libraries.extend(installer_info.libraries.client) + loader_lib = PolyMCLibrary(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + v.libraries.append(loader_lib) + return v + + +def process_intermediary_version(entry) -> PolyMCVersionFile: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + + v = PolyMCVersionFile(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=entry["version"]) + v.releaseTime = jar_info.releaseTime + v.requires = [DependencyEntry(uid='net.minecraft', equals=entry["version"])] + v.order = 11 + v.type = "release" + v.libraries = [] + v.volatile = True + intermediary_lib = PolyMCLibrary(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + v.libraries.append(intermediary_lib) + return v + + +def main(): + recommended_loader_versions = [] + recommended_intermediary_versions = [] + + with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as f: + loader_version_index = json.load(f) + for entry in loader_version_index: + version = entry["version"] + print(f"Processing loader {version}") + + v = process_loader_version(entry) + + if not recommended_loader_versions: # first (newest) loader is recommended + recommended_loader_versions.append(version) + + with open(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json"), 'w') as outfile: + json.dump(v.to_json(), outfile, sort_keys=True, indent=4) + + with open(os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), 'r', encoding='utf-8') as f: + intermediary_version_index = json.load(f) + for entry in intermediary_version_index: + version = entry["version"] + print(f"Processing intermediary {version}") + + v = process_intermediary_version(entry) + + recommended_intermediary_versions.append(version) # all intermediaries are recommended + + with open(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json"), 'w') as outfile: + json.dump(v.to_json(), outfile, sort_keys=True, indent=4) + + package = PolyMCSharedPackageData(uid=LOADER_COMPONENT, name='Fabric Loader') + package.recommended = recommended_loader_versions + package.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." + package.projectUrl = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write() + + package = PolyMCSharedPackageData(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') + package.recommended = recommended_intermediary_versions + package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." + package.projectUrl = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write() + + +if __name__ == '__main__': + main() diff --git a/meta/common.py b/meta/common.py deleted file mode 100644 index 5454f517f3..0000000000 --- a/meta/common.py +++ /dev/null @@ -1,19 +0,0 @@ -import os - - -def polymc_path(): - if "PMC_DIR" in os.environ: - return os.environ["PMC_DIR"] - return "polymc" - - -def upstream_path(): - if "UPSTREAM_DIR" in os.environ: - return os.environ["UPSTREAM_DIR"] - return "upstream" - - -def ensure_component_dir(component_id): - path = os.path.join(polymc_path(), component_id) - if not os.path.exists(path): - os.makedirs(path) diff --git a/meta/common/__init__.py b/meta/common/__init__.py new file mode 100644 index 0000000000..77aa996552 --- /dev/null +++ b/meta/common/__init__.py @@ -0,0 +1,31 @@ +import os + +DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" + + +def polymc_path(): + if "PMC_DIR" in os.environ: + return os.environ["PMC_DIR"] + return "polymc" + + +def upstream_path(): + if "UPSTREAM_DIR" in os.environ: + return os.environ["UPSTREAM_DIR"] + return "upstream" + + +def ensure_upstream_dir(path): + path = os.path.join(upstream_path(), path) + if not os.path.exists(path): + os.makedirs(path) + + +def ensure_component_dir(component_id): + path = os.path.join(polymc_path(), component_id) + if not os.path.exists(path): + os.makedirs(path) + + +def transform_maven_key(maven_key: str): + return maven_key.replace(":", ".") diff --git a/meta/common/fabric.py b/meta/common/fabric.py new file mode 100644 index 0000000000..0861730ce9 --- /dev/null +++ b/meta/common/fabric.py @@ -0,0 +1,10 @@ +from os.path import join + +BASE_DIR = "fabric" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json") +META_DIR = join(BASE_DIR, "loader-installer-json") + +LOADER_COMPONENT = "net.fabricmc.fabric-loader" +INTERMEDIARY_COMPONENT = "net.fabricmc.intermediary" diff --git a/meta/metautil.py b/meta/metautil.py index e417bd6e65..11c4009868 100644 --- a/meta/metautil.py +++ b/meta/metautil.py @@ -4,8 +4,9 @@ import os import iso8601 from .jsonobject import * +from .common import polymc_path -PMC_DIR = os.environ["PMC_DIR"] +PMC_DIR = polymc_path() class ISOTimestampProperty(AbstractDateProperty): diff --git a/updateFabric.py b/updateFabric.py index 57e6bee77c..f48858d7ae 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -5,33 +5,32 @@ import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache from meta.fabricutil import * +from meta.common import DATETIME_FORMAT_HTTP, upstream_path, ensure_upstream_dir, transform_maven_key +from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR -DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" +UPSTREAM_DIR = upstream_path() -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(META_DIR) forever_cache = FileCache('caches/http_cache', forever=True) sess = CacheControl(requests.Session(), forever_cache) -def mkdirs(path): - if not os.path.exists(path): - os.makedirs(path) - - def filehash(filename, hashtype, blocksize=65536): - hash = hashtype() + h = hashtype() with open(filename, "rb") as f: for block in iter(lambda: f.read(blocksize), b""): - hash.update(block) - return hash.hexdigest() + h.update(block) + return h.hexdigest() -def get_maven_url(mavenKey, server, ext): - mavenParts = mavenKey.split(":", 3) - mavenVerUrl = server + mavenParts[0].replace(".", "/") + "/" + mavenParts[1] + "/" + mavenParts[2] + "/" - mavenUrl = mavenVerUrl + mavenParts[1] + "-" + mavenParts[2] + ext - return mavenUrl +def get_maven_url(maven_key, server, ext): + parts = maven_key.split(":", 3) + maven_ver_url = server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext + return maven_url def get_json_file(path, url): @@ -56,12 +55,11 @@ def head_file(url): def get_binary_file(path, url): - with open(path, 'w', encoding='utf-8') as f: + with open(path, 'wb') as f: r = sess.get(url) r.raise_for_status() - with open(path, 'wb') as f: - for chunk in r.iter_content(chunk_size=128): - f.write(chunk) + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) def compute_jar_file(path, url): @@ -101,21 +99,24 @@ def compute_jar_file(path, url): json.dump(data.to_json(), outfile, sort_keys=True, indent=4) -mkdirs(UPSTREAM_DIR + "/fabric/meta-v2") -mkdirs(UPSTREAM_DIR + "/fabric/loader-installer-json") -mkdirs(UPSTREAM_DIR + "/fabric/jars") - -# get the version list for each component we are interested in -for component in ["intermediary", "loader"]: - index = get_json_file(UPSTREAM_DIR + "/fabric/meta-v2/" + component + ".json", - "https://meta.fabricmc.net/v2/versions/" + component) - for it in index: - jarMavenUrl = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") - compute_jar_file(UPSTREAM_DIR + "/fabric/jars/" + it["maven"].replace(":", "."), jarMavenUrl) - -# for each loader, download installer JSON file from maven -with open(UPSTREAM_DIR + "/fabric/meta-v2/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile: - loaderVersionIndex = json.load(loaderVersionIndexFile) - for it in loaderVersionIndex: - mavenUrl = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") - get_json_file(UPSTREAM_DIR + "/fabric/loader-installer-json/" + it["version"] + ".json", mavenUrl) +def main(): + # get the version list for each component we are interested in + for component in ["intermediary", "loader"]: + index = get_json_file(os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.fabricmc.net/v2/versions/" + component) + for it in index: + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") + compute_jar_file(os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), jar_maven_url) + + # for each loader, download installer JSON file from maven + with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile: + loader_version_index = json.load(loaderVersionIndexFile) + for it in loader_version_index: + print(f"Downloading installer info for loader {it['version']} ") + maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") + get_json_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), maven_url) + + +if __name__ == '__main__': + main() -- cgit 0.0.5-2-1-g0f52 From 6d9561c28dbabeec600ee647f5a4f5870f78d523 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 29 Mar 2022 13:36:29 +0200 Subject: fix: use correct directory for fabric meta --- meta/common/fabric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/common/fabric.py b/meta/common/fabric.py index 0861730ce9..a306f15a16 100644 --- a/meta/common/fabric.py +++ b/meta/common/fabric.py @@ -4,7 +4,7 @@ BASE_DIR = "fabric" JARS_DIR = join(BASE_DIR, "jars") INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json") -META_DIR = join(BASE_DIR, "loader-installer-json") +META_DIR = join(BASE_DIR, "meta-v2") LOADER_COMPONENT = "net.fabricmc.fabric-loader" INTERMEDIARY_COMPONENT = "net.fabricmc.intermediary" -- cgit 0.0.5-2-1-g0f52 From a5bb3a091d72e565e08958fc8097395121b813b1 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 29 Mar 2022 13:53:59 +0200 Subject: refactor: switch Fabric over to pydantic --- Dockerfile | 2 +- generateFabric.py | 64 ++++++++++---------- meta/common/__init__.py | 5 ++ meta/fabricutil.py | 32 ---------- meta/model/__init__.py | 154 ++++++++++++++++++++++++++++++++++++++++++++++++ meta/model/fabric.py | 43 ++++++++++++++ meta/model/types.py | 47 +++++++++++++++ updateFabric.py | 20 +++---- 8 files changed, 290 insertions(+), 77 deletions(-) delete mode 100644 meta/fabricutil.py create mode 100644 meta/model/__init__.py create mode 100644 meta/model/fabric.py create mode 100644 meta/model/types.py (limited to 'meta') diff --git a/Dockerfile b/Dockerfile index 6fa5e4b686..e7a58203ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM python:3.10.2-bullseye ARG UID=1337 ARG GID=1337 -RUN pip install cachecontrol iso8601 requests lockfile jsonobject six \ +RUN pip install cachecontrol iso8601 requests lockfile jsonobject six pydantic \ && apt-get update && apt-get install -y rsync cron # add our cronjob diff --git a/generateFabric.py b/generateFabric.py index 333145cace..09795294a7 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -1,6 +1,11 @@ -from meta.fabricutil import * +import json +import os + from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT +from meta.model import MetaVersionFile, Dependency, Library, MetaPackageData +from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses +from meta.model.types import GradleSpecifier PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() @@ -9,51 +14,46 @@ ensure_component_dir("net.fabricmc.fabric-loader") ensure_component_dir("net.fabricmc.intermediary") -def load_jar_info(artifact_key): - with open(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json"), 'r', - encoding='utf-8') as jarInfoFile: - return FabricJarInfo(json.load(jarInfoFile)) +def load_jar_info(artifact_key) -> FabricJarInfo: + return FabricJarInfo.parse_file(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json")) -def load_installer_info(version): - with open(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json"), 'r', - encoding='utf-8') as loaderVersionFile: - data = json.load(loaderVersionFile) - return FabricInstallerDataV1(data) +def load_installer_info(version) -> FabricInstallerDataV1: + return FabricInstallerDataV1.parse_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json")) -def process_loader_version(entry) -> PolyMCVersionFile: +def process_loader_version(entry) -> MetaVersionFile: jar_info = load_jar_info(transform_maven_key(entry["maven"])) installer_info = load_installer_info(entry["version"]) - v = PolyMCVersionFile(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"]) - v.releaseTime = jar_info.releaseTime - v.requires = [DependencyEntry(uid='net.fabricmc.intermediary')] + v = MetaVersionFile(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"]) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid='net.fabricmc.intermediary')] v.order = 10 v.type = "release" - if isinstance(installer_info.mainClass, dict): - v.mainClass = installer_info.mainClass["client"] + if isinstance(installer_info.main_class, FabricMainClasses): + v.main_class = installer_info.main_class.client else: - v.mainClass = installer_info.mainClass + v.main_class = installer_info.main_class v.libraries = [] v.libraries.extend(installer_info.libraries.common) v.libraries.extend(installer_info.libraries.client) - loader_lib = PolyMCLibrary(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + loader_lib = Library(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") v.libraries.append(loader_lib) return v -def process_intermediary_version(entry) -> PolyMCVersionFile: +def process_intermediary_version(entry) -> MetaVersionFile: jar_info = load_jar_info(transform_maven_key(entry["maven"])) - v = PolyMCVersionFile(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=entry["version"]) - v.releaseTime = jar_info.releaseTime - v.requires = [DependencyEntry(uid='net.minecraft', equals=entry["version"])] + v = MetaVersionFile(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=entry["version"]) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid='net.minecraft', equals=entry["version"])] v.order = 11 v.type = "release" v.libraries = [] v.volatile = True - intermediary_lib = PolyMCLibrary(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + intermediary_lib = Library(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") v.libraries.append(intermediary_lib) return v @@ -73,8 +73,7 @@ def main(): if not recommended_loader_versions: # first (newest) loader is recommended recommended_loader_versions.append(version) - with open(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json"), 'w') as outfile: - json.dump(v.to_json(), outfile, sort_keys=True, indent=4) + v.write(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json")) with open(os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), 'r', encoding='utf-8') as f: intermediary_version_index = json.load(f) @@ -86,22 +85,21 @@ def main(): recommended_intermediary_versions.append(version) # all intermediaries are recommended - with open(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json"), 'w') as outfile: - json.dump(v.to_json(), outfile, sort_keys=True, indent=4) + v.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) - package = PolyMCSharedPackageData(uid=LOADER_COMPONENT, name='Fabric Loader') + package = MetaPackageData(uid=LOADER_COMPONENT, name='Fabric Loader') package.recommended = recommended_loader_versions package.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." - package.projectUrl = "https://fabricmc.net" + package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] - package.write() + package.write(os.path.join(PMC_DIR, LOADER_COMPONENT, "package.json")) - package = PolyMCSharedPackageData(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') + package = MetaPackageData(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') package.recommended = recommended_intermediary_versions package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." - package.projectUrl = "https://fabricmc.net" + package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] - package.write() + package.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 77aa996552..f0f620f4e9 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -1,8 +1,13 @@ import os +import datetime 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() + + def polymc_path(): if "PMC_DIR" in os.environ: return os.environ["PMC_DIR"] diff --git a/meta/fabricutil.py b/meta/fabricutil.py deleted file mode 100644 index 2f38f8f051..0000000000 --- a/meta/fabricutil.py +++ /dev/null @@ -1,32 +0,0 @@ -from .metautil import * - - -class FabricInstallerArguments(JsonObject): - client = ListProperty(StringProperty) - common = ListProperty(StringProperty) - server = ListProperty(StringProperty) - - -class FabricInstallerLaunchwrapper(JsonObject): - tweakers = ObjectProperty(FabricInstallerArguments, required=True) - - -class FabricInstallerLibraries(JsonObject): - client = ListProperty(PolyMCLibrary) - common = ListProperty(PolyMCLibrary) - server = ListProperty(PolyMCLibrary) - - -class FabricInstallerDataV1(JsonObject): - version = IntegerProperty(required=True) - libraries = ObjectProperty(FabricInstallerLibraries, required=True) - mainClass = DefaultProperty() - arguments = ObjectProperty(FabricInstallerArguments, required=False) - launchwrapper = ObjectProperty(FabricInstallerLaunchwrapper, required=False) - - -class FabricJarInfo(JsonObject): - releaseTime = ISOTimestampProperty() - size = IntegerProperty() - sha256 = StringProperty() - sha1 = StringProperty() diff --git a/meta/model/__init__.py b/meta/model/__init__.py new file mode 100644 index 0000000000..91e40bfe68 --- /dev/null +++ b/meta/model/__init__.py @@ -0,0 +1,154 @@ +import os.path +from datetime import datetime +from typing import Optional, List, Dict, Any + +import pydantic +from pydantic import Field, AnyHttpUrl, validator + +from .types import GradleSpecifier +from ..common import serialize_datetime + +META_FORMAT_VERSION = 1 + + +class MetaBase(pydantic.BaseModel): + def dict(self, **kwargs) -> Dict[str, Any]: + for k in ["by_alias"]: + if k in kwargs: + del kwargs[k] + + return super(MetaBase, self).dict(by_alias=True, **kwargs) + + def json(self, **kwargs: Any) -> str: + for k in ["exclude_none", "sort_keys", "indent"]: + if k in kwargs: + del kwargs[k] + + return super(MetaBase, self).json(exclude_none=True, sort_keys=True, indent=4, **kwargs) + + def write(self, file_path): + with open(file_path, "w") as f: + f.write(self.json()) + + class Config: + allow_population_by_field_name = True + + json_encoders = { + datetime: serialize_datetime + } + + +class Versioned(MetaBase): + @validator("format_version") + def format_version_must_be_supported(cls, v): + return v > META_FORMAT_VERSION + + format_version: int = Field(META_FORMAT_VERSION, alias="formatVersion") + + +class MojangArtifactBase(MetaBase): + sha1: Optional[str] + size: Optional[int] + url: AnyHttpUrl + + +class MojangAssets(MojangArtifactBase): + id: str + totalSize: int + + +class MojangArtifact(MojangArtifactBase): + path: Optional[str] + + +class MojangLibraryExtractRules(MetaBase): + """ + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + } + ] + """ + exclude: List[str] # TODO maybe drop this completely? + + +class MojangLibraryDownloads(MetaBase): + artifact: Optional[MojangArtifact] + classifiers: Dict[Any, MojangArtifact] + + +class OSRule(MetaBase): + @validator("name") + def name_must_be_os(cls, v): + return v in ["osx", "linux", "windows"] + + name: str + version: Optional[str] + + +class MojangRule(MetaBase): + @validator("action") + def action_must_be_allow_disallow(cls, v): + return v in ["allow", "disallow"] + + action: str + os: Optional[OSRule] + + +class MojangLibrary(MetaBase): + extract: Optional[MojangLibraryExtractRules] + name: GradleSpecifier + downloads: Optional[MojangLibraryDownloads] + natives: Optional[Dict[str, str]] + rules: Optional[List[MojangRule]] + + class Config: + arbitrary_types_allowed = True + + +class Dependency(MetaBase): + uid: str + equals: Optional[str] + suggests: Optional[str] + + +class Library(MojangLibrary): + url: Optional[str] + mmcHint: Optional[AnyHttpUrl] = Field(None, alias="MMC-hint") + + +class MetaVersionFile(Versioned): + name: str + version: str + uid: str + type: Optional[str] + order: Optional[int] + volatile: Optional[bool] + requires: Optional[List[Dependency]] + conflicts: Optional[List[Dependency]] + libraries: Optional[List[Library]] + asset_index: Optional[MojangAssets] = Field(alias="assetIndex") + maven_files: Optional[List[Library]] = Field(alias="mavenFiles") + main_jar: Optional[Library] = Field(alias="mainJar") + jar_mods: Optional[List[Library]] = Field(alias="jarMods") + main_class: Optional[str] = Field(alias="mainClass") + applet_class: Optional[str] = Field(alias="appletClass") + minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") + release_time: Optional[datetime] = Field(alias="releaseTime") + additional_traits: Optional[List[str]] = Field(alias="+traits") + additional_tweakers: Optional[List[str]] = Field(alias="+tweakers") + + +class MetaPackageData(Versioned): + name: str + uid: str + recommended: Optional[List[str]] + authors: Optional[List[str]] + description: Optional[str] + project_url: Optional[AnyHttpUrl] = Field(alias="projectUrl") diff --git a/meta/model/fabric.py b/meta/model/fabric.py new file mode 100644 index 0000000000..cd326e54c2 --- /dev/null +++ b/meta/model/fabric.py @@ -0,0 +1,43 @@ +from datetime import datetime +from typing import Optional, List, Union, Dict + +from pydantic import Field + +from . import Library, MetaBase + + +class FabricInstallerArguments(MetaBase): + client: Optional[List[str]] + common: Optional[List[str]] + server: Optional[List[str]] + + +class FabricInstallerLaunchwrapper(MetaBase): + tweakers: FabricInstallerArguments + + +class FabricInstallerLibraries(MetaBase): + client: Optional[List[Library]] + common: Optional[List[Library]] + server: Optional[List[Library]] + + +class FabricMainClasses(MetaBase): + client: Optional[str] + common: Optional[str] + server: Optional[str] + + +class FabricInstallerDataV1(MetaBase): + version: int + libraries: FabricInstallerLibraries + main_class: Optional[Union[str, FabricMainClasses]] = Field(alias="mainClass") + arguments: Optional[FabricInstallerArguments] + launchwrapper: Optional[FabricInstallerLaunchwrapper] + + +class FabricJarInfo(MetaBase): + release_time: Optional[datetime] = Field(alias="releaseTime") + size: Optional[int] + sha256: Optional[str] + sha1: Optional[str] diff --git a/meta/model/types.py b/meta/model/types.py new file mode 100644 index 0000000000..d631565718 --- /dev/null +++ b/meta/model/types.py @@ -0,0 +1,47 @@ +class GradleSpecifier(str): + """ + A gradle specifier - a maven coordinate. Like one of these: + "org.lwjgl.lwjgl:lwjgl:2.9.0" + "net.java.jinput:jinput:2.0.5" + "net.minecraft:launchwrapper:1.5" + """ + + def __init__(self, name: str): + ext_split = name.split('@') + + components = ext_split[0].split(':') + self.group = components[0] + self.artifact = components[1] + self.version = components[2] + + self.extension = 'jar' + if len(ext_split) == 2: + self.extension = ext_split[1] + + self.classifier = None + if len(components) == 4: + self.classifier = components[3] + + def __new__(cls, name: str): + return super(GradleSpecifier, cls).__new__(cls, name) + + def filename(self): + if self.classifier: + return "%s-%s-%s.%s" % (self.artifact, self.version, self.classifier, self.extension) + else: + return "%s-%s.%s" % (self.artifact, self.version, self.extension) + + def base(self): + return "%s/%s/%s/" % (self.group.replace('.', '/'), self.artifact, self.version) + + def path(self): + return self.base() + self.filename() + + def __repr__(self): + return f"GradleSpecifier('{self}')" + + def is_lwjgl(self): + return self.group in ("org.lwjgl", "org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils") + + def is_log4j(self): + return self.group == "org.apache.logging.log4j" \ No newline at end of file diff --git a/updateFabric.py b/updateFabric.py index f48858d7ae..37740f16fb 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -1,10 +1,13 @@ import hashlib import zipfile +import json +import os +from datetime import datetime import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.fabricutil import * +from meta.model.fabric import FabricJarInfo from meta.common import DATETIME_FORMAT_HTTP, upstream_path, ensure_upstream_dir, transform_maven_key from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR @@ -68,7 +71,7 @@ def compute_jar_file(path, url): try: # Let's not download a Jar file if we don't need to. headers = head_file(url) - tstamp = datetime.datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) + tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) sha1 = get_plaintext(url + ".sha1") sha256 = get_plaintext(url + ".sha256") size = int(headers["Content-Length"]) @@ -78,11 +81,11 @@ def compute_jar_file(path, url): jar_path = path + ".jar" get_binary_file(jar_path, url) - tstamp = datetime.datetime.fromtimestamp(0) + tstamp = datetime.fromtimestamp(0) with zipfile.ZipFile(jar_path, 'r') as jar: allinfo = jar.infolist() for info in allinfo: - tstamp_new = datetime.datetime(*info.date_time) + tstamp_new = datetime(*info.date_time) if tstamp_new > tstamp: tstamp = tstamp_new @@ -90,13 +93,8 @@ def compute_jar_file(path, url): sha256 = filehash(jar_path, hashlib.sha256) size = os.path.getsize(jar_path) - data = FabricJarInfo() - data.releaseTime = tstamp - data.sha1 = sha1 - data.sha256 = sha256 - data.size = size - with open(path + ".json", 'w') as outfile: - json.dump(data.to_json(), outfile, sort_keys=True, indent=4) + data = FabricJarInfo(releaseTime=tstamp, sha1=sha1, sha256=sha256, size=size) + data.write(path + ".json") def main(): -- cgit 0.0.5-2-1-g0f52 From 367518371fef6c4b7d655875be6853a4c283d482 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 2 Apr 2022 14:46:38 +0200 Subject: fix: set by_alias for json export --- meta/model/__init__.py | 2 +- updateFabric.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 91e40bfe68..3b343a4a02 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -24,7 +24,7 @@ class MetaBase(pydantic.BaseModel): if k in kwargs: del kwargs[k] - return super(MetaBase, self).json(exclude_none=True, sort_keys=True, indent=4, **kwargs) + return super(MetaBase, self).json(exclude_none=True, sort_keys=True, by_alias=True, indent=4, **kwargs) def write(self, file_path): with open(file_path, "w") as f: diff --git a/updateFabric.py b/updateFabric.py index 37740f16fb..31708052c8 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -93,7 +93,7 @@ def compute_jar_file(path, url): sha256 = filehash(jar_path, hashlib.sha256) size = os.path.getsize(jar_path) - data = FabricJarInfo(releaseTime=tstamp, sha1=sha1, sha256=sha256, size=size) + data = FabricJarInfo(release_time=tstamp, sha1=sha1, sha256=sha256, size=size) data.write(path + ".json") -- cgit 0.0.5-2-1-g0f52 From 7cd825c67f288cfec366cb1e38f389e769307be9 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 2 Apr 2022 14:57:19 +0200 Subject: refactor: move updateMojang to pydantic models --- meta/common/mojang.py | 10 ++++ meta/model/mojang.py | 52 +++++++++++++++++++++ updateMojang.py | 126 +++++++++++++++++++++++++++----------------------- 3 files changed, 129 insertions(+), 59 deletions(-) create mode 100644 meta/common/mojang.py create mode 100644 meta/model/mojang.py (limited to 'meta') diff --git a/meta/common/mojang.py b/meta/common/mojang.py new file mode 100644 index 0000000000..953e3d1d37 --- /dev/null +++ b/meta/common/mojang.py @@ -0,0 +1,10 @@ +from os.path import join + +BASE_DIR = "mojang" + +VERSION_MANIFEST_FILE = join(BASE_DIR, "version_manifest_v2.json") +VERSIONS_DIR = join(BASE_DIR, "versions") +ASSETS_DIR = join(BASE_DIR, "assets") + +MINECRAFT_COMPONENT = "" +LWJGL_COMPONENT = "" diff --git a/meta/model/mojang.py b/meta/model/mojang.py new file mode 100644 index 0000000000..37a14b4435 --- /dev/null +++ b/meta/model/mojang.py @@ -0,0 +1,52 @@ +from datetime import datetime +from typing import Optional, List + +from . import MetaBase + +''' +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 MojangLatestVersion(MetaBase): + release: str + snapshot: str + + +class MojangIndexEntry(MetaBase): + id: Optional[str] + releaseTime: Optional[datetime] + time: Optional[datetime] + type: Optional[str] + url: Optional[str] + sha1: Optional[str] + complianceLevel: Optional[int] + + +class MojangIndex(MetaBase): + latest: MojangLatestVersion + versions: List[MojangIndexEntry] + + +class MojangIndexWrap: + def __init__(self, index: MojangIndex): + self.index = index + self.latest = index.latest + self.versions = dict((x.id, x) for x in index.versions) diff --git a/updateMojang.py b/updateMojang.py index 9f106d735a..965ddb5b2f 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -1,74 +1,82 @@ +import json +import os.path + import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.metautil import * -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] +from meta.common import upstream_path, ensure_upstream_dir +from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR +from meta.model.mojang import MojangIndexWrap, MojangIndex + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(BASE_DIR) +ensure_upstream_dir(VERSIONS_DIR) +ensure_upstream_dir(ASSETS_DIR) forever_cache = FileCache('caches/http_cache', forever=True) sess = CacheControl(requests.Session(), forever_cache) -def get_version_file(path, url): - with open(path, 'w', encoding='utf-8') as f: - r = sess.get(url) - r.raise_for_status() - version_json = r.json() - assetId = version_json["assetIndex"]["id"] - assetUrl = version_json["assetIndex"]["url"] - json.dump(version_json, f, sort_keys=True, indent=4) - return assetId, assetUrl +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 get_file(path, url): +def fetch_file(path, url): + r = sess.get(url) + r.raise_for_status() + version_json = r.json() + with open(path, 'w', encoding='utf-8') as f: - r = sess.get(url) - r.raise_for_status() - version_json = r.json() json.dump(version_json, f, sort_keys=True, indent=4) + return version_json + + +def main(): + # get the remote version list + r = sess.get('https://launchermeta.mojang.com/mc/game/version_manifest_v2.json') + r.raise_for_status() + + remote_versions = MojangIndexWrap(MojangIndex(**r.json())) + remote_ids = set(remote_versions.versions.keys()) + + version_manifest = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE) + + if os.path.exists(version_manifest): + # get the local version list + current_versions = MojangIndexWrap(MojangIndex.parse_file(version_manifest)) + local_ids = set(current_versions.versions.keys()) + + # versions not present locally but present remotely are new + pending_ids = remote_ids.difference(local_ids) + + for x in local_ids: + remote_version = remote_versions.versions[x] + local_version = current_versions.versions[x] + if remote_version.time > local_version.time: + pending_ids.add(x) + 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 + + 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) + + remote_versions.index.write(version_manifest) + -# get the local version list -localVersionlist = None -try: - with open(UPSTREAM_DIR + "/mojang/version_manifest_v2.json", 'r', encoding='utf-8') as localIndexFile: - localVersionlist = MojangIndexWrap(json.load(localIndexFile)) -except: - localVersionlist = MojangIndexWrap({}) -localIDs = set(localVersionlist.versions.keys()) - -# get the remote version list -r = sess.get('https://launchermeta.mojang.com/mc/game/version_manifest_v2.json') -r.raise_for_status() -main_json = r.json() -remoteVersionlist = MojangIndexWrap(main_json) -remoteIDs = set(remoteVersionlist.versions.keys()) - -# versions not present locally but present remotely are new -newIDs = remoteIDs.difference(localIDs) - -# versions present both locally and remotely need to be checked -checkedIDs = remoteIDs.difference(newIDs) - -# versions that actually need to be updated have updated timestamps or are new -updatedIDs = newIDs -for id in checkedIDs: - remoteVersion = remoteVersionlist.versions[id] - localVersion = localVersionlist.versions[id] - if remoteVersion.time > localVersion.time: - updatedIDs.add(id) - -# update versions and the linked assets files -assets = {} -for id in updatedIDs: - version = remoteVersionlist.versions[id] - print("Updating " + version.id + " to timestamp " + version.releaseTime.strftime('%s')) - assetId, assetUrl = get_version_file(UPSTREAM_DIR + "/mojang/versions/" + id + '.json', version.url) - assets[assetId] = assetUrl - -for assetId, assetUrl in iter(assets.items()): - print("assets", assetId, assetUrl) - get_file(UPSTREAM_DIR + "/mojang/assets/" + assetId + '.json', assetUrl) - -with open(UPSTREAM_DIR + "/mojang/version_manifest_v2.json", 'w', encoding='utf-8') as f: - json.dump(main_json, f, sort_keys=True, indent=4) +if __name__ == '__main__': + main() -- cgit 0.0.5-2-1-g0f52 From 5895e5accfbb1268500f9dd35003abf207a548c8 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 2 Apr 2022 16:49:31 +0200 Subject: feat: implement experiments updates --- meta/common/__init__.py | 6 ++ meta/common/http.py | 6 ++ meta/common/mojang.py | 2 + meta/model/mojang.py | 20 +++++- static/mojang/minecraft-experiments.json | 104 +++++++++++++++++++++++++++++++ updateMojang.py | 50 ++++++++++++--- 6 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 meta/common/http.py create mode 100644 static/mojang/minecraft-experiments.json (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index f0f620f4e9..478404362a 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -20,6 +20,12 @@ def upstream_path(): return "upstream" +def static_path(): + if "STATIC_DIR" in os.environ: + return os.environ["STATIC_DIR"] + return "static" + + def ensure_upstream_dir(path): path = os.path.join(upstream_path(), path) if not os.path.exists(path): diff --git a/meta/common/http.py b/meta/common/http.py new file mode 100644 index 0000000000..c057e4b06f --- /dev/null +++ b/meta/common/http.py @@ -0,0 +1,6 @@ +def download_binary_file(sess, path, url): + with open(path, 'wb') as f: + r = sess.get(url) + r.raise_for_status() + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) diff --git a/meta/common/mojang.py b/meta/common/mojang.py index 953e3d1d37..1c16afc885 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -6,5 +6,7 @@ VERSION_MANIFEST_FILE = join(BASE_DIR, "version_manifest_v2.json") VERSIONS_DIR = join(BASE_DIR, "versions") ASSETS_DIR = join(BASE_DIR, "assets") +STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") + MINECRAFT_COMPONENT = "" LWJGL_COMPONENT = "" diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 37a14b4435..fa00071dd7 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -1,5 +1,7 @@ from datetime import datetime -from typing import Optional, List +from typing import Optional, List, Dict + +from pydantic import AnyHttpUrl from . import MetaBase @@ -50,3 +52,19 @@ class MojangIndexWrap: self.index = index self.latest = index.latest self.versions = dict((x.id, x) for x in index.versions) + + +class ExperimentEntry(MetaBase): + id: str + url: AnyHttpUrl + wiki: Optional[AnyHttpUrl] + + +class ExperimentIndex(MetaBase): + experiments: List[ExperimentEntry] + + +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) diff --git a/static/mojang/minecraft-experiments.json b/static/mojang/minecraft-experiments.json new file mode 100644 index 0000000000..4b16b70601 --- /dev/null +++ b/static/mojang/minecraft-experiments.json @@ -0,0 +1,104 @@ +{ + "experiments": [ + { + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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" + } + ] +} \ No newline at end of file diff --git a/updateMojang.py b/updateMojang.py index 965ddb5b2f..54d5d739be 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -1,15 +1,18 @@ import json import os.path +import zipfile import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.common import upstream_path, ensure_upstream_dir -from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR -from meta.model.mojang import MojangIndexWrap, MojangIndex +from meta.common import upstream_path, ensure_upstream_dir, static_path +from meta.common.http import download_binary_file +from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR, STATIC_EXPERIMENTS_FILE +from meta.model.mojang import MojangIndexWrap, MojangIndex, ExperimentIndex, ExperimentIndexWrap UPSTREAM_DIR = upstream_path() +STATIC_DIR = static_path() ensure_upstream_dir(BASE_DIR) ensure_upstream_dir(VERSIONS_DIR) @@ -26,6 +29,26 @@ def fetch_version_file(path, url): return asset_id, asset_url +def fetch_zipped_version_file(path, url): + zip_path = f"{path}.zip" + download_binary_file(sess, zip_path, url) + with zipfile.ZipFile(zip_path, 'r') as z: + for info in z.infolist(): + if info.filename.endswith(".json"): + print(f"Found {info.filename} as version json") + version_json = json.load(z.open(info)) + break + + assert version_json + + 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 + + def fetch_file(path, url): r = sess.get(url) r.raise_for_status() @@ -45,11 +68,11 @@ def main(): remote_versions = MojangIndexWrap(MojangIndex(**r.json())) remote_ids = set(remote_versions.versions.keys()) - version_manifest = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE) + version_manifest_path = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE) - if os.path.exists(version_manifest): + if os.path.exists(version_manifest_path): # get the local version list - current_versions = MojangIndexWrap(MojangIndex.parse_file(version_manifest)) + current_versions = MojangIndexWrap(MojangIndex.parse_file(version_manifest_path)) local_ids = set(current_versions.versions.keys()) # versions not present locally but present remotely are new @@ -71,11 +94,24 @@ def main(): asset_id, asset_url = fetch_version_file(os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json"), version.url) assets[asset_id] = asset_url + # deal with experimental snapshots separately + static_experiments_path = os.path.join(STATIC_DIR, STATIC_EXPERIMENTS_FILE) + if os.path.exists(static_experiments_path): + experiments = ExperimentIndexWrap(ExperimentIndex.parse_file(static_experiments_path)) + experiment_ids = set(experiments.versions.keys()) + + 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) - remote_versions.index.write(version_manifest) + remote_versions.index.write(version_manifest_path) if __name__ == '__main__': -- cgit 0.0.5-2-1-g0f52 From 2ca56cafdf767c32fd8397bc4089c1e8513272d5 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 2 Apr 2022 19:35:02 +0200 Subject: refactor: move generateMojang to pydantic models --- generateMojang.py | 379 ++++++++++++++------------- index.py | 3 +- meta/common/__init__.py | 5 +- meta/common/mojang.py | 6 +- meta/metautil.py | 169 ------------ meta/model/__init__.py | 42 ++- meta/model/mojang.py | 140 +++++++++- static/minecraft.json | 348 ------------------------ static/mojang/minecraft-experiments.json | 40 +-- static/mojang/minecraft-legacy-override.json | 348 ++++++++++++++++++++++++ updateMojang.py | 32 +-- 11 files changed, 745 insertions(+), 767 deletions(-) delete mode 100644 static/minecraft.json create mode 100644 static/mojang/minecraft-legacy-override.json (limited to 'meta') 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() diff --git a/index.py b/index.py index ee19a477ca..b03e665e60 100755 --- a/index.py +++ b/index.py @@ -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/minecraft.json b/static/minecraft.json deleted file mode 100644 index d30db4c10c..0000000000 --- a/static/minecraft.json +++ /dev/null @@ -1,348 +0,0 @@ -{ - "versions": { - "1.5.2": { - "releaseTime": "2013-04-25T17:45:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.5.1": { - "releaseTime": "2013-03-20T12:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.5": { - "releaseTime": "2013-03-07T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.7": { - "releaseTime": "2012-12-28T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.6": { - "releaseTime": "2012-12-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.5": { - "releaseTime": "2012-11-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.4": { - "releaseTime": "2012-11-14T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.3": { - "releaseTime": "2012-11-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.2": { - "releaseTime": "2012-10-25T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.1": { - "releaseTime": "2012-10-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4": { - "releaseTime": "2012-10-19T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.3.2": { - "releaseTime": "2012-08-16T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.3.1": { - "releaseTime": "2012-08-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.3": { - "releaseTime": "2012-07-26T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.5": { - "releaseTime": "2012-03-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.4": { - "releaseTime": "2012-03-22T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.3": { - "releaseTime": "2012-03-02T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.2": { - "releaseTime": "2012-03-01T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.1": { - "releaseTime": "2012-03-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.1": { - "releaseTime": "2012-01-12T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.0": { - "releaseTime": "2011-11-18T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.8.1": { - "releaseTime": "2011-09-19T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.8": { - "releaseTime": "2011-09-15T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.7.3": { - "releaseTime": "2011-07-08T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.7.2": { - "releaseTime": "2011-07-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.7": { - "releaseTime": "2011-06-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.6": { - "releaseTime": "2011-05-31T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.5": { - "releaseTime": "2011-05-28T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.4": { - "releaseTime": "2011-05-26T00:00:04+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.3": { - "releaseTime": "2011-05-26T00:00:03+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.2": { - "releaseTime": "2011-05-26T00:00:02+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.1": { - "releaseTime": "2011-05-26T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6": { - "releaseTime": "2011-05-26T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.5_01": { - "releaseTime": "2011-04-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.5": { - "releaseTime": "2011-04-19T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.4_01": { - "releaseTime": "2011-04-05T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.4": { - "releaseTime": "2011-03-31T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.3_01": { - "releaseTime": "2011-02-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.3b": { - "releaseTime": "2011-02-22T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.2_02": { - "releaseTime": "2011-01-21T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.2_01": { - "releaseTime": "2011-01-14T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.2": { - "releaseTime": "2011-01-13T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.1_02": { - "releaseTime": "2010-12-22T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.1_01": { - "releaseTime": "2010-12-22T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.0.2": { - "releaseTime": "2010-12-21T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.0_01": { - "releaseTime": "2010-12-20T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.0": { - "releaseTime": "2010-12-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.6": { - "releaseTime": "2010-12-03T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.5": { - "releaseTime": "2010-12-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.4_01": { - "releaseTime": "2010-11-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3_04": { - "releaseTime": "2010-11-26T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3_02": { - "releaseTime": "2010-11-25T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3_01": { - "releaseTime": "2010-11-24T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3": { - "releaseTime": "2010-11-24T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.2b": { - "releaseTime": "2010-11-10T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.2a": { - "releaseTime": "2010-11-10T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.1_01": { - "releaseTime": "2010-11-05T00:00:01+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.1": { - "releaseTime": "2010-11-05T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.0_02": { - "releaseTime": "2010-11-04T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.0_01": { - "releaseTime": "2010-10-31T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.0": { - "releaseTime": "2010-10-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.1.2_01": { - "releaseTime": "2010-09-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.1.2": { - "releaseTime": "2010-09-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.1.0": { - "releaseTime": "2010-09-13T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.17_04": { - "releaseTime": "2010-08-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.17_02": { - "releaseTime": "2010-08-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.16": { - "releaseTime": "2010-08-12T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.15": { - "releaseTime": "2010-08-04T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.14": { - "releaseTime": "2010-07-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.11": { - "releaseTime": "2010-07-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.5_01": { - "releaseTime": "2010-07-13T00:00:00+02:00", - "mainClass": "y", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.0.4": { - "releaseTime": "2010-07-09T00:00:00+02:00", - "mainClass": "ax", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "inf-20100618": { - "releaseTime": "2010-06-16T00:00:00+02:00", - "mainClass": "net.minecraft.client.d", - "appletClass": "net.minecraft.client.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "c0.30_01c": { - "releaseTime": "2009-12-22T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.l", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "c0.0.13a_03": { - "releaseTime": "2009-05-22T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.c", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "c0.0.13a": { - "releaseTime": "2009-05-31T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.Minecraft", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "c0.0.11a": { - "releaseTime": "2009-05-17T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.Minecraft", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "rd-161348": { - "releaseTime": "2009-05-16T13:48:00+02:00", - "mainClass": "com.mojang.minecraft.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-160052": { - "releaseTime": "2009-05-16T00:52:00+02:00", - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-20090515": { - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-132328": { - "releaseTime": "2009-05-13T23:28:00+02:00", - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-132211": { - "releaseTime": "2009-05-13T22:11:00+02:00", - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - } - } -} \ No newline at end of file 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/mojang/minecraft-legacy-override.json b/static/mojang/minecraft-legacy-override.json new file mode 100644 index 0000000000..d30db4c10c --- /dev/null +++ b/static/mojang/minecraft-legacy-override.json @@ -0,0 +1,348 @@ +{ + "versions": { + "1.5.2": { + "releaseTime": "2013-04-25T17:45:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.5.1": { + "releaseTime": "2013-03-20T12:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.5": { + "releaseTime": "2013-03-07T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.7": { + "releaseTime": "2012-12-28T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.6": { + "releaseTime": "2012-12-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.5": { + "releaseTime": "2012-11-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.4": { + "releaseTime": "2012-11-14T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.3": { + "releaseTime": "2012-11-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.2": { + "releaseTime": "2012-10-25T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.1": { + "releaseTime": "2012-10-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4": { + "releaseTime": "2012-10-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3.2": { + "releaseTime": "2012-08-16T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3.1": { + "releaseTime": "2012-08-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3": { + "releaseTime": "2012-07-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.5": { + "releaseTime": "2012-03-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.4": { + "releaseTime": "2012-03-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.3": { + "releaseTime": "2012-03-02T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.2": { + "releaseTime": "2012-03-01T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.1": { + "releaseTime": "2012-03-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.1": { + "releaseTime": "2012-01-12T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.0": { + "releaseTime": "2011-11-18T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8.1": { + "releaseTime": "2011-09-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8": { + "releaseTime": "2011-09-15T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7.3": { + "releaseTime": "2011-07-08T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7.2": { + "releaseTime": "2011-07-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7": { + "releaseTime": "2011-06-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.6": { + "releaseTime": "2011-05-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.5": { + "releaseTime": "2011-05-28T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.4": { + "releaseTime": "2011-05-26T00:00:04+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.3": { + "releaseTime": "2011-05-26T00:00:03+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.2": { + "releaseTime": "2011-05-26T00:00:02+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.1": { + "releaseTime": "2011-05-26T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6": { + "releaseTime": "2011-05-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.5_01": { + "releaseTime": "2011-04-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.5": { + "releaseTime": "2011-04-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.4_01": { + "releaseTime": "2011-04-05T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.4": { + "releaseTime": "2011-03-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.3_01": { + "releaseTime": "2011-02-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.3b": { + "releaseTime": "2011-02-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2_02": { + "releaseTime": "2011-01-21T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2_01": { + "releaseTime": "2011-01-14T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2": { + "releaseTime": "2011-01-13T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.1_02": { + "releaseTime": "2010-12-22T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.1_01": { + "releaseTime": "2010-12-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0.2": { + "releaseTime": "2010-12-21T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0_01": { + "releaseTime": "2010-12-20T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0": { + "releaseTime": "2010-12-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.6": { + "releaseTime": "2010-12-03T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.5": { + "releaseTime": "2010-12-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.4_01": { + "releaseTime": "2010-11-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_04": { + "releaseTime": "2010-11-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_02": { + "releaseTime": "2010-11-25T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_01": { + "releaseTime": "2010-11-24T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3": { + "releaseTime": "2010-11-24T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.2b": { + "releaseTime": "2010-11-10T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.2a": { + "releaseTime": "2010-11-10T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.1_01": { + "releaseTime": "2010-11-05T00:00:01+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.1": { + "releaseTime": "2010-11-05T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0_02": { + "releaseTime": "2010-11-04T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0_01": { + "releaseTime": "2010-10-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0": { + "releaseTime": "2010-10-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.1.2_01": { + "releaseTime": "2010-09-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.1.2": { + "releaseTime": "2010-09-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.1.0": { + "releaseTime": "2010-09-13T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.17_04": { + "releaseTime": "2010-08-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.17_02": { + "releaseTime": "2010-08-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.16": { + "releaseTime": "2010-08-12T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.15": { + "releaseTime": "2010-08-04T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.14": { + "releaseTime": "2010-07-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.11": { + "releaseTime": "2010-07-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.5_01": { + "releaseTime": "2010-07-13T00:00:00+02:00", + "mainClass": "y", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.0.4": { + "releaseTime": "2010-07-09T00:00:00+02:00", + "mainClass": "ax", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "inf-20100618": { + "releaseTime": "2010-06-16T00:00:00+02:00", + "mainClass": "net.minecraft.client.d", + "appletClass": "net.minecraft.client.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.30_01c": { + "releaseTime": "2009-12-22T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.l", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.13a_03": { + "releaseTime": "2009-05-22T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.c", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.13a": { + "releaseTime": "2009-05-31T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.Minecraft", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.11a": { + "releaseTime": "2009-05-17T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.Minecraft", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "rd-161348": { + "releaseTime": "2009-05-16T13:48:00+02:00", + "mainClass": "com.mojang.minecraft.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-160052": { + "releaseTime": "2009-05-16T00:52:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-20090515": { + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-132328": { + "releaseTime": "2009-05-13T23:28:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-132211": { + "releaseTime": "2009-05-13T22:11:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + } + } +} \ No newline at end of file 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) -- cgit 0.0.5-2-1-g0f52 From b4dcfe056f80f33c1469c63af43844ef4a85425a Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 2 Apr 2022 20:24:00 +0200 Subject: refactor: cleanup --- generateFabric.py | 14 +-- generateMojang.py | 272 ++++++++++++++++++++++++------------------------- meta/model/__init__.py | 10 +- meta/model/mojang.py | 48 ++++----- 4 files changed, 170 insertions(+), 174 deletions(-) (limited to 'meta') diff --git a/generateFabric.py b/generateFabric.py index 09795294a7..2de6724e5e 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -3,7 +3,7 @@ import os from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT -from meta.model import MetaVersionFile, Dependency, Library, MetaPackageData +from meta.model import MetaVersion, Dependency, Library, MetaPackage from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses from meta.model.types import GradleSpecifier @@ -22,11 +22,11 @@ def load_installer_info(version) -> FabricInstallerDataV1: return FabricInstallerDataV1.parse_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json")) -def process_loader_version(entry) -> MetaVersionFile: +def process_loader_version(entry) -> MetaVersion: jar_info = load_jar_info(transform_maven_key(entry["maven"])) installer_info = load_installer_info(entry["version"]) - v = MetaVersionFile(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"]) + v = MetaVersion(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"]) v.release_time = jar_info.release_time v.requires = [Dependency(uid='net.fabricmc.intermediary')] v.order = 10 @@ -43,10 +43,10 @@ def process_loader_version(entry) -> MetaVersionFile: return v -def process_intermediary_version(entry) -> MetaVersionFile: +def process_intermediary_version(entry) -> MetaVersion: jar_info = load_jar_info(transform_maven_key(entry["maven"])) - v = MetaVersionFile(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=entry["version"]) + v = MetaVersion(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=entry["version"]) v.release_time = jar_info.release_time v.requires = [Dependency(uid='net.minecraft', equals=entry["version"])] v.order = 11 @@ -87,14 +87,14 @@ def main(): v.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) - package = MetaPackageData(uid=LOADER_COMPONENT, name='Fabric Loader') + package = MetaPackage(uid=LOADER_COMPONENT, name='Fabric Loader') package.recommended = recommended_loader_versions package.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] package.write(os.path.join(PMC_DIR, LOADER_COMPONENT, "package.json")) - package = MetaPackageData(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') + package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') package.recommended = recommended_intermediary_versions package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." package.project_url = "https://fabricmc.net" diff --git a/generateMojang.py b/generateMojang.py index 9cd17ff969..2431238e93 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -9,9 +9,9 @@ from typing import Optional 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 meta.model import MetaVersion, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ + MetaPackage, MojangRules +from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, LegacyOverrideIndex from updateMojang import STATIC_DIR PMC_DIR = polymc_path() @@ -80,7 +80,7 @@ BAD_VARIANTS = [ ] -def add_or_get_bucket(buckets, rules: Optional[MojangRules]) -> MetaVersionFile: +def add_or_get_bucket(buckets, rules: Optional[MojangRules]) -> MetaVersion: rule_hash = None if rules: rule_hash = hash(rules.json()) @@ -88,13 +88,13 @@ def add_or_get_bucket(buckets, rules: Optional[MojangRules]) -> MetaVersionFile: if rule_hash in buckets: bucket = buckets[rule_hash] else: - bucket = MetaVersionFile(name="LWJGL", version="undetermined", uid=LWJGL_COMPONENT) + bucket = MetaVersion(name="LWJGL", version="undetermined", uid=LWJGL_COMPONENT) bucket.type = "release" buckets[rule_hash] = bucket return bucket -def hash_lwjgl_version(lwjgl: MetaVersionFile): +def hash_lwjgl_version(lwjgl: MetaVersion): lwjgl_copy = copy.deepcopy(lwjgl) lwjgl_copy.release_time = None return hashlib.sha1(lwjgl_copy.json().encode("utf-8", "strict")).hexdigest() @@ -119,16 +119,16 @@ def add_lwjgl_version(variants, lwjgl): current_hash = hash_lwjgl_version(lwjgl_copy) found = False for variant in variants[version]: - existingHash = variant.sha1 - if current_hash == existingHash: + existing_hash = variant.sha1 + if current_hash == existing_hash: found = True break if not found: - print("!!! New variant for LWJGL version %s" % (version)) + print("!!! New variant for LWJGL version %s" % version) variants[version].append(LWJGLEntry(version=lwjgl_copy, sha1=current_hash)) -def removePathsFromLib(lib): +def remove_paths_from_lib(lib): if lib.downloads.artifact: lib.downloads.artifact.path = None if lib.downloads.classifiers: @@ -136,8 +136,8 @@ def removePathsFromLib(lib): value.path = None -def adaptNewStyleArguments(arguments): - outarr = [] +def adapt_new_style_arguments(arguments): + foo = [] # we ignore the jvm arguments entirely. # grab the strings, log the complex stuff for arg in arguments.game: @@ -150,14 +150,14 @@ def adaptNewStyleArguments(arguments): continue if arg == '${auth_xuid}': continue - outarr.append(arg) + foo.append(arg) else: print("!!! Unrecognized structure in Minecraft game arguments:") pprint(arg) - return ' '.join(outarr) + return ' '.join(foo) -def is_macos_only(rules: Optional[MojangRules], specifier): +def is_macos_only(rules: Optional[MojangRules]): allows_osx = False allows_all = False # print("Considering", specifier, "rules", rules) @@ -172,50 +172,49 @@ def is_macos_only(rules: Optional[MojangRules], specifier): return False -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)] +def process_single_variant(lwjgl_variant: MetaVersion): + lwjgl_version = lwjgl_variant.version + v = copy.deepcopy(lwjgl_variant) + if lwjgl_version[0] == '2': + filename = os.path.join(PMC_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") + v.name = 'LWJGL 2' + v.uid = LWJGL_COMPONENT + v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] + elif lwjgl_version[0] == '3': + filename = os.path.join(PMC_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") + v.name = 'LWJGL 3' + v.uid = LWJGL3_COMPONENT + v.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 + filtered_libraries = list(filter(lambda l: l.name.artifact not in ["jutils", "jinput"], v.libraries)) + v.libraries = filtered_libraries else: - raise Exception("LWJGL version not recognized: %s" % versionObj.version) + raise Exception("LWJGL version not recognized: %s" % v.version) - versionObj.volatile = True - versionObj.order = -1 + v.volatile = True + v.order = -1 good = True - for lib in versionObj.libraries: + for lib in v.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()) + checked_dict = {'linux', 'windows', 'osx'} + if not checked_dict.issubset(lib.natives.keys()): + print("Missing system classifier!", v.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, + for entry in checked_dict: + baked_entry = lib.natives[entry] + if baked_entry not in lib.downloads.classifiers: + print("Missing download for classifier!", v.version, lib.name, baked_entry, lib.downloads.classifiers.keys()) good = False break if good: - versionObj.write(filename) + v.write(filename) else: - print("Skipped LWJGL", versionObj.version) + print("Skipped LWJGL", v.version) def main(): @@ -230,21 +229,21 @@ def main(): # skip non JSON files continue print("Processing", filename) - mojangVersionFile = MojangVersionFile.parse_file(input_file) - versionFile = mojangVersionFile.to_meta_version("Minecraft", MINECRAFT_COMPONENT, mojangVersionFile.id) + mojang_version = MojangVersion.parse_file(input_file) + v = mojang_version.to_meta_version("Minecraft", MINECRAFT_COMPONENT, mojang_version.id) + libs_minecraft = [] is_lwjgl_3 = False buckets = {} - for pmcLib in versionFile.libraries: - removePathsFromLib(pmcLib) - specifier = pmcLib.name - ruleHash = None + for lib in v.libraries: + remove_paths_from_lib(lib) + specifier = lib.name if specifier.is_lwjgl(): rules = None - if pmcLib.rules: - rules = pmcLib.rules - pmcLib.rules = None - if is_macos_only(rules, specifier): + if lib.rules: + rules = lib.rules + lib.rules = None + if is_macos_only(rules): print("Candidate library ", specifier, " is only for macOS and is therefore ignored.") continue bucket = add_or_get_bucket(buckets, rules) @@ -256,141 +255,138 @@ def main(): bucket.version = specifier.version if not bucket.libraries: bucket.libraries = [] - bucket.libraries.append(pmcLib) - bucket.release_time = versionFile.release_time + bucket.libraries.append(lib) + bucket.release_time = v.release_time + # FIXME: workaround for insane log4j nonsense from December 2021. Probably needs adjustment. + elif lib.name.is_log4j(): + version_override, maven_override = map_log4j_artifact(lib.name.version) + + if version_override not in LOG4J_HASHES: + raise Exception("ERROR: unhandled log4j version (overriden) %s!" % version_override) + + if lib.name.artifact not in LOG4J_HASHES[version_override]: + raise Exception("ERROR: unhandled log4j artifact %s!" % lib.name.artifact) + + replacement_name = GradleSpecifier( + "org.apache.logging.log4j:%s:%s" % (lib.name.artifact, version_override)) + artifact = MojangArtifact( + url=maven_override % (replacement_name.path()), + sha1=LOG4J_HASHES[version_override][lib.name.artifact]["sha1"], + size=LOG4J_HASHES[version_override][lib.name.artifact]["size"] + ) + + libs_minecraft.append(Library( + name=replacement_name, + downloads=MojangLibraryDownloads(artifact=artifact) + )) else: - # FIXME: workaround for insane log4j nonsense from December 2021. Probably needs adjustment. - if pmcLib.name.is_log4j(): - versionOverride, mavenOverride = map_log4j_artifact(pmcLib.name.version) - - if versionOverride not in LOG4J_HASHES: - raise Exception("ERROR: unhandled log4j version (overriden) %s!" % versionOverride) - - if pmcLib.name.artifact not in LOG4J_HASHES[versionOverride]: - raise Exception("ERROR: unhandled log4j artifact %s!" % pmcLib.name.artifact) - - 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) + libs_minecraft.append(lib) if len(buckets) == 1: for key in buckets: - keyBucket = buckets[key] - keyBucket.libraries = sorted(keyBucket.libraries, key=attrgetter("name")) - add_lwjgl_version(lwjglVersionVariants, keyBucket) - print("Found only candidate LWJGL", keyBucket.version, key) + lwjgl = buckets[key] + lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) + add_lwjgl_version(lwjglVersionVariants, lwjgl) + print("Found only candidate LWJGL", lwjgl.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 is None: continue - keyBucket = buckets[key] + lwjgl = buckets[key] if None in buckets: - keyBucket.libraries = sorted(keyBucket.libraries + buckets[None].libraries, key=attrgetter("name")) + lwjgl.libraries = sorted(lwjgl.libraries + buckets[None].libraries, key=attrgetter("name")) else: - keyBucket.libraries = sorted(keyBucket.libraries, key=attrgetter('name')) - add_lwjgl_version(lwjglVersionVariants, keyBucket) - print("Found candidate LWJGL", keyBucket.version, key) + lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter('name')) + add_lwjgl_version(lwjglVersionVariants, lwjgl) + print("Found candidate LWJGL", lwjgl.version, key) # remove the common bucket... if None in buckets: del buckets[None] - versionFile.libraries = libs_minecraft - depentry = None + v.libraries = libs_minecraft if is_lwjgl_3: - depentry = Dependency(uid=LWJGL3_COMPONENT) + lwjgl_dependency = Dependency(uid=LWJGL3_COMPONENT) else: - depentry = Dependency(uid=LWJGL_COMPONENT) + lwjgl_dependency = Dependency(uid=LWJGL_COMPONENT) if len(buckets) == 1: - suggestedVersion = next(iter(buckets.values())).version + suggested_version = 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 if is_lwjgl_3: - depentry.suggests = suggestedVersion - depentry.equals = suggestedVersion + lwjgl_dependency.suggests = suggested_version + lwjgl_dependency.equals = suggested_version else: - depentry.suggests = '2.9.4-nightly-20150209' + lwjgl_dependency.suggests = '2.9.4-nightly-20150209' else: - badVersions1 = {'3.1.6', '3.2.1'} - ourVersions = set() + bad_versions = {'3.1.6', '3.2.1'} + our_versions = set() for lwjgl in iter(buckets.values()): - ourVersions = ourVersions.union({lwjgl.version}) + our_versions = our_versions.union({lwjgl.version}) - if ourVersions == badVersions1: + if our_versions == bad_versions: print("Found broken 3.1.6/3.2.1 combo, forcing LWJGL to 3.2.1") - suggestedVersion = '3.2.1' - depentry.suggests = suggestedVersion + suggested_version = '3.2.1' + lwjgl_dependency.suggests = suggested_version else: - raise Exception("ERROR: cannot determine single suggested LWJGL version in %s" % mojangVersionFile.id) + raise Exception("ERROR: cannot determine single suggested LWJGL version in %s" % mojang_version.id) # if it uses LWJGL 3, add the trait that enables starting on first thread on macOS if is_lwjgl_3: - if not versionFile.additional_traits: - versionFile.additional_traits = [] - versionFile.additional_traits.append("FirstThreadOnMacOS") - versionFile.requires = [depentry] - versionFile.order = -2 + if not v.additional_traits: + v.additional_traits = [] + v.additional_traits.append("FirstThreadOnMacOS") + v.requires = [lwjgl_dependency] + v.order = -2 # process 1.13 arguments into previous version - if not mojangVersionFile.minecraftArguments and mojangVersionFile.arguments: - 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) + if not mojang_version.minecraft_arguments and mojang_version.arguments: + v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) + out_filename = os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{v.version}.json") + if v.version in override_index.versions: + override = override_index.versions[v.version] + override.apply_onto_meta_version(v) + v.write(out_filename) for lwjglVersionVariant in lwjglVersionVariants: - decidedVariant = None - passedVariants = 0 - unknownVariants = 0 + decided_variant = None + passed_variants = 0 + unknown_variants = 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)) + 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 + print("Variant %s accepted." % variant.sha1) + decided_variant = variant + passed_variants += 1 continue print(f" \"{variant.sha1}\", # {lwjglVersionVariant} ({variant.version.release_time})") - unknownVariants += 1 + unknown_variants += 1 print("") - if decidedVariant and passedVariants == 1 and unknownVariants == 0: - process_single_variant(decidedVariant.version) + if decided_variant and passed_variants == 1 and unknown_variants == 0: + process_single_variant(decided_variant.version) else: raise Exception("No variant decided for version %s out of %d possible ones and %d unknown ones." % ( - lwjglVersionVariant, passedVariants, unknownVariants)) + lwjglVersionVariant, passed_variants, unknown_variants)) - 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")) + lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name='LWJGL 2') + lwjgl_package.recommended = ['2.9.4-nightly-20150209'] + lwjgl_package.write(os.path.join(PMC_DIR, LWJGL_COMPONENT, "package.json")) 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")) + lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name='LWJGL 3') + lwjgl_package.recommended = ['3.1.2'] + lwjgl_package.write(os.path.join(PMC_DIR, LWJGL3_COMPONENT, "package.json")) - localVersionlist = MojangIndexWrap(MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE))) + mojang_index = MojangIndexWrap(MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE))) - mcSharedData = MetaPackageData(uid=MINECRAFT_COMPONENT, name='Minecraft') - mcSharedData.recommended = [localVersionlist.latest.release] - mcSharedData.write(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, "package.json")) + minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name='Minecraft') + minecraft_package.recommended = [mojang_index.latest.release] + minecraft_package.write(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 73c1e80a42..d7373323a1 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Optional, List, Dict, Any +from typing import Optional, List, Dict, Any, Iterator import pydantic from pydantic import Field, AnyHttpUrl, validator @@ -106,10 +106,10 @@ class MojangRule(MetaBase): class MojangRules(MetaBase): __root__: List[MojangRule] - def __iter__(self): + def __iter__(self) -> Iterator[MojangRule]: return iter(self.__root__) - def __getitem__(self, item): + def __getitem__(self, item) -> MojangRule: return self.__root__[item] @@ -138,7 +138,7 @@ class Dependency(MetaBase): suggests: Optional[str] -class MetaVersionFile(Versioned): +class MetaVersion(Versioned): name: str version: str uid: str @@ -161,7 +161,7 @@ class MetaVersionFile(Versioned): additional_tweakers: Optional[List[str]] = Field(alias="+tweakers") -class MetaPackageData(Versioned): +class MetaPackage(Versioned): name: str uid: str recommended: Optional[List[str]] diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 1d739f4725..f7bb29e510 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -4,7 +4,7 @@ from typing import Optional, List, Dict, Any from pydantic import AnyHttpUrl, validator, Field from . import MetaBase, MojangArtifactBase, MojangAssets, MojangLibrary, MojangArtifact, MojangLibraryDownloads, \ - Library, MetaVersionFile, GradleSpecifier + Library, MetaVersion, GradleSpecifier SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 @@ -38,12 +38,12 @@ class MojangLatestVersion(MetaBase): class MojangIndexEntry(MetaBase): id: Optional[str] - releaseTime: Optional[datetime] + release_time: Optional[datetime] = Field(alias="releaseTime") time: Optional[datetime] type: Optional[str] url: Optional[str] sha1: Optional[str] - complianceLevel: Optional[int] + compliance_level: Optional[int] = Field(alias="complianceLevel") class MojangIndex(MetaBase): @@ -80,7 +80,7 @@ class LegacyOverrideEntry(MetaBase): 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): + def apply_onto_meta_version(self, meta_version: MetaVersion, legacy: bool = True): # simply hard override classes meta_version.main_class = self.main_class meta_version.applet_class = self.applet_class @@ -127,40 +127,40 @@ class MojangLogging(MetaBase): class JavaVersion(MetaBase): component: str = "jre-legacy" - majorVersion: int = 8 + major_version: int = Field(8, alias="majorVersion") -class MojangVersionFile(MetaBase): - @validator("minimumLauncherVersion") +class MojangVersion(MetaBase): + @validator("minimum_launcher_version") def validate_minimum_launcher_version(cls, v): assert v <= SUPPORTED_LAUNCHER_VERSION return v - @validator("complianceLevel") + @validator("compliance_level") def validate_compliance_level(cls, v): assert v <= SUPPORTED_COMPLIANCE_LEVEL return v id: str # TODO: optional? arguments: Optional[MojangArguments] - assetIndex: Optional[MojangAssets] + asset_index: Optional[MojangAssets] = Field(alias="assetIndex") assets: Optional[str] downloads: Dict[str, MojangArtifactBase] # TODO improve this? libraries: Optional[List[MojangLibrary]] # TODO: optional? - mainClass: Optional[str] - appletClass: Optional[str] + main_class: Optional[str] = Field(alias="mainClass") + applet_class: Optional[str] = Field(alias="appletClass") processArguments: Optional[str] - minecraftArguments: Optional[str] - minimumLauncherVersion: Optional[int] # TODO: validate validateSupportedMojangVersion - releaseTime: Optional[datetime] + minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") + minimum_launcher_version: Optional[int] = Field(alias="minimumLauncherVersion") # TODO: validate validateSupportedMojangVersion + release_time: Optional[datetime] = Field(alias="releaseTime") time: Optional[datetime] type: Optional[str] inheritsFrom: Optional[str] logging: Optional[Dict[str, MojangLogging]] # TODO improve this? - complianceLevel: Optional[int] + compliance_level: Optional[int] = Field(alias="complianceLevel") javaVersion: Optional[JavaVersion] - def to_meta_version(self, name: str, uid: str, version: str) -> MetaVersionFile: + def to_meta_version(self, name: str, uid: str, version: str) -> MetaVersion: main_jar = None addn_traits = None new_type = self.type @@ -171,14 +171,14 @@ class MojangVersionFile(MetaBase): 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 + if not self.compliance_level: # both == 0 and is None pass - elif self.complianceLevel == 1: + elif self.compliance_level == 1: if not addn_traits: addn_traits = [] addn_traits.append("XR:Initial") else: - raise Exception(f"Unsupported compliance level {self.complianceLevel}") + raise Exception(f"Unsupported compliance level {self.compliance_level}") if self.javaVersion is not None: # some versions don't have this. TODO: maybe maintain manual overrides major = self.javaVersion.major_version @@ -189,15 +189,15 @@ class MojangVersionFile(MetaBase): if new_type == "pending": # TODO: why wasn't this needed before large refactor new_type = "experiment" - return MetaVersionFile( + return MetaVersion( name=name, uid=uid, version=version, - asset_index=self.assetIndex, + asset_index=self.asset_index, libraries=self.libraries, - main_class=self.mainClass, - minecraft_arguments=self.minecraftArguments, - release_time=self.releaseTime, + main_class=self.main_class, + minecraft_arguments=self.minecraft_arguments, + release_time=self.release_time, type=new_type, compatible_java_majors=compatible_java_majors, additional_traits=addn_traits, -- cgit 0.0.5-2-1-g0f52 From 5a6ae1875510bf51a2513fc92fda789cfd9a5f3d Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 3 Apr 2022 13:19:01 +0200 Subject: refactor: move liteloader to pydantic models --- generateLiteloader.py | 163 +++++++++++++++++++++++++--------------------- meta/common/liteloader.py | 7 ++ meta/liteloaderutil.py | 118 --------------------------------- meta/model/liteloader.py | 108 ++++++++++++++++++++++++++++++ updateLiteloader.py | 51 ++++++++------- 5 files changed, 231 insertions(+), 216 deletions(-) create mode 100644 meta/common/liteloader.py delete mode 100644 meta/liteloaderutil.py create mode 100644 meta/model/liteloader.py (limited to 'meta') diff --git a/generateLiteloader.py b/generateLiteloader.py index 63ffc2e1bd..1af84a2232 100755 --- a/generateLiteloader.py +++ b/generateLiteloader.py @@ -1,93 +1,108 @@ -from meta.liteloaderutil import * +import os +from datetime import datetime +from typing import List, Tuple, Dict, Optional + from meta.common import ensure_component_dir, polymc_path, upstream_path +from meta.common.liteloader import LITELOADER_COMPONENT, VERSIONS_FILE +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import MetaVersion, GradleSpecifier, Library, MetaPackage, Dependency +from meta.model.liteloader import LiteloaderIndex, LiteloaderArtefact PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() -ensure_component_dir("com.mumfrey.liteloader") - - -# load the locally cached version list -def loadLiteloaderJson(): - with open(UPSTREAM_DIR + "/liteloader/versions.json", 'r', encoding='utf-8') as f: - return LiteloaderIndex(json.load(f)) +ensure_component_dir(LITELOADER_COMPONENT) -remoteVersionlist = loadLiteloaderJson() - - -def processArtefacts(mcVersion, liteloader, notSnapshots): - versions = [] - lookup = {} - latestVersion = None +def process_artefacts(mc_version: str, artefacts: Dict[str, LiteloaderArtefact], is_snapshot: bool) \ + -> Tuple[List[MetaVersion], Optional[MetaVersion]]: + versions: List[MetaVersion] = [] + lookup: Dict[str, MetaVersion] = {} + latest_version = None latest = None - for id, artefact in liteloader.items(): - if id == 'latest': - latestVersion = artefact.version + for x, artefact in artefacts.items(): + if x == 'latest': + latest_version = artefact.version continue - version = PolyMCVersionFile(name="LiteLoader", uid="com.mumfrey.liteloader", version=artefact.version) - version.requires = [DependencyEntry(uid='net.minecraft', equals=mcVersion)] - version.releaseTime = datetime.datetime.utcfromtimestamp(int(artefact.timestamp)) - version.addTweakers = [artefact.tweakClass] - version.mainClass = "net.minecraft.launchwrapper.Launch" - version.order = 10 - if notSnapshots: - version.type = "release" - else: - version.type = "snapshot" - lookup[version.version] = version - libraries = artefact.libraries + v = MetaVersion( + name="LiteLoader", + uid=LITELOADER_COMPONENT, + version=artefact.version, + requires=[Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)], + release_time=datetime.utcfromtimestamp(int(artefact.timestamp)), + additional_tweakers=[artefact.tweakClass], + main_class="net.minecraft.launchwrapper.Launch", + order=10, + libraries=artefact.libraries, + type="release") + + if is_snapshot: + v.type = "snapshot" + # hack to make broken liteloader versions work - for lib in libraries: + for lib in v.libraries: if lib.name == GradleSpecifier("org.ow2.asm:asm-all:5.0.3"): lib.url = "https://repo.maven.apache.org/maven2/" if lib.name == GradleSpecifier("org.ow2.asm:asm-all:5.2"): lib.url = "http://repo.liteloader.com/" - liteloaderLib = PolyMCLibrary( - name=GradleSpecifier("com.mumfrey:liteloader:%s" % version.version), + + liteloader_lib = Library( + name=GradleSpecifier("com.mumfrey:liteloader:%s" % v.version), url="http://dl.liteloader.com/versions/" ) - if not notSnapshots: - liteloaderLib.mmcHint = "always-stale" - libraries.append(liteloaderLib) - version.libraries = libraries - versions.append(version) - if latestVersion: - latest = lookup[latestVersion] + if is_snapshot: + liteloader_lib.mmcHint = "always-stale" + v.libraries.append(liteloader_lib) + + versions.append(v) + lookup[v.version] = v + + if latest_version: + latest = lookup[latest_version] return versions, latest -allVersions = [] -recommended = [] -for mcVersion, versionObject in remoteVersionlist.versions.items(): - # ignore this for now. It should be a jar mod or something. - if mcVersion == "1.5.2": - continue - latestSnapshot = None - latestRelease = None - version = [] - if versionObject.artefacts: - versions, latestRelease = processArtefacts(mcVersion, versionObject.artefacts.liteloader, True) - allVersions.extend(versions) - if versionObject.snapshots: - versions, latestSnapshot = processArtefacts(mcVersion, versionObject.snapshots.liteloader, False) - allVersions.extend(versions) - - if latestRelease: - recommended.append(latestRelease.version) - -recommended.sort() - -allVersions.sort(key=lambda x: x.releaseTime, reverse=True) - -for version in allVersions: - outFilepath = PMC_DIR + "/com.mumfrey.liteloader/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) - -sharedData = PolyMCSharedPackageData(uid='com.mumfrey.liteloader', name='LiteLoader') -sharedData.recommended = recommended -sharedData.description = remoteVersionlist.meta.description -sharedData.projectUrl = remoteVersionlist.meta.url -sharedData.authors = [remoteVersionlist.meta.authors] -sharedData.write() +def process_versions(index: LiteloaderIndex) -> Tuple[List[MetaVersion], List[str]]: + all_versions: List[MetaVersion] = [] + recommended: List[str] = [] + for mcVersion, versionObject in index.versions.items(): + # ignore this for now. It should be a jar mod or something. + if mcVersion == "1.5.2": + continue + + latest_release = None + if versionObject.artefacts: + versions, latest_release = process_artefacts(mcVersion, versionObject.artefacts.liteloader, False) + all_versions.extend(versions) + if versionObject.snapshots: + versions, latest_snapshot = process_artefacts(mcVersion, versionObject.snapshots.liteloader, True) + all_versions.extend(versions) + + if latest_release: + recommended.append(latest_release.version) + + recommended.sort() + + all_versions.sort(key=lambda x: x.release_time, reverse=True) + return all_versions, recommended + + +def main(): + index = LiteloaderIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) + + all_versions, recommended = process_versions(index) + + for version in all_versions: + version.write(os.path.join(PMC_DIR, LITELOADER_COMPONENT, f"{version.version}.json")) + + package = MetaPackage(uid=LITELOADER_COMPONENT, + name='LiteLoader', + description=index.meta.description, + project_url=index.meta.url, + authors=[index.meta.authors], + recommended=recommended) + package.write(os.path.join(PMC_DIR, LITELOADER_COMPONENT, "package.json")) + + +if __name__ == '__main__': + main() diff --git a/meta/common/liteloader.py b/meta/common/liteloader.py new file mode 100644 index 0000000000..7a6c19eb46 --- /dev/null +++ b/meta/common/liteloader.py @@ -0,0 +1,7 @@ +from os.path import join + +BASE_DIR = "liteloader" + +VERSIONS_FILE = join(BASE_DIR, "versions.json") + +LITELOADER_COMPONENT = "com.mumfrey.liteloader" diff --git a/meta/liteloaderutil.py b/meta/liteloaderutil.py deleted file mode 100644 index dce6cb19d4..0000000000 --- a/meta/liteloaderutil.py +++ /dev/null @@ -1,118 +0,0 @@ -from .metautil import * - -''' - "repo":{ - "stream":"RELEASE", - "type":"m2", - "url":"http:\/\/dl.liteloader.com\/repo\/", - "classifier":"" - }, -''' - - -class LiteloaderRepo(JsonObject): - stream = StringProperty(required=True) - type = StringProperty(required=True) - url = StringProperty(required=True) - classifier = StringProperty(required=True) - - -''' - "53639d52340479ccf206a04f5e16606f":{ - "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", - "libraries":[ - { - "name":"net.minecraft:launchwrapper:1.5" - }, - { - "name":"net.sf.jopt-simple:jopt-simple:4.5" - }, - { - "name":"org.ow2.asm:asm-all:4.1" - } - ], - "stream":"RELEASE", - "file":"liteloader-1.5.2_01.jar", - "version":"1.5.2_01", - "md5":"53639d52340479ccf206a04f5e16606f", - "timestamp":"1367366420" - }, -''' - - -class LiteloaderArtefact(JsonObject): - tweakClass = StringProperty(required=True) - libraries = ListProperty(PolyMCLibrary, required=True) - stream = StringProperty(required=True) - file = StringProperty(required=True) - version = StringProperty(required=True) - build = StringProperty(default=None, exclude_if_none=True) - md5 = StringProperty(required=True) - timestamp = StringProperty(required=True) - srcJar = StringProperty(default=None, exclude_if_none=True) - mcpJar = StringProperty(default=None, exclude_if_none=True) - - -class LiteloaderDev(JsonObject): - fgVersion = StringProperty(default=None, exclude_if_none=True) - mappings = StringProperty(required=None, exclude_if_none=True) - mcp = StringProperty(default=None, exclude_if_none=True) - - -class LiteloaderArtefacts(JsonObject): - liteloader = DictProperty(LiteloaderArtefact, name="com.mumfrey:liteloader", required=True) - - -class LiteloaderSnapshot(LiteloaderArtefact): - lastSuccessfulBuild = IntegerProperty() - - -class LiteloaderSnapshots(JsonObject): - libraries = ListProperty(PolyMCLibrary, required=True) - liteloader = DictProperty(LiteloaderSnapshot, name="com.mumfrey:liteloader", required=True) - - -''' - "1.10.2":{ - "dev": { ... }, - "repo":{ ... }, - "artefacts":{ - "com.mumfrey:liteloader":{ }, - ... - }, - "snapshots":{ - ... - } -''' - - -class LiteloaderEntry(JsonObject): - dev = ObjectProperty(LiteloaderDev, default=None, exclude_if_none=True) - repo = ObjectProperty(LiteloaderRepo, required=True) - artefacts = ObjectProperty(LiteloaderArtefacts, default=None, exclude_if_none=True) - snapshots = ObjectProperty(LiteloaderSnapshots, default=None, exclude_if_none=True) - - -''' - "meta":{ - "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", - "authors":"Mumfrey", - "url":"http:\/\/dl.liteloader.com", - "updated":"2017-02-22T11:34:07+00:00", - "updatedTime":1487763247 - }, -''' - - -class LiteloaderMeta(JsonObject): - description = StringProperty(required=True) - authors = StringProperty(required=True) - url = StringProperty(required=True) - updated = ISOTimestampProperty(required=True) - updatedTime = IntegerProperty(required=True) - - -# The raw Forge version index -class LiteloaderIndex(JsonObject): - meta = ObjectProperty(LiteloaderMeta, required=True) - versions = DictProperty(LiteloaderEntry) diff --git a/meta/model/liteloader.py b/meta/model/liteloader.py new file mode 100644 index 0000000000..0bd6794773 --- /dev/null +++ b/meta/model/liteloader.py @@ -0,0 +1,108 @@ +from datetime import datetime +from typing import Optional, List, Dict, Any + +from pydantic import Field + +from . import Library, MetaBase + + +class LiteloaderDev(MetaBase): + fgVersion: Optional[str] + mappings: Optional[str] + mcp: Optional[str] + + +class LiteloaderRepo(MetaBase): + """ + "repo":{ + "stream":"RELEASE", + "type":"m2", + "url":"http://dl.liteloader.com/repo/", + "classifier":"" + }, + """ + stream: str + type: str + url: str + classifier: str + + +class LiteloaderArtefact(MetaBase): + """ + "53639d52340479ccf206a04f5e16606f":{ + "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", + "libraries":[ + { + "name":"net.minecraft:launchwrapper:1.5" + }, + { + "name":"net.sf.jopt-simple:jopt-simple:4.5" + }, + { + "name":"org.ow2.asm:asm-all:4.1" + } + ], + "stream":"RELEASE", + "file":"liteloader-1.5.2_01.jar", + "version":"1.5.2_01", + "md5":"53639d52340479ccf206a04f5e16606f", + "timestamp":"1367366420" + }, + """ + tweakClass: str + libraries: List[Library] + stream: str + file: str + version: str + build: Optional[str] + md5: str + timestamp: str + srcJar: Optional[str] + mcpJar: Optional[str] + lastSuccessfulBuild: Optional[int] # only for snapshots + + +class LiteloaderArtefacts(MetaBase): + liteloader: Dict[str, LiteloaderArtefact] = Field(alias="com.mumfrey:liteloader") + libraries: Optional[List[Library]] + + +class LiteloaderEntry(MetaBase): + """ + "1.10.2":{ + "dev": { ... }, + "repo":{ ... }, + "artefacts":{ + "com.mumfrey:liteloader":{ }, + ... + }, + "snapshots":{ + ... + } + """ + dev: Optional[LiteloaderDev] + repo: LiteloaderRepo + artefacts: Optional[LiteloaderArtefacts] + snapshots: Optional[LiteloaderArtefacts] + + +class LiteloaderMeta(MetaBase): + """ + "meta":{ + "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", + "authors":"Mumfrey", + "url":"http://dl.liteloader.com", + "updated":"2017-02-22T11:34:07+00:00", + "updatedTime":1487763247 + }, + """ + description: str + authors: str + url: str + updated: datetime + updated_time: int = Field(alias="updatedTime") + + +class LiteloaderIndex(MetaBase): + meta: LiteloaderMeta + versions: Dict[Any, LiteloaderEntry] diff --git a/updateLiteloader.py b/updateLiteloader.py index 2add518446..e4d09fabc8 100755 --- a/updateLiteloader.py +++ b/updateLiteloader.py @@ -1,37 +1,40 @@ -''' - Get the source files necessary for generating Forge versions -''' -import copy -import sys +import json +import os import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.liteloaderutil import * -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] - - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) +from meta.common import upstream_path +from meta.common.liteloader import VERSIONS_FILE +from meta.model.liteloader import LiteloaderIndex +UPSTREAM_DIR = upstream_path() forever_cache = FileCache('caches/http_cache', forever=True) sess = CacheControl(requests.Session(), forever_cache) -# get the remote version list -r = sess.get('http://dl.liteloader.com/versions/versions.json') -r.raise_for_status() -# make sure it's JSON -main_json = r.json() +def main(): + # get the remote version list + r = sess.get('http://dl.liteloader.com/versions/versions.json') + r.raise_for_status() + + # make sure it's JSON + main_json = r.json() + + # make sure we understand the schema + remote_versions = LiteloaderIndex.parse_obj(main_json) + parsed = remote_versions.json() + original = json.dumps(main_json, sort_keys=True, indent=4) + assert parsed == original + + print("Successfully parsed index") + print(f"Last updated {remote_versions.meta.updated}") + + # save the json it to file + remote_versions.write(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) -# make sure we understand the schema -remoteVersionlist = LiteloaderIndex(copy.deepcopy(main_json)) -newStr = json.dumps(remoteVersionlist.to_json(), sort_keys=True) -origStr = json.dumps(main_json, sort_keys=True) -assert newStr == origStr -# save the json it to file -with open(UPSTREAM_DIR + "/liteloader/versions.json", 'w', encoding='utf-8') as f: - json.dump(main_json, f, sort_keys=True, indent=4) +if __name__ == '__main__': + main() -- cgit 0.0.5-2-1-g0f52 From efd1aff14718c206627def2fbd5b1e94940930fd Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 00:19:03 +0200 Subject: fix: expect strings instead of urls in all models --- meta/model/__init__.py | 10 +++++----- meta/model/mojang.py | 11 ++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index d7373323a1..ed4e4c4b0c 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -2,7 +2,7 @@ from datetime import datetime from typing import Optional, List, Dict, Any, Iterator import pydantic -from pydantic import Field, AnyHttpUrl, validator +from pydantic import Field, validator from .types import GradleSpecifier from ..common import serialize_datetime @@ -40,7 +40,7 @@ class MetaBase(pydantic.BaseModel): class Versioned(MetaBase): @validator("format_version") def format_version_must_be_supported(cls, v): - assert v > META_FORMAT_VERSION + assert v <= META_FORMAT_VERSION return v format_version: int = Field(META_FORMAT_VERSION, alias="formatVersion") @@ -49,7 +49,7 @@ class Versioned(MetaBase): class MojangArtifactBase(MetaBase): sha1: Optional[str] size: Optional[int] - url: AnyHttpUrl + url: str class MojangAssets(MojangArtifactBase): @@ -129,7 +129,7 @@ class MojangLibrary(MetaBase): class Library(MojangLibrary): url: Optional[str] - mmcHint: Optional[AnyHttpUrl] = Field(None, alias="MMC-hint") + mmcHint: Optional[str] = Field(None, alias="MMC-hint") class Dependency(MetaBase): @@ -167,4 +167,4 @@ class MetaPackage(Versioned): recommended: Optional[List[str]] authors: Optional[List[str]] description: Optional[str] - project_url: Optional[AnyHttpUrl] = Field(alias="projectUrl") + project_url: Optional[str] = Field(alias="projectUrl") diff --git a/meta/model/mojang.py b/meta/model/mojang.py index f7bb29e510..0b8415d4ee 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -1,7 +1,7 @@ from datetime import datetime from typing import Optional, List, Dict, Any -from pydantic import AnyHttpUrl, validator, Field +from pydantic import validator, Field from . import MetaBase, MojangArtifactBase, MojangAssets, MojangLibrary, MojangArtifact, MojangLibraryDownloads, \ Library, MetaVersion, GradleSpecifier @@ -60,8 +60,8 @@ class MojangIndexWrap: class ExperimentEntry(MetaBase): id: str - url: AnyHttpUrl - wiki: Optional[AnyHttpUrl] + url: str + wiki: Optional[str] class ExperimentIndex(MetaBase): @@ -145,13 +145,14 @@ class MojangVersion(MetaBase): arguments: Optional[MojangArguments] asset_index: Optional[MojangAssets] = Field(alias="assetIndex") assets: Optional[str] - downloads: Dict[str, MojangArtifactBase] # TODO improve this? + downloads: Optional[Dict[str, MojangArtifactBase]] # TODO improve this? libraries: Optional[List[MojangLibrary]] # TODO: optional? main_class: Optional[str] = Field(alias="mainClass") applet_class: Optional[str] = Field(alias="appletClass") processArguments: Optional[str] minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") - minimum_launcher_version: Optional[int] = Field(alias="minimumLauncherVersion") # TODO: validate validateSupportedMojangVersion + minimum_launcher_version: Optional[int] = Field( + alias="minimumLauncherVersion") # TODO: validate validateSupportedMojangVersion release_time: Optional[datetime] = Field(alias="releaseTime") time: Optional[datetime] type: Optional[str] -- cgit 0.0.5-2-1-g0f52 From 7ab37c8658c4c8614a85e5ff729aa4ef3592801f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 14:02:24 +0200 Subject: refactor: make GradleSpecifier its own class --- generateFabric.py | 4 +-- generateLiteloader.py | 6 ++-- generateMojang.py | 3 +- meta/model/__init__.py | 9 ++---- meta/model/mojang.py | 2 +- meta/model/types.py | 80 ++++++++++++++++++++++++++++++++++++++------------ 6 files changed, 70 insertions(+), 34 deletions(-) (limited to 'meta') diff --git a/generateFabric.py b/generateFabric.py index 2de6724e5e..cfdcdf4e61 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -38,7 +38,7 @@ def process_loader_version(entry) -> MetaVersion: v.libraries = [] v.libraries.extend(installer_info.libraries.common) v.libraries.extend(installer_info.libraries.client) - loader_lib = Library(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + loader_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), url="https://maven.fabricmc.net") v.libraries.append(loader_lib) return v @@ -53,7 +53,7 @@ def process_intermediary_version(entry) -> MetaVersion: v.type = "release" v.libraries = [] v.volatile = True - intermediary_lib = Library(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + intermediary_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), url="https://maven.fabricmc.net") v.libraries.append(intermediary_lib) return v diff --git a/generateLiteloader.py b/generateLiteloader.py index 1af84a2232..17882d582b 100755 --- a/generateLiteloader.py +++ b/generateLiteloader.py @@ -41,13 +41,13 @@ def process_artefacts(mc_version: str, artefacts: Dict[str, LiteloaderArtefact], # hack to make broken liteloader versions work for lib in v.libraries: - if lib.name == GradleSpecifier("org.ow2.asm:asm-all:5.0.3"): + if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.0.3"): lib.url = "https://repo.maven.apache.org/maven2/" - if lib.name == GradleSpecifier("org.ow2.asm:asm-all:5.2"): + if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.2"): lib.url = "http://repo.liteloader.com/" liteloader_lib = Library( - name=GradleSpecifier("com.mumfrey:liteloader:%s" % v.version), + name=GradleSpecifier("com.mumfrey", "liteloader", v.version), url="http://dl.liteloader.com/versions/" ) if is_snapshot: diff --git a/generateMojang.py b/generateMojang.py index c26428c126..8e573efa41 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -267,8 +267,7 @@ def main(): if lib.name.artifact not in LOG4J_HASHES[version_override]: raise Exception("ERROR: unhandled log4j artifact %s!" % lib.name.artifact) - replacement_name = GradleSpecifier( - "org.apache.logging.log4j:%s:%s" % (lib.name.artifact, version_override)) + replacement_name = GradleSpecifier("org.apache.logging.log4j", lib.name.artifact, version_override) artifact = MojangArtifact( url=maven_override % (replacement_name.path()), sha1=LOG4J_HASHES[version_override][lib.name.artifact]["sha1"], diff --git a/meta/model/__init__.py b/meta/model/__init__.py index ed4e4c4b0c..3cc6a3b96e 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -33,7 +33,8 @@ class MetaBase(pydantic.BaseModel): allow_population_by_field_name = True json_encoders = { - datetime: serialize_datetime + datetime: serialize_datetime, + GradleSpecifier: str } @@ -114,12 +115,6 @@ class MojangRules(MetaBase): 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] diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 0b8415d4ee..0df4cbcfc0 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -170,7 +170,7 @@ class MojangVersion(MetaBase): 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) + main_jar = Library(name=GradleSpecifier("com.mojang", "minecraft", self.id, "client"), downloads=downloads) if not self.compliance_level: # both == 0 and is None pass diff --git a/meta/model/types.py b/meta/model/types.py index d631565718..2fd5435e1e 100644 --- a/meta/model/types.py +++ b/meta/model/types.py @@ -1,4 +1,7 @@ -class GradleSpecifier(str): +from typing import Optional + + +class GradleSpecifier: """ A gradle specifier - a maven coordinate. Like one of these: "org.lwjgl.lwjgl:lwjgl:2.9.0" @@ -6,24 +9,24 @@ class GradleSpecifier(str): "net.minecraft:launchwrapper:1.5" """ - def __init__(self, name: str): - ext_split = name.split('@') - - components = ext_split[0].split(':') - self.group = components[0] - self.artifact = components[1] - self.version = components[2] - - self.extension = 'jar' - if len(ext_split) == 2: - self.extension = ext_split[1] + def __init__(self, group: str, artifact: str, version: str, classifier: Optional[str] = None, + extension: Optional[str] = None): + if extension is None: + extension = "jar" + self.group = group + self.artifact = artifact + self.version = version + self.classifier = classifier + self.extension = extension - self.classifier = None - if len(components) == 4: - self.classifier = components[3] - - def __new__(cls, name: str): - return super(GradleSpecifier, cls).__new__(cls, name) + def __str__(self): + ext = '' + if self.extension != 'jar': + ext = "@%s" % self.extension + if self.classifier: + return "%s:%s:%s:%s%s" % (self.group, self.artifact, self.version, self.classifier, ext) + else: + return "%s:%s:%s%s" % (self.group, self.artifact, self.version, ext) def filename(self): if self.classifier: @@ -44,4 +47,43 @@ class GradleSpecifier(str): return self.group in ("org.lwjgl", "org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils") def is_log4j(self): - return self.group == "org.apache.logging.log4j" \ No newline at end of file + return self.group == "org.apache.logging.log4j" + + def __eq__(self, other): + return str(self) == str(other) + + def __lt__(self, other): + return str(self) < str(other) + + def __gt__(self, other): + return str(self) > str(other) + + @classmethod + def __get_validators__(cls): + yield cls.validate + + @classmethod + def from_string(cls, v: str): + ext_split = v.split('@') + + components = ext_split[0].split(':') + group = components[0] + artifact = components[1] + version = components[2] + + extension = None + if len(ext_split) == 2: + extension = ext_split[1] + + classifier = None + if len(components) == 4: + classifier = components[3] + return cls(group, artifact, version, classifier, extension) + + @classmethod + def validate(cls, v): + if isinstance(v, cls): + return v + if isinstance(v, str): + return cls.from_string(v) + raise TypeError("Invalid type") -- cgit 0.0.5-2-1-g0f52 From eda318131d1e938ee331cc2149a0518e25b7aa76 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 14:29:44 +0200 Subject: refactor: move forge to pydantic models --- generateForge.py | 478 ++--- meta/common/forge.py | 17 + meta/forgeutil.py | 323 ---- meta/model/forge.py | 306 +++ static/forge-legacyinfo.json | 3712 ------------------------------------ static/forge/forge-legacyinfo.json | 3712 ++++++++++++++++++++++++++++++++++++ updateForge.py | 517 +++-- 7 files changed, 4505 insertions(+), 4560 deletions(-) create mode 100644 meta/common/forge.py delete mode 100644 meta/forgeutil.py create mode 100644 meta/model/forge.py delete mode 100644 static/forge-legacyinfo.json create mode 100644 static/forge/forge-legacyinfo.json (limited to 'meta') diff --git a/generateForge.py b/generateForge.py index 222233023c..b161b29a3e 100755 --- a/generateForge.py +++ b/generateForge.py @@ -1,17 +1,24 @@ +import os import re import sys +from datetime import timezone from distutils.version import LooseVersion -from meta.forgeutil import * -from meta.metautil import * -from meta.common import ensure_component_dir, polymc_path, upstream_path +from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path +from meta.common.forge import FORGE_COMPONENT, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, \ + STATIC_LEGACYINFO_FILE, INSTALLER_INFO_DIR, BAD_VERSIONS, FORGEWRAPPER_MAVEN +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import MetaVersion, Dependency, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, \ + MetaPackage +from meta.model.forge import ForgeVersion, ForgeInstallerProfile, ForgeLegacyInfo, fml_libs_for_version, \ + ForgeInstallerProfileV2, InstallerInfo, DerivedForgeIndex, ForgeLegacyInfoList +from meta.model.mojang import MojangVersion PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() +STATIC_DIR = static_path() -ensure_component_dir("net.minecraftforge") - -FORGEWRAPPER_MAVEN = "https://polymc.github.io/files/maven/%s" +ensure_component_dir(FORGE_COMPONENT) def eprint(*args, **kwargs): @@ -26,12 +33,11 @@ def loadMcVersionFilter(version): if version in mcVersionCache: return mcVersionCache[version] libSet = set() - with open(PMC_DIR + "/net.minecraft/%s.json" % version, 'r', encoding='utf-8') as mcFile: - mcVersion = PolyMCVersionFile(json.load(mcFile)) - for lib in mcVersion.libraries: - libSet.add(lib.name) - mcVersionCache[version] = libSet - return libSet + mcVersion = MetaVersion.parse_file(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version}.json")) + for lib in mcVersion.libraries: + libSet.add(lib.name) + mcVersionCache[version] = libSet + return libSet ''' @@ -58,30 +64,30 @@ def shouldIgnoreArtifact(libSet, match): return False -def versionFromProfile(profile, version): - result = PolyMCVersionFile({"name": "Forge", "version": version.rawVersion, "uid": "net.minecraftforge"}) +def versionFromProfile(profile: ForgeInstallerProfile, version): + result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) mcversion = profile.install.minecraft - result.requires = [DependencyEntry(uid='net.minecraft', equals=mcversion)] - result.mainClass = profile.versionInfo.mainClass - args = profile.versionInfo.minecraftArguments + result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mcversion)] + result.main_class = profile.versionInfo.main_class + args = profile.versionInfo.minecraft_arguments tweakers = [] expression = re.compile("--tweakClass ([a-zA-Z0-9\\.]+)") match = expression.search(args) - while match != None: - tweakers.append(match.group(1)); + while match is not None: + tweakers.append(match.group(1)) args = args[:match.start()] + args[match.end():] - match = expression.search(args); + match = expression.search(args) if len(tweakers) > 0: args = args.strip() - result.addTweakers = tweakers; + result.additional_tweakers = tweakers # result.minecraftArguments = args - result.releaseTime = profile.versionInfo.time + result.release_time = profile.versionInfo.time libs = [] mcFilter = loadMcVersionFilter(mcversion) for forgeLib in profile.versionInfo.libraries: - if forgeLib.name.isLwjgl(): + if forgeLib.name.is_lwjgl(): continue - if forgeLib.name.isLog4j(): + if forgeLib.name.is_log4j(): continue if shouldIgnoreArtifact(mcFilter, forgeLib.name): continue @@ -93,7 +99,7 @@ def versionFromProfile(profile, version): fixedName.version = "%s-%s" % (mcversion, fixedName.version) elif fixedName.artifact == "forge": fixedName.classifier = "universal" - ourLib = PolyMCLibrary(name=fixedName) + ourLib = Library(name=fixedName) if forgeLib.url == "http://files.minecraftforge.net/maven/": ourLib.url = "https://maven.minecraftforge.net/" else: @@ -106,32 +112,32 @@ def versionFromProfile(profile, version): return result -def versionFromModernizedInstaller(installerVersion: MojangVersionFile, version: ForgeVersion): +def versionFromModernizedInstaller(installerVersion: MojangVersion, version: ForgeVersion): eprint("Generating Modernized Forge %s." % version.longVersion) - result = PolyMCVersionFile({"name": "Forge", "version": version.rawVersion, "uid": "net.minecraftforge"}) + result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) mcversion = version.mcversion - result.requires = [DependencyEntry(uid='net.minecraft', equals=mcversion)] - result.mainClass = installerVersion.mainClass - args = installerVersion.minecraftArguments + result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mcversion)] + result.main_class = installerVersion.main_class + args = installerVersion.minecraft_arguments tweakers = [] expression = re.compile("--tweakClass ([a-zA-Z0-9\\.]+)") match = expression.search(args) - while match != None: - tweakers.append(match.group(1)); + while match is not None: + tweakers.append(match.group(1)) args = args[:match.start()] + args[match.end():] - match = expression.search(args); + match = expression.search(args) if len(tweakers) > 0: args = args.strip() - result.addTweakers = tweakers; + result.additional_tweakers = tweakers # result.minecraftArguments = args - result.releaseTime = installerVersion.releaseTime + result.release_time = installerVersion.release_time libs = [] mcFilter = loadMcVersionFilter(mcversion) for upstreamLib in installerVersion.libraries: - pmcLib = PolyMCLibrary(upstreamLib.to_json()) - if pmcLib.name.isLwjgl(): + pmcLib = Library.parse_obj(upstreamLib.dict()) + if pmcLib.name.is_lwjgl(): continue - if pmcLib.name.isLog4j(): + if pmcLib.name.is_log4j(): continue if shouldIgnoreArtifact(mcFilter, pmcLib.name): continue @@ -139,8 +145,8 @@ def versionFromModernizedInstaller(installerVersion: MojangVersionFile, version: if pmcLib.name.artifact == "forge": fixedName = pmcLib.name fixedName.classifier = "universal" - pmcLib.downloads.artifact.path = fixedName.getPath() - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.getPath() + pmcLib.downloads.artifact.path = fixedName.path() + pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.path() pmcLib.name = fixedName libs.append(pmcLib) continue @@ -149,8 +155,8 @@ def versionFromModernizedInstaller(installerVersion: MojangVersionFile, version: fixedName.artifact = "forge" fixedName.classifier = "universal" fixedName.version = "%s-%s" % (mcversion, fixedName.version) - pmcLib.downloads.artifact.path = fixedName.getPath() - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.getPath() + pmcLib.downloads.artifact.path = fixedName.path() + pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.path() pmcLib.name = fixedName libs.append(pmcLib) continue @@ -161,288 +167,228 @@ def versionFromModernizedInstaller(installerVersion: MojangVersionFile, version: return result -def versionFromLegacy(version, legacyinfo: ForgeLegacyInfo): - result = PolyMCVersionFile({"name": "Forge", "version": version.rawVersion, "uid": "net.minecraftforge"}) +def versionFromLegacy(version: ForgeVersion, legacyinfo: ForgeLegacyInfo): + result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) mcversion = version.mcversion_sane - result.requires = [DependencyEntry(uid='net.minecraft', equals=mcversion)] - result.releaseTime = legacyinfo.releaseTime + result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mcversion)] + result.release_time = legacyinfo.releaseTime result.order = 5 - if mcversion in fmlLibsMapping: - result.addTraits = ["legacyFML"] + if fml_libs_for_version(mcversion): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING + result.additional_traits = ["legacyFML"] url = version.url() - classifier = None if "universal" in url: classifier = "universal" else: classifier = "client" - coord = GradleSpecifier("net.minecraftforge:forge:%s:%s" % (version.longVersion, classifier)) - mainmod = PolyMCLibrary(name=coord) + coord = GradleSpecifier("net.minecraftforge", "forge", version.longVersion, classifier) + mainmod = Library(name=coord) mainmod.downloads = MojangLibraryDownloads() - mainmod.downloads.artifact = MojangArtifact() + mainmod.downloads.artifact = MojangArtifact(url=version.url(), sha1=legacyinfo.sha1, size=legacyinfo.size) mainmod.downloads.artifact.path = None - mainmod.downloads.artifact.url = version.url() - mainmod.downloads.artifact.sha1 = legacyinfo.sha1 - mainmod.downloads.artifact.size = legacyinfo.size - result.jarMods = [mainmod] + result.jar_mods = [mainmod] return result -def versionFromBuildSystemInstaller(installerVersion: MojangVersionFile, installerProfile: ForgeInstallerProfileV2, +def versionFromBuildSystemInstaller(installerVersion: MojangVersion, installerProfile: ForgeInstallerProfileV2, version: ForgeVersion): eprint("Generating Forge %s." % version.longVersion) - result = PolyMCVersionFile({"name": "Forge", "version": version.rawVersion, "uid": "net.minecraftforge"}) - result.requires = [DependencyEntry(uid='net.minecraft', equals=version.mcversion_sane)] - result.mainClass = "io.github.zekerzhayard.forgewrapper.installer.Main" + result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mcversion_sane)] + result.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" # FIXME: Add the size and hash here mavenLibs = [] # load the locally cached installer file info and use it to add the installer entry in the json - with open(UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.longVersion, 'r', encoding='utf-8') as f: - installerInfo = InstallerInfo(json.load(f)) - InstallerLib = PolyMCLibrary( - name=GradleSpecifier("net.minecraftforge:forge:%s:installer" % (version.longVersion))) - InstallerLib.downloads = MojangLibraryDownloads() - InstallerLib.downloads.artifact = MojangArtifact() - InstallerLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % ( - InstallerLib.name.getPath()) - InstallerLib.downloads.artifact.sha1 = installerInfo.sha1hash - InstallerLib.downloads.artifact.size = installerInfo.size - mavenLibs.append(InstallerLib) + installerInfo = InstallerInfo.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.longVersion}.json")) + InstallerLib = Library( + name=GradleSpecifier("net.minecraftforge", "forge", version.longVersion, "installer")) + InstallerLib.downloads = MojangLibraryDownloads() + InstallerLib.downloads.artifact = MojangArtifact( + url="https://files.minecraftforge.net/maven/%s" % (InstallerLib.name.path()), + sha1=installerInfo.sha1hash, + size=installerInfo.size) + mavenLibs.append(InstallerLib) for upstreamLib in installerProfile.libraries: - pmcLib = PolyMCLibrary(upstreamLib.to_json()) + pmcLib = Library.parse_obj(upstreamLib.dict()) if pmcLib.name.group == "net.minecraftforge": if pmcLib.name.artifact == "forge": if pmcLib.name.classifier == "universal": - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % pmcLib.name.getPath() + pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % pmcLib.name.path() mavenLibs.append(pmcLib) continue - if pmcLib.name.isLog4j(): + if pmcLib.name.is_log4j(): continue mavenLibs.append(pmcLib) - result.mavenFiles = mavenLibs + result.maven_files = mavenLibs libraries = [] - # wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:1.4.1")) - # wrapperLib.downloads = MojangLibraryDownloads() - # wrapperLib.downloads.artifact = MojangArtifact() - # wrapperLib.downloads.artifact.url = "https://meta.polymc.org/maven/%s" % (wrapperLib.name.getPath()) - # wrapperLib.downloads.artifact.sha1 = "82f01de97e29ba34be9fc628084b6d10ce2235c5" - # wrapperLib.downloads.artifact.size = 14351 - # libraries.append(wrapperLib) - - # wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:1.4.2")) - # wrapperLib.downloads = MojangLibraryDownloads() - # wrapperLib.downloads.artifact = MojangArtifact() - # wrapperLib.downloads.artifact.url = "https://meta.polymc.org/maven/%s" % (wrapperLib.name.getPath()) - # wrapperLib.downloads.artifact.sha1 = "79ff9c1530e8743450c5c3ebc6e07b535437aa6e" - # wrapperLib.downloads.artifact.size = 22346 - # libraries.append(wrapperLib) - - # wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:1.5.1")) - # wrapperLib.downloads = MojangLibraryDownloads() - # wrapperLib.downloads.artifact = MojangArtifact() - # wrapperLib.downloads.artifact.url = "https://meta.polymc.org/maven/%s" % (wrapperLib.name.getPath()) - # wrapperLib.downloads.artifact.sha1 = "90104e9aaa8fbedf6c3d1f6d0b90cabce080b5a9" - # wrapperLib.downloads.artifact.size = 29892 - # libraries.append(wrapperLib) - - # wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:1.5.3")) - # wrapperLib.downloads = MojangLibraryDownloads() - # wrapperLib.downloads.artifact = MojangArtifact() - # wrapperLib.downloads.artifact.url = "https://meta.polymc.org/maven/%s" % (wrapperLib.name.getPath()) - # wrapperLib.downloads.artifact.sha1 = "2b0e06937349a209dbb90dca6381258daa456ad7" - # wrapperLib.downloads.artifact.size = 30486 - # libraries.append(wrapperLib) - - # wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:1.5.4")) - # wrapperLib.downloads = MojangLibraryDownloads() - # wrapperLib.downloads.artifact = MojangArtifact() - # wrapperLib.downloads.artifact.url = "https://meta.polymc.org/maven/%s" % (wrapperLib.name.getPath()) - # wrapperLib.downloads.artifact.sha1 = "e97805af76d4c1cebb753132eadbabd92e67a17b" - # wrapperLib.downloads.artifact.size = 34299 - # libraries.append(wrapperLib) - - # wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:pmc1")) - # wrapperLib.downloads = MojangLibraryDownloads() - # wrapperLib.downloads.artifact = MojangArtifact() - # wrapperLib.downloads.artifact.url = "https://meta.polymc.org/maven/%s" % (wrapperLib.name.getPath()) - # wrapperLib.downloads.artifact.sha1 = "e8e0fe708742ecf15ab4af55ae8227fa4349362d" - # wrapperLib.downloads.artifact.size = 34628 - # libraries.append(wrapperLib) - - # wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:1.5.5")) - # wrapperLib.downloads = MojangLibraryDownloads() - # wrapperLib.downloads.artifact = MojangArtifact() - # wrapperLib.downloads.artifact.url = "https://meta.polymc.org/maven/%s" % (wrapperLib.name.getPath()) - # wrapperLib.downloads.artifact.sha1 = "566dfd60aacffaa02884614835f1151d36f1f985" - # wrapperLib.downloads.artifact.size = 34331 - # libraries.append(wrapperLib) - - wrapperLib = PolyMCLibrary(name=GradleSpecifier("io.github.zekerzhayard:ForgeWrapper:mmc2")) + + wrapperLib = Library(name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2")) wrapperLib.downloads = MojangLibraryDownloads() - wrapperLib.downloads.artifact = MojangArtifact() - wrapperLib.downloads.artifact.url = FORGEWRAPPER_MAVEN % (wrapperLib.name.getPath()) - wrapperLib.downloads.artifact.sha1 = "4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3" - wrapperLib.downloads.artifact.size = 34444 + wrapperLib.downloads.artifact = MojangArtifact(url=FORGEWRAPPER_MAVEN % (wrapperLib.name.path()), + sha1="4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", + size=34444) libraries.append(wrapperLib) for upstreamLib in installerVersion.libraries: - pmcLib = PolyMCLibrary(upstreamLib.to_json()) + pmcLib = Library.parse_obj(upstreamLib.dict()) if pmcLib.name.group == "net.minecraftforge": if pmcLib.name.artifact == "forge": fixedName = pmcLib.name fixedName.classifier = "launcher" - pmcLib.downloads.artifact.path = fixedName.getPath() - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.getPath() + pmcLib.downloads.artifact.path = fixedName.path() + pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.path() pmcLib.name = fixedName libraries.append(pmcLib) continue - if pmcLib.name.isLog4j(): + if pmcLib.name.is_log4j(): continue libraries.append(pmcLib) result.libraries = libraries - result.releaseTime = installerVersion.releaseTime + result.release_time = installerVersion.release_time result.order = 5 mcArgs = "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" for arg in installerVersion.arguments.game: mcArgs += " %s" % arg - result.minecraftArguments = mcArgs + result.minecraft_arguments = mcArgs return result -# load the locally cached version list -with open(UPSTREAM_DIR + "/forge/derived_index.json", 'r', encoding='utf-8') as f: - main_json = json.load(f) - remoteVersionlist = DerivedForgeIndex(main_json) - -recommendedVersions = [] - -tsPath = "static/forge-legacyinfo.json" - -legacyinfolist = None -with open(tsPath, 'r', encoding='utf-8') as tsFile: - legacyinfolist = ForgeLegacyInfoList(json.load(tsFile)) - -legacyVersions = [ - "1.1", - "1.2.3", - "1.2.4", - "1.2.5", - "1.3.2", - "1.4.1", - "1.4.2", - "1.4.3", - "1.4.4", - "1.4.5", - "1.4.6", - "1.4.7", - "1.5", - "1.5.1", - "1.5.2", - "1.6.1", - "1.6.2", - "1.6.3", - "1.6.4", - "1.7.10", - "1.7.10-pre4", - "1.7.2", - "1.8", - "1.8.8", - "1.8.9", - "1.9", - "1.9.4", - "1.10", - "1.10.2", - "1.11", - "1.11.2", - "1.12", - "1.12.1", - "1.12.2", -] - -for id, entry in remoteVersionlist.versions.items(): - if entry.mcversion == None: - eprint("Skipping %s with invalid MC version" % id) - continue - - version = ForgeVersion(entry) - if version.url() == None: - eprint("Skipping %s with no valid files" % id) - continue - eprint("Processing Forge %s" % version.rawVersion) - versionElements = version.rawVersion.split('.') - if len(versionElements) < 1: - eprint("Skipping version %s with not enough version elements" % (id)) - continue - - majorVersionStr = versionElements[0] - if not majorVersionStr.isnumeric(): - eprint("Skipping version %s with non-numeric major version %s" % (id, majorVersionStr)) - continue - - majorVersion = int(majorVersionStr) - # if majorVersion >= 37: - # eprint ("Skipping unsupported major version %d (%s)" % (majorVersion, id)) - # continue - - if entry.recommended: - recommendedVersions.append(version.rawVersion) - - # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile(PMC_DIR + "/net.minecraft/%s.json" % version.mcversion_sane): - eprint("Skipping %s with no corresponding Minecraft version %s" % (id, version.mcversion_sane)) - continue - - outVersion = None - - # Path for new-style build system based installers - installerVersionFilepath = UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.longVersion - profileFilepath = UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.longVersion - - eprint(installerVersionFilepath) - if os.path.isfile(installerVersionFilepath): - with open(installerVersionFilepath, 'r', encoding='utf-8') as installerVersionFile: - installerVersion = MojangVersionFile(json.load(installerVersionFile)) - if entry.mcversion in legacyVersions: - outVersion = versionFromModernizedInstaller(installerVersion, version) +def main(): + # load the locally cached version list + remoteVersionlist = DerivedForgeIndex.parse_file(os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE)) + + recommendedVersions = [] + + legacyinfolist = ForgeLegacyInfoList.parse_file(os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE)) + + legacyVersions = [ + "1.1", + "1.2.3", + "1.2.4", + "1.2.5", + "1.3.2", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "1.4.6", + "1.4.7", + "1.5", + "1.5.1", + "1.5.2", + "1.6.1", + "1.6.2", + "1.6.3", + "1.6.4", + "1.7.10", + "1.7.10-pre4", + "1.7.2", + "1.8", + "1.8.8", + "1.8.9", + "1.9", + "1.9.4", + "1.10", + "1.10.2", + "1.11", + "1.11.2", + "1.12", + "1.12.1", + "1.12.2", + ] + + for id, entry in remoteVersionlist.versions.items(): + if entry.mcversion is None: + eprint("Skipping %s with invalid MC version" % id) + continue + + version = ForgeVersion(entry) + + if version.longVersion in BAD_VERSIONS: + # Version 1.12.2-14.23.5.2851 is ultra cringe, I can't imagine why you would even spend one second on + # actually adding support for this version. + # It is cringe, because it's installer info is broken af + eprint(f"Skipping bad version {version.longVersion}") + continue + + if version.url() is None: + eprint("Skipping %s with no valid files" % id) + continue + eprint("Processing Forge %s" % version.rawVersion) + versionElements = version.rawVersion.split('.') + if len(versionElements) < 1: + eprint("Skipping version %s with not enough version elements" % (id)) + continue + + majorVersionStr = versionElements[0] + if not majorVersionStr.isnumeric(): + eprint("Skipping version %s with non-numeric major version %s" % (id, majorVersionStr)) + continue + + majorVersion = int(majorVersionStr) + # if majorVersion >= 37: + # eprint ("Skipping unsupported major version %d (%s)" % (majorVersion, id)) + # continue + + if entry.recommended: + recommendedVersions.append(version.rawVersion) + + # If we do not have the corresponding Minecraft version, we ignore it + if not os.path.isfile(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version.mcversion_sane}.json")): + eprint("Skipping %s with no corresponding Minecraft version %s" % (id, version.mcversion_sane)) + continue + + outVersion = None + + # Path for new-style build system based installers + installerVersionFilepath = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.longVersion}.json") + profileFilepath = os.path.join(UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.longVersion}.json") + + eprint(installerVersionFilepath) + if os.path.isfile(installerVersionFilepath): + installerVersion = MojangVersion.parse_file(installerVersionFilepath) + if entry.mcversion in legacyVersions: + outVersion = versionFromModernizedInstaller(installerVersion, version) + else: + installerProfile = ForgeInstallerProfileV2.parse_file(profileFilepath) + outVersion = versionFromBuildSystemInstaller(installerVersion, installerProfile, version) else: - with open(profileFilepath, 'r', encoding='utf-8') as profileFile: - installerProfile = ForgeInstallerProfileV2(json.load(profileFile)) - outVersion = versionFromBuildSystemInstaller(installerVersion, installerProfile, version) - else: - if version.usesInstaller(): + if version.uses_installer(): - # If we do not have the Forge json, we ignore this version - if not os.path.isfile(profileFilepath): - eprint("Skipping %s with missing profile json" % id) - continue - with open(profileFilepath, 'r', encoding='utf-8') as profileFile: - profile = ForgeInstallerProfile(json.load(profileFile)) + # If we do not have the Forge json, we ignore this version + if not os.path.isfile(profileFilepath): + eprint("Skipping %s with missing profile json" % id) + continue + profile = ForgeInstallerProfile.parse_file(profileFilepath) outVersion = versionFromProfile(profile, version) - else: - # Generate json for legacy here - if version.mcversion_sane == "1.6.1": - continue - build = version.build - if not str(build).encode('utf-8').decode('utf8') in legacyinfolist.number: - eprint("Legacy build %d is missing in legacy info. Ignoring." % build) - continue + else: + # Generate json for legacy here + if version.mcversion_sane == "1.6.1": + continue + build = version.build + if not str(build).encode('utf-8').decode('utf8') in legacyinfolist.number: + eprint("Legacy build %d is missing in legacy info. Ignoring." % build) + continue + + outVersion = versionFromLegacy(version, legacyinfolist.number[str(build)]) - outVersion = versionFromLegacy(version, legacyinfolist.number[build]) + outFilepath = os.path.join(PMC_DIR, FORGE_COMPONENT, f"{outVersion.version}.json") + outVersion.write(outFilepath) - outFilepath = PMC_DIR + "/net.minecraftforge/%s.json" % outVersion.version - with open(outFilepath, 'w') as outfile: - json.dump(outVersion.to_json(), outfile, sort_keys=True, indent=4) + recommendedVersions.sort() -recommendedVersions.sort() + print('Recommended versions:', recommendedVersions) -print('Recommended versions:', recommendedVersions) + package = MetaPackage(uid=FORGE_COMPONENT, name="Forge", project_url="https://www.minecraftforge.net/forum/") + package.recommended = recommendedVersions + package.write(os.path.join(PMC_DIR, FORGE_COMPONENT, "package.json")) -sharedData = PolyMCSharedPackageData(uid='net.minecraftforge', name="Forge") -sharedData.projectUrl = 'https://www.minecraftforge.net/forum/' -sharedData.recommended = recommendedVersions -sharedData.write() +if __name__ == '__main__': + main() diff --git a/meta/common/forge.py b/meta/common/forge.py new file mode 100644 index 0000000000..d39249cc0c --- /dev/null +++ b/meta/common/forge.py @@ -0,0 +1,17 @@ +from os.path import join + +BASE_DIR = "forge" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "installer_info") +INSTALLER_MANIFEST_DIR = join(BASE_DIR, "installer_manifests") +VERSION_MANIFEST_DIR = join(BASE_DIR, "version_manifests") +FILE_MANIFEST_DIR = join(BASE_DIR, "files_manifests") +DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") + +STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") + +FORGE_COMPONENT = "net.minecraftforge" + +FORGEWRAPPER_MAVEN = "https://polymc.github.io/files/maven/%s" +BAD_VERSIONS = ["1.12.2-14.23.5.2851"] diff --git a/meta/forgeutil.py b/meta/forgeutil.py deleted file mode 100644 index 4c2615cb8d..0000000000 --- a/meta/forgeutil.py +++ /dev/null @@ -1,323 +0,0 @@ -from collections import namedtuple - -from .metautil import * - - -# A post-processed entry constructed from the reconstructed Forge version index -class ForgeVersion: - def __init__(self, entry): - self.build = entry.build - self.rawVersion = entry.version - self.mcversion = entry.mcversion - self.mcversion_sane = self.mcversion.replace("_pre", "-pre", 1) - self.branch = entry.branch - self.installer_filename = None - self.installer_url = None - self.universal_filename = None - self.universal_url = None - self.changelog_url = None - self.longVersion = "%s-%s" % (self.mcversion, self.rawVersion) - if self.branch != None: - self.longVersion = self.longVersion + "-%s" % (self.branch) - for classifier, fileentry in entry.files.items(): - extension = fileentry.extension - checksum = fileentry.hash - filename = fileentry.filename(self.longVersion) - url = fileentry.url(self.longVersion) - if (classifier == "installer") and (extension == "jar"): - self.installer_filename = filename - self.installer_url = url - if (classifier == "universal" or classifier == "client") and (extension == "jar" or extension == "zip"): - self.universal_filename = filename - self.universal_url = url - if (classifier == "changelog") and (extension == "txt"): - self.changelog_url = url - - def name(self): - return "Forge %d" % (self.build) - - def usesInstaller(self): - if self.installer_url == None: - return False - if self.mcversion == "1.5.2": - return False - return True - - def filename(self): - if self.usesInstaller(): - return self.installer_filename - else: - return self.universal_filename - - def url(self): - if self.usesInstaller(): - return self.installer_url - else: - return self.universal_url - - def isSupported(self): - if self.url() == None: - return False - - versionElements = self.rawVersion.split('.') - if len(versionElements) < 1: - return False - - majorVersionStr = versionElements[0] - if not majorVersionStr.isnumeric(): - return False - - # majorVersion = int(majorVersionStr) - # if majorVersion >= 37: - # return False - - return True - - -class ForgeFile(JsonObject): - classifier = StringProperty(required=True) - hash = StringProperty(required=True) - extension = StringProperty(required=True) - - def filename(self, longversion): - return "%s-%s-%s.%s" % ("forge", longversion, self.classifier, self.extension) - - def url(self, longversion): - return "https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s/%s" % ( - longversion, self.filename(longversion)) - - -class ForgeEntry(JsonObject): - longversion = StringProperty(required=True) - mcversion = StringProperty(required=True) - version = StringProperty(required=True) - build = IntegerProperty(required=True) - branch = StringProperty() - latest = BooleanProperty() - recommended = BooleanProperty() - files = DictProperty(ForgeFile) - - -class ForgeMcVersionInfo(JsonObject): - latest = StringProperty() - recommended = StringProperty() - versions = ListProperty(StringProperty()) - - -class DerivedForgeIndex(JsonObject): - versions = DictProperty(ForgeEntry) - by_mcversion = DictProperty(ForgeMcVersionInfo) - - -''' -FML library mappings - these are added to legacy Forge versions because Forge no longer can download these -by itself - the locations have changed and some of this has to be rehosted on PolyMC servers. -''' - -FMLLib = namedtuple('FMLLib', ('filename', 'checksum', 'ours')) - -fmlLibsMapping = {} - -fmlLibsMapping["1.3.2"] = [ - FMLLib("argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", False), - FMLLib("guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", False), - FMLLib("asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", False) -] - -fml14 = [ - FMLLib("argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", False), - FMLLib("guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", False), - FMLLib("asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", False), - FMLLib("bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", False) -] -fmlLibsMapping["1.4"] = fml14; -fmlLibsMapping["1.4.1"] = fml14; -fmlLibsMapping["1.4.2"] = fml14; -fmlLibsMapping["1.4.3"] = fml14; -fmlLibsMapping["1.4.4"] = fml14; -fmlLibsMapping["1.4.5"] = fml14; -fmlLibsMapping["1.4.6"] = fml14; -fmlLibsMapping["1.4.7"] = fml14; - -fmlLibsMapping["1.5"] = [ - FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", False), - FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", False), - FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", False), - FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", True), - FMLLib("deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", False), - FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", True) -] - -fmlLibsMapping["1.5.1"] = [ - FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", False), - FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", False), - FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", False), - FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", True), - FMLLib("deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", False), - FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", True) -] - -fmlLibsMapping["1.5.2"] = [ - FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", False), - FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", False), - FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", False), - FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", True), - FMLLib("deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", False), - FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", True) -] - -''' -"install": { - "profileName": "Forge", - "target":"Forge8.9.0.753", - "path":"net.minecraftforge:minecraftforge:8.9.0.753", - "version":"Forge 8.9.0.753", - "filePath":"minecraftforge-universal-1.6.1-8.9.0.753.jar", - "welcome":"Welcome to the simple Forge installer.", - "minecraft":"1.6.1", - "logo":"/big_logo.png", - "mirrorList": "http://files.minecraftforge.net/mirror-brand.list" -}, -"install": { - "profileName": "forge", - "target":"1.11-forge1.11-13.19.0.2141", - "path":"net.minecraftforge:forge:1.11-13.19.0.2141", - "version":"forge 1.11-13.19.0.2141", - "filePath":"forge-1.11-13.19.0.2141-universal.jar", - "welcome":"Welcome to the simple forge installer.", - "minecraft":"1.11", - "mirrorList" : "http://files.minecraftforge.net/mirror-brand.list", - "logo":"/big_logo.png", - "modList":"none" -}, -''' - - -class ForgeInstallerProfileInstallSection(JsonObject): - profileName = StringProperty(required=True) - target = StringProperty(required=True) - path = GradleSpecifierProperty(required=True) - version = StringProperty(required=True) - filePath = StringProperty(required=True) - welcome = StringProperty(required=True) - minecraft = StringProperty(required=True) - logo = StringProperty(required=True) - mirrorList = StringProperty(required=True) - modList = StringProperty(exclude_if_none=True, default=None) - - -class ForgeLibrary(MojangLibrary): - url = StringProperty(exclude_if_none=True) - serverreq = BooleanProperty(exclude_if_none=True, default=None) - clientreq = BooleanProperty(exclude_if_none=True, default=None) - checksums = ListProperty(StringProperty) - comment = StringProperty() - - -class ForgeVersionFile(MojangVersionFile): - libraries = ListProperty(ForgeLibrary, exclude_if_none=True, default=None) # overrides Mojang libraries - inheritsFrom = StringProperty() - jar = StringProperty() - - -''' -"optionals": [ - { - "name": "Mercurius", - "client": true, - "server": true, - "default": true, - "inject": true, - "desc": "A mod that collects statistics about Minecraft and your system.
Useful for Forge to understand how Minecraft/Forge are used.", - "url": "http://www.minecraftforge.net/forum/index.php?topic=43278.0", - "artifact": "net.minecraftforge:MercuriusUpdater:1.11.2", - "maven": "http://files.minecraftforge.net/maven/" - } -] -''' - - -class ForgeOptional(JsonObject): - name = StringProperty() - client = BooleanProperty() - server = BooleanProperty() - default = BooleanProperty() - inject = BooleanProperty() - desc = StringProperty() - url = StringProperty() - artifact = GradleSpecifierProperty() - maven = StringProperty() - - -class ForgeInstallerProfile(JsonObject): - install = ObjectProperty(ForgeInstallerProfileInstallSection, required=True) - versionInfo = ObjectProperty(ForgeVersionFile, required=True) - optionals = ListProperty(ForgeOptional) - - -class ForgeLegacyInfo(JsonObject): - releaseTime = ISOTimestampProperty() - size = IntegerProperty() - sha256 = StringProperty() - sha1 = StringProperty() - - -class ForgeLegacyInfoList(JsonObject): - number = DictProperty(ForgeLegacyInfo) - - -class DataSpec(JsonObject): - client = StringProperty() - server = StringProperty() - - -class ProcessorSpec(JsonObject): - jar = StringProperty() - classpath = ListProperty(StringProperty) - args = ListProperty(StringProperty) - outputs = DictProperty(StringProperty) - sides = ListProperty(StringProperty, exclude_if_none=True, default=None) - - -# Note: This is only used in one version (1.12.2-14.23.5.2851) and we don't even use the installer profile in it. -# It's here just so it parses and we can continue... -class ForgeInstallerProfileV1_5(JsonObject): - _comment = ListProperty(StringProperty) - spec = IntegerProperty() - profile = StringProperty() - version = StringProperty() - icon = StringProperty() - json = StringProperty() - path = GradleSpecifierProperty() - logo = StringProperty() - minecraft = StringProperty() - welcome = StringProperty() - # We don't know what 'data' actually is in this one. It's an empty array - data = ListProperty(StringProperty) - processors = ListProperty(ProcessorSpec) - libraries = ListProperty(MojangLibrary) - mirrorList = StringProperty(exclude_if_none=True, default=None) - - -class ForgeInstallerProfileV2(JsonObject): - _comment = ListProperty(StringProperty) - spec = IntegerProperty() - profile = StringProperty() - version = StringProperty() - icon = StringProperty() - json = StringProperty() - path = GradleSpecifierProperty() - logo = StringProperty() - minecraft = StringProperty() - welcome = StringProperty() - data = DictProperty(DataSpec) - processors = ListProperty(ProcessorSpec) - libraries = ListProperty(MojangLibrary) - mirrorList = StringProperty(exclude_if_none=True, default=None) - serverJarPath = StringProperty(exclude_if_none=True, default=None) - - -class InstallerInfo(JsonObject): - sha1hash = StringProperty() - sha256hash = StringProperty() - size = IntegerProperty() diff --git a/meta/model/forge.py b/meta/model/forge.py new file mode 100644 index 0000000000..6290cc8dff --- /dev/null +++ b/meta/model/forge.py @@ -0,0 +1,306 @@ +from datetime import datetime +from typing import Optional, List, Dict + +from pydantic import Field + +from . import MetaBase, GradleSpecifier, MojangLibrary +from .mojang import MojangVersion + + +class ForgeFile(MetaBase): + classifier: str + hash: str + extension: str + + def filename(self, longversion): + return "%s-%s-%s.%s" % ("forge", longversion, self.classifier, self.extension) + + def url(self, longversion): + return "https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s/%s" % ( + longversion, self.filename(longversion)) + + +class ForgeEntry(MetaBase): + longversion: str + mcversion: str + version: str + build: int + branch: Optional[str] + latest: Optional[bool] + recommended: Optional[bool] + files: Optional[Dict[str, ForgeFile]] + + +class ForgeMCVersionInfo(MetaBase): + latest: Optional[str] + recommended: Optional[str] + versions: List[str] = Field([]) + + +class DerivedForgeIndex(MetaBase): + versions: Dict[str, ForgeEntry] = Field({}) + by_mcversion: Dict[str, ForgeMCVersionInfo] = Field({}) + + +class FMLLib(MetaBase): # old ugly stuff. Maybe merge this with Library or MojangLibrary later + filename: str + checksum: str + ours: bool + + +class ForgeInstallerProfileInstallSection(MetaBase): + """ + "install": { + "profileName": "Forge", + "target":"Forge8.9.0.753", + "path":"net.minecraftforge:minecraftforge:8.9.0.753", + "version":"Forge 8.9.0.753", + "filePath":"minecraftforge-universal-1.6.1-8.9.0.753.jar", + "welcome":"Welcome to the simple Forge installer.", + "minecraft":"1.6.1", + "logo":"/big_logo.png", + "mirrorList": "http://files.minecraftforge.net/mirror-brand.list" + }, + "install": { + "profileName": "forge", + "target":"1.11-forge1.11-13.19.0.2141", + "path":"net.minecraftforge:forge:1.11-13.19.0.2141", + "version":"forge 1.11-13.19.0.2141", + "filePath":"forge-1.11-13.19.0.2141-universal.jar", + "welcome":"Welcome to the simple forge installer.", + "minecraft":"1.11", + "mirrorList" : "http://files.minecraftforge.net/mirror-brand.list", + "logo":"/big_logo.png", + "modList":"none" + }, + """ + profileName: str + target: str + path: GradleSpecifier + version: str + filePath: str + welcome: str + minecraft: str + logo: str + mirrorList: str + modList: Optional[str] + + +class ForgeLibrary(MojangLibrary): + url: Optional[str] + serverreq: Optional[bool] + clientreq: Optional[bool] + checksums: Optional[List[str]] + comment: Optional[str] + + +class ForgeVersionFile(MojangVersion): + libraries: Optional[List[ForgeLibrary]] # overrides Mojang libraries + inheritsFrom: Optional[str] + jar: Optional[str] + + +class ForgeOptional(MetaBase): + """ + "optionals": [ + { + "name": "Mercurius", + "client": true, + "server": true, + "default": true, + "inject": true, + "desc": "A mod that collects statistics about Minecraft and your system.
Useful for Forge to understand how Minecraft/Forge are used.", + "url": "http://www.minecraftforge.net/forum/index.php?topic=43278.0", + "artifact": "net.minecraftforge:MercuriusUpdater:1.11.2", + "maven": "http://files.minecraftforge.net/maven/" + } + ] + """ + name: Optional[str] + client: Optional[bool] + server: Optional[bool] + default: Optional[bool] + inject: Optional[bool] + desc: Optional[str] + url: Optional[str] + artifact: Optional[GradleSpecifier] + maven: Optional[str] + + +class ForgeInstallerProfile(MetaBase): + install: ForgeInstallerProfileInstallSection + versionInfo: ForgeVersionFile + optionals: Optional[List[ForgeOptional]] + + +class ForgeLegacyInfo(MetaBase): + releaseTime: Optional[datetime] + size: Optional[int] + sha256: Optional[str] + sha1: Optional[str] + + +class ForgeLegacyInfoList(MetaBase): + number: Dict[str, ForgeLegacyInfo] = Field({}) + + +class DataSpec(MetaBase): + client: Optional[str] + server: Optional[str] + + +class ProcessorSpec(MetaBase): + jar: Optional[str] + classpath: Optional[List[str]] + args: Optional[List[str]] + outputs: Optional[Dict[str, str]] + sides: Optional[List[str]] + + +class ForgeInstallerProfileV2(MetaBase): + _comment: Optional[List[str]] + spec: Optional[int] + profile: Optional[str] + version: Optional[str] + icon: Optional[str] + json_data: Optional[str] = Field(alias="json") + path: Optional[GradleSpecifier] + logo: Optional[str] + minecraft: Optional[str] + welcome: Optional[str] + data: Optional[Dict[str, DataSpec]] + processors: Optional[List[ProcessorSpec]] + libraries: Optional[List[MojangLibrary]] + mirrorList: Optional[str] + serverJarPath: Optional[str] + + +class InstallerInfo(MetaBase): + sha1hash: Optional[str] + sha256hash: Optional[str] + size: Optional[int] + + +def fml_libs_for_version(mc_version: str) -> List[FMLLib]: + argo_2_25 = FMLLib(filename="argo-2.25.jar", + checksum="bb672829fde76cb163004752b86b0484bd0a7f4b", + ours=False) + argo_small_3_2 = FMLLib(filename="argo-small-3.2.jar", + checksum="58912ea2858d168c50781f956fa5b59f0f7c6b51", + ours=False) + guava_12_0_1 = FMLLib(filename="guava-12.0.1.jar", + checksum="b8e78b9af7bf45900e14c6f958486b6ca682195f", + ours=False) + guava_14_0_rc3 = FMLLib(filename="guava-14.0-rc3.jar", + checksum="931ae21fa8014c3ce686aaa621eae565fefb1a6a", + ours=False) + asm_all_4_0 = FMLLib(filename="asm-all-4.0.jar", + checksum="98308890597acb64047f7e896638e0d98753ae82", + ours=False) + asm_all_4_1 = FMLLib(filename="asm-all-4.1.jar", + checksum="054986e962b88d8660ae4566475658469595ef58", + ours=False) + bcprov_jdk15on_147 = FMLLib(filename="bcprov-jdk15on-147.jar", + checksum="b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", + ours=False) + bcprov_jdk15on_148 = FMLLib(filename="bcprov-jdk15on-148.jar", + checksum="960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", + ours=True) + scala_library = FMLLib(filename="scala-library.jar", + checksum="458d046151ad179c85429ed7420ffb1eaf6ddf85", + ours=True) + + deobfuscation_data_1_5 = FMLLib(filename="deobfuscation_data_1.5.zip", + checksum="5f7c142d53776f16304c0bbe10542014abad6af8", + ours=False) + + deobfuscation_data_1_5_1 = FMLLib(filename="deobfuscation_data_1.5.1.zip", + checksum="22e221a0d89516c1f721d6cab056a7e37471d0a6", + ours=False) + deobfuscation_data_1_5_2 = FMLLib(filename="deobfuscation_data_1.5.2.zip", + checksum="446e55cd986582c70fcf12cb27bc00114c5adfd9", + ours=False) + if mc_version == "1.3.2": + return [argo_2_25, guava_12_0_1, asm_all_4_0] + elif mc_version in ["1.4", "1.4.1", "1.4.2", "1.4.3", "1.4.4", "1.4.5", "1.4.6", "1.4.7"]: + return [argo_2_25, guava_12_0_1, asm_all_4_0, bcprov_jdk15on_147] + elif mc_version == "1.5": + return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5, + scala_library] + elif mc_version == "1.5.1": + return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_1, + scala_library] + elif mc_version == "1.5.2": + return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_2, + scala_library] + return [] + + +# A post-processed entry constructed from the reconstructed Forge version index +class ForgeVersion: + def __init__(self, entry: ForgeEntry): + self.build = entry.build + self.rawVersion = entry.version + self.mcversion = entry.mcversion + self.mcversion_sane = self.mcversion.replace("_pre", "-pre", 1) + self.branch = entry.branch + self.installer_filename = None + self.installer_url = None + self.universal_filename = None + self.universal_url = None + self.changelog_url = None + self.longVersion = "%s-%s" % (self.mcversion, self.rawVersion) + if self.branch is not None: + self.longVersion = self.longVersion + "-%s" % self.branch + + # this comment's whole purpose is to say this: cringe + for classifier, file in entry.files.items(): + extension = file.extension + filename = file.filename(self.longVersion) + url = file.url(self.longVersion) + if (classifier == "installer") and (extension == "jar"): + self.installer_filename = filename + self.installer_url = url + if (classifier == "universal" or classifier == "client") and (extension == "jar" or extension == "zip"): + self.universal_filename = filename + self.universal_url = url + if (classifier == "changelog") and (extension == "txt"): + self.changelog_url = url + + def name(self): + return "Forge %d" % self.build + + def uses_installer(self): + if self.installer_url is None: + return False + if self.mcversion == "1.5.2": + return False + return True + + def filename(self): + if self.uses_installer(): + return self.installer_filename + return self.universal_filename + + def url(self): + if self.uses_installer(): + return self.installer_url + return self.universal_url + + def is_supported(self): + if self.url() is None: + return False + + foo = self.rawVersion.split('.') + if len(foo) < 1: + return False + + major_version = foo[0] + if not major_version.isnumeric(): + return False + + # majorVersion = int(majorVersionStr) + # if majorVersion >= 37: + # return False + + return True diff --git a/static/forge-legacyinfo.json b/static/forge-legacyinfo.json deleted file mode 100644 index 28e45244f8..0000000000 --- a/static/forge-legacyinfo.json +++ /dev/null @@ -1,3712 +0,0 @@ -{ - "number": { - "1": { - "releaseTime": "2012-02-03T03:43:02", - "sha1": "3b67ffda89f4d8c7625a00aee23c270ffef642c8", - "sha256": "090bc30701b942efcfcbca6ccc22cb16aca74e12f16d47e0c026508d1e115cb3", - "size": 385340 - }, - "10": { - "releaseTime": "2012-02-14T11:17:12", - "sha1": "b08fd9b88a7c4f2773462a501ec2a37e8a71f177", - "sha256": "a93fbce5ebf0046cec068db167ca380b207b6a2092b2487d438bf0b6c14b4509", - "size": 446516 - }, - "100": { - "releaseTime": "2012-04-26T14:52:52", - "sha1": "9107451e325dd60b21fd31db956e2cba7ad78777", - "sha256": "09e6242404f8f1d1bff77fc1a88ebc650a5db5afd61c1bcaf155a7cccbc38dc4", - "size": 535241 - }, - "101": { - "releaseTime": "2012-04-26T19:15:44", - "sha1": "1ec31c6def402042b240b78b29f62d282dda9245", - "sha256": "6ba717cbb338d02bc517026dde1046ee32b99df869ce444f2c524766cf587ac1", - "size": 539903 - }, - "102": { - "releaseTime": "2012-04-29T03:15:02", - "sha1": "7d27b1cf0bba9084ca9dd40836a591a6f549ab99", - "sha256": "b7d54a5bf528e197b84176feca4c6dfc39e7510dd2b934c01bba4d20b3fd5a05", - "size": 539984 - }, - "103": { - "releaseTime": "2012-05-01T17:41:18", - "sha1": "ff0f5ba142f93216e3414a62a35bc0ea63c04e2b", - "sha256": "035dc0c527456593aabf95e5af6a353244deba2c7dd42abc512e87877be09a21", - "size": 539984 - }, - "104": { - "releaseTime": "2012-05-02T10:40:54", - "sha1": "1267987ae92e7b33807f64cb878bd69d0237929e", - "sha256": "cfc17f996343fa607af6913804e7aee3a88ec75b70c5e95d5189b96fbadf9312", - "size": 540020 - }, - "105": { - "releaseTime": "2012-05-02T11:15:28", - "sha1": "3107da18680cc7a4c8da48a87987c6b54c1cdbd3", - "sha256": "fe79e721c75454eec6b9c4fea77f07ca5ed9ed6a5f89d7339f13bf665e9fe044", - "size": 540020 - }, - "106": { - "releaseTime": "2012-05-05T21:26:20", - "sha1": "073fe35f1465b042cc1a404ee162a78be07a3118", - "sha256": "699943f76f8eba5bece28bad466c2510513432b5916831d8eb873ba9e55f8f07", - "size": 540033 - }, - "107": { - "releaseTime": "2012-05-05T21:48:02", - "sha1": "5a94773af77831db154836b33c31b0572f906e2f", - "sha256": "450496d301b3a5929c833561ef860aa845fe42a48b7ba40628134cffd6324480", - "size": 540049 - }, - "108": { - "releaseTime": "2012-05-26T20:33:00", - "sha1": "91a5cb7e60c573c6f5700afc9a61dc987c90837e", - "sha256": "88b9d9050a889839ff260accfc1f2cb70320891b88f74f23ef7630000755e59c", - "size": 540051 - }, - "110": { - "releaseTime": "2012-05-27T05:14:54", - "sha1": "f14ac41dc2c3dfcbb31ca9625b0ddde5ee50e60c", - "sha256": "b421c75a9635633c2406779d94ac185fd907cba9e398d7f40d1397e9493111b1", - "size": 682378 - }, - "111": { - "releaseTime": "2012-05-27T05:52:26", - "sha1": "37ea7bd0a7a4643e405d1930306e0ae48eb6fa72", - "sha256": "844cf9d1a842f680c40aa64b442e08575ff14c776732bfef02fb836d7150336c", - "size": 692653 - }, - "114": { - "releaseTime": "2012-05-27T07:49:00", - "sha1": "6656816ca2a9b8ee781b21ffe397351c1cff242b", - "sha256": "7b4d0d01792533479630ec61caa056821d5faf49a94976de6809b5bc5ea6407d", - "size": 692890 - }, - "115": { - "releaseTime": "2012-06-02T17:05:10", - "sha1": "fa56c8a9ba515b4ebafa29a9d8b463844d8cefbf", - "sha256": "28376c420dc439a2972aee59fbf5369e4662abb9f4255f215efbc07aa43103f5", - "size": 699345 - }, - "116": { - "releaseTime": "2012-06-02T19:29:02", - "sha1": "a0bc1631878d6c82e90cc8c8428d531e616d0b4d", - "sha256": "3689d1c1d54d408872909b6864b91c16822f13b6c000aa6d4b7c50fc0ee103a5", - "size": 771433 - }, - "117": { - "releaseTime": "2012-06-03T00:39:56", - "sha1": "fad26f06303d49516f30bd9787c60254b9d64832", - "sha256": "0f6ab352cbdde133519af2446cb1e95596ee83bd7862d0396ce176fe6f58a289", - "size": 793622 - }, - "118": { - "releaseTime": "2012-06-03T01:06:46", - "sha1": "2417311461424c258b1ae75b3c2aca5ed8a93212", - "sha256": "750ce4702906336213c8cebf38f51f42ab32a5097b54850b8a9c2da6cba4f165", - "size": 795988 - }, - "119": { - "releaseTime": "2012-06-03T11:46:04", - "sha1": "9a729ba30e68d06dc1299bf7e2c11f0df2014076", - "sha256": "9eee8d3488c055f54741c865dba925ed0f20fc0fbc93beee930137dff6524099", - "size": 795981 - }, - "12": { - "releaseTime": "2012-02-15T07:01:32", - "sha1": "7a5585b8d63e14d27550a0caa326da98842ba75b", - "sha256": "bff27ad5c4370e4f1b83766f57f193cd69e9ee4918fec123230144f36fd0779d", - "size": 446491 - }, - "120": { - "releaseTime": "2012-06-05T00:26:38", - "sha1": "e46ce772d92952ed79f4dfc4ab3a401855f9ac45", - "sha256": "ac7b487bc153a2d0de283e644e5c573c4937d5c2ee436751d2e5d3f99a91bbbc", - "size": 795970 - }, - "121": { - "releaseTime": "2012-06-06T02:03:28", - "sha1": "4106e1a59253e2cc4ba3c553e1bcfd9363838215", - "sha256": "bdcc1bfa0bf290592de5da011b998b30b88b911a4e1d00ff4a2bd882eb1e1b96", - "size": 796825 - }, - "122": { - "releaseTime": "2012-06-06T07:11:36", - "sha1": "5e9dc2ee5aae4b6dbebc2d03200f0a2e36dfc6ef", - "sha256": "002c98545240753ae60a8e9f0d6067056332b02ab313e5da11749e2c68ab82c1", - "size": 796287 - }, - "123": { - "releaseTime": "2012-06-06T08:16:50", - "sha1": "b8e119c79d6c45a1f8b9816f916426b5015b2a03", - "sha256": "b7ebbaf7f9f6d8070746cac75659bfa55fe7007ec5f8297d7ea7ab4578a48dea", - "size": 796331 - }, - "124": { - "releaseTime": "2012-06-06T09:12:32", - "sha1": "cd06a21016af921260658e2bb72bac0278bd19f1", - "sha256": "3510025daeab7f07afe9f8c454d201c21a0256c00ce5944472291bd6986403b1", - "size": 796364 - }, - "125": { - "releaseTime": "2012-06-06T10:39:50", - "sha1": "730910dbf2756723b0bda64b23d1b86e6e2e360c", - "sha256": "00488c996a010a6544b0c9567cbf52576a09ca960a5071f0d0c96ed3610a3fa1", - "size": 796361 - }, - "126": { - "releaseTime": "2012-06-09T18:07:04", - "sha1": "f936f629b58aa9a26423e7d31fac1016df2ed43e", - "sha256": "c43a7b4dfd7fdf9ce1de709568323933d195ce5d091076183023221ea7868e9e", - "size": 798733 - }, - "127": { - "releaseTime": "2012-06-09T23:23:20", - "sha1": "277b3a9e14efb646541225de6fdb4ac22439a6c0", - "sha256": "8e6bda4d4c0b323729a158f11c8b384429eeb37c5edc770ded4d54c35a8e9345", - "size": 805738 - }, - "128": { - "releaseTime": "2012-06-10T01:57:00", - "sha1": "cf44068b9c694278dc56bf3e912bfb42915a0910", - "sha256": "cfa22e39605b31af73f9dcce17d26c575a5e11d878afaf27dc50b6237f5c05c4", - "size": 805907 - }, - "129": { - "releaseTime": "2012-06-11T14:16:08", - "sha1": "25c1928a77454207548479ed3365b9ac5b6cb724", - "sha256": "a346c164275e470e84e02547c5b78c1ecb9e7a5c273340f7f5722f3639a6cac7", - "size": 806759 - }, - "13": { - "releaseTime": "2012-02-16T20:12:54", - "sha1": "7d833787cd732c36183e83078d5059abf9d2d86f", - "sha256": "c2f2f379cc9eb550eb3db1eb36ecaf2f99fefa0ae34a6db3e565beedfddf7f79", - "size": 446490 - }, - "130": { - "releaseTime": "2012-06-11T14:45:56", - "sha1": "646de970a77cecb90cb4e95a0f20dcd6836ea427", - "sha256": "21e8559b168e199d00a8d107c89ed683b7e430690c2682abc0d510e850084b23", - "size": 806775 - }, - "131": { - "releaseTime": "2012-06-11T15:50:10", - "sha1": "e52706d1ffa3958da1d1ca7dbb4c98c6a91c00c2", - "sha256": "2a90471ccb7636fb65fe3604490c24e1dcb412236883a5d691586146636029c8", - "size": 806773 - }, - "132": { - "releaseTime": "2012-06-12T15:51:22", - "sha1": "c74ac5310eb0459799bc5916564b595f9c8a0558", - "sha256": "1610df104d38406d0f241918a893210503202d1a28f6510029ba612efa5abb1f", - "size": 806787 - }, - "133": { - "releaseTime": "2012-06-13T21:54:32", - "sha1": "9a765110a452eb1c729cd9d1dd72b75ac46a9cc5", - "sha256": "855ecc4c169efca986dea547ba94aeb52d6c8ca696aa94ef727351f92350ea23", - "size": 807737 - }, - "134": { - "releaseTime": "2012-06-13T22:13:02", - "sha1": "3859eb4e96ad8b596648c654603be8c7a2880aed", - "sha256": "237814d9e0f086c066659578fe42ff7cada5dd93b9a2fb9076551d5cac7ae22d", - "size": 807730 - }, - "135": { - "releaseTime": "2012-06-13T23:11:14", - "sha1": "7ca221567a9b8be19ed242cf3027ef85cb5831b5", - "sha256": "ca358444aca70dd229688f4f9aa5c69f6f54362f232f1ff745a15055137e6a72", - "size": 807734 - }, - "136": { - "releaseTime": "2012-06-15T21:13:22", - "sha1": "351d8168796136b453ff07ca3498d079005eecf2", - "sha256": "123c1e3e77f6709bf1074ff8186793ab1574ebb8c137d829a44757b46e1e593e", - "size": 820929 - }, - "137": { - "releaseTime": "2012-06-16T01:31:16", - "sha1": "43b5cedd31124e38d9ac45278f49c3c1b760bc91", - "sha256": "17380821b55e688afe499cd58e1ffa8d08ad1c5a6d0d709a0323a1ee8d615be7", - "size": 820938 - }, - "138": { - "releaseTime": "2012-06-16T13:29:30", - "sha1": "bb06fb63150c309298b5d13fd1386f815a8cb58c", - "sha256": "e7f981301aa518465c22530b8987ca64fc8ef732037ef1e868c7a30effee8303", - "size": 820935 - }, - "139": { - "releaseTime": "2012-06-18T20:20:22", - "sha1": "fa14db691e5caecf901bc03db26f62a41398f0bf", - "sha256": "3745c6f8ec04beb978d3ffefab8093233160fa16c44a14c77ec3ce23b4f864f4", - "size": 824101 - }, - "14": { - "releaseTime": "2012-02-18T10:59:08", - "sha1": "a2e9d478829c8eeef907a2e9fb026b7f7b06d503", - "sha256": "4d8639e623029834b8facb5e773a099ec9b5137e9b5c66acf8d38f9cf08213b1", - "size": 446490 - }, - "140": { - "releaseTime": "2012-06-19T13:54:46", - "sha1": "0393025b622c1963789de2de8cae76bb80a9a40c", - "sha256": "4aa5efe6548af749acdf3805fc6dbbcd78c1dd12f19bbff89e2bab84662242fa", - "size": 824100 - }, - "141": { - "releaseTime": "2012-06-19T14:33:18", - "sha1": "172f03f6df59bc600a325e2eed9252f1466218ca", - "sha256": "3b256df597d86d8650e808846d363e667dce2f467db84576397944fbc4d83522", - "size": 824099 - }, - "142": { - "releaseTime": "2012-06-19T20:50:12", - "sha1": "9bb6c62055657637755ebdfb2c01f1d5be4eb86f", - "sha256": "43661e039a129d00f44ccef4a383c134ba5bb8f66e22252576fd5ae8e91b349b", - "size": 742043 - }, - "143": { - "releaseTime": "2012-06-19T21:35:44", - "sha1": "55aae8a09af8275044e83731e160490e3f96e4f0", - "sha256": "16a65c0fc67a7b52df3bc09924ab9bd860f716d5134e3ec843779d2e2c833441", - "size": 742047 - }, - "144": { - "releaseTime": "2012-06-20T02:27:20", - "sha1": "7af758710c159b940e1a1acce61752b769b9c8c0", - "sha256": "e49b93b985344c3eb5fc0fdd84a3a410c271c713188a969585b2c30f8b1632b2", - "size": 828804 - }, - "145": { - "releaseTime": "2012-06-21T04:10:00", - "sha1": "4574a57cd18f729f3783569dda3414af955a5a7c", - "sha256": "ee338a711e8fdd938813ef85aac9018e510dcfda142e01af2c4d48f66de266f2", - "size": 833053 - }, - "146": { - "releaseTime": "2012-06-21T05:12:52", - "sha1": "a9434adf87ddbaaa0ee766a681796ec2c6baaa3c", - "sha256": "922fb4f5ea0d6c143a2fd7d0ec5b0e816239ada14330553d874bb82832608497", - "size": 833072 - }, - "147": { - "releaseTime": "2012-06-21T06:14:56", - "sha1": "e34ab34210f9ba2ef911a9d8261bee46e58d1181", - "sha256": "cd90d2fb96fafaebbd8832b82996718b2ce6687867c98b9b8b10131e5da0e6e1", - "size": 833263 - }, - "148": { - "releaseTime": "2012-06-21T15:33:06", - "sha1": "269b4dcf1895eb1c861a45596fbdf03a7d952b03", - "sha256": "e8553aebad4aba8f4a3501b7c66ca9ba9e1a72bcce1653943da2b5fdc02be2d1", - "size": 833383 - }, - "15": { - "releaseTime": "2012-02-21T00:08:16", - "sha1": "0c288624b936ae51e74849185db9456b0f6eaecf", - "sha256": "839d7cd8f71501ee7bd2f8bcbd05f9be15f1d28223ea92a7715e59e38f30ef37", - "size": 461232 - }, - "150": { - "releaseTime": "2012-06-22T17:50:02", - "sha1": "69992524b6dad50b7a1f134084d6723941600178", - "sha256": "b377f8001a182855709ef08f002d6426d3d1704b04a3abce7162f688628411bc", - "size": 834008 - }, - "151": { - "releaseTime": "2012-06-22T18:53:06", - "sha1": "390e254050b5d437c52fd3372a9bf5e7af82d190", - "sha256": "8ebc2bf8dd8afd0d17607df892276827cee6accfefe02ddbcdcc0d1fa622cc37", - "size": 834136 - }, - "152": { - "releaseTime": "2012-06-24T14:51:06", - "sha1": "3457f99c4572e65c0c453825131cafce62a403a3", - "sha256": "606e7e860725a3beac211c8814377be05fce2f0d4d31e6591a08a56124883e68", - "size": 834135 - }, - "153": { - "releaseTime": "2012-06-26T12:14:12", - "sha1": "a02b59b5eba868c9ef653e6372dabacff0d7c185", - "sha256": "f71fa6baf922ed05cf02d47dd55eed16e9d351b7aa9cd75be92623d278c2c6e2", - "size": 835486 - }, - "154": { - "releaseTime": "2012-06-27T14:38:54", - "sha1": "1aab062c85fea0f607b34a9aae213de23d557219", - "sha256": "aa20ffa2bc0395657185a58c32e51d23c6485fe9a11e49a6488d5db7c52474a6", - "size": 836032 - }, - "155": { - "releaseTime": "2012-06-27T17:24:36", - "sha1": "072165b010760b236cd60d9270e0ca691a0a1eb4", - "sha256": "e77a492dfd41732cd31ed066419247a12bbdad81a5035f082cbe559c3ee3904e", - "size": 835994 - }, - "156": { - "releaseTime": "2012-06-28T12:47:50", - "sha1": "e65ddb0a00327cc3042977dfb4b3cf7d2c3f9141", - "sha256": "69cffff633cf417d15def003152b1219deeac932905331e1e355a579de8d6610", - "size": 835993 - }, - "157": { - "releaseTime": "2012-06-29T14:06:30", - "sha1": "875565aa589b1c56332f3732f1830b5ada72f353", - "sha256": "b93a825687291259d9ecee57f861a92f876b85c974ef596498b25f27e2f82209", - "size": 835994 - }, - "158": { - "releaseTime": "2012-07-01T06:58:20", - "sha1": "a6d07ec81f663969efdefdb0da0a01c3bd7e61a1", - "sha256": "af68569fcabc2f46331e296e7ce6f4a38d664245dee702827c6f301f00f767b9", - "size": 835995 - }, - "159": { - "releaseTime": "2012-07-02T20:30:34", - "sha1": "1902fd2cee020fb0cc37323df70123c9f1ef521f", - "sha256": "8e95e919e287c486745da1abb4f4f514790dfa4e03a7cd667ff6dcad3b7ea950", - "size": 835994 - }, - "16": { - "releaseTime": "2012-02-21T01:08:40", - "sha1": "e122dd4424507cb886cfaf17d74d32f0b5c27976", - "sha256": "73913abfd6fc33e5fda8d42ed3877e1d6c7ebf693add23727450411ac48aeee8", - "size": 461230 - }, - "160": { - "releaseTime": "2012-07-03T22:13:38", - "sha1": "ffce964d80f804b44f41f9445720cca889df82e3", - "sha256": "428e96518a844bab63f7b7baaddd47fc83596a161827d0776ab95a3cf5e87c97", - "size": 840432 - }, - "161": { - "releaseTime": "2012-07-09T13:47:08", - "sha1": "9b577c7c90c075345c9edbbbf1e9e1b04d526a5e", - "sha256": "159f2f456214b343e12aebfd5f4c6a2aa25534f2de04ef1518c058d736a6dbcf", - "size": 840533 - }, - "162": { - "releaseTime": "2012-07-09T16:06:48", - "sha1": "0c2899851e84610ff9f68178d8982feb2994e30e", - "sha256": "addc741a97b22b20521f1155437215b04318e6a66bd5a65c8c132283b66efd1b", - "size": 841554 - }, - "163": { - "releaseTime": "2012-07-09T21:41:18", - "sha1": "75d6ec38c6ab0667583a5a7253004c739b8e628d", - "sha256": "1a5acd0213bd0e915b83b995ecdd99c0de9d1ecb1c1e732eb044fb79363a1059", - "size": 841544 - }, - "164": { - "releaseTime": "2012-07-10T17:05:40", - "sha1": "93be0a3149c333402a7696a23a45f4ffdb901ae4", - "sha256": "00e8168f96459964e97a37bcfe6c6f83f46d0825f00fbf96b8fec6d2439292eb", - "size": 841547 - }, - "168": { - "releaseTime": "2012-08-01T02:52:16", - "sha1": "1297549223eb2fcf39228b2ef9f572d8fb843dbe", - "sha256": "fed79cb7f26711043db245577f0b826b948cc2184219380b37277782604049f9", - "size": 841565 - }, - "170": { - "releaseTime": "2012-08-01T03:06:10", - "sha1": "b5076149dc1890bdf7df986d77b2a9f78b3873db", - "sha256": "ee62fb09ceebd3a73642a6ba9218f2323fb6f450246355d3a7dfd74b62e0d0b8", - "size": 841564 - }, - "171": { - "releaseTime": "2012-08-03T16:59:00", - "sha1": "65fe624282d24b03e2a35212f9ab6c5e3e10a5e0", - "sha256": "dd6f66865bf04b89fd80a5041c6f9e81e0caefd266097447c73d7e924f67875a", - "size": 841570 - }, - "172": { - "releaseTime": "2012-08-11T02:06:04", - "sha1": "c965a2b9ec9b32ca0570248c99bc1536cf264be9", - "sha256": "16b6cc8b3479318b8a4f438536622852fd553c191fe4a327f0db5d6568c1d48d", - "size": 1056844 - }, - "173": { - "releaseTime": "2012-08-11T04:15:12", - "sha1": "27de803e547a20deb519d1f4a46bda7b639ac0d3", - "sha256": "0e66efa38a4da2e2455701a6107116269c3c5a8110609c05ca54b95035480a52", - "size": 1062629 - }, - "176": { - "releaseTime": "2012-08-11T16:25:50", - "sha1": "c7dc3e0b343c0be64fe7158b05d48ded492c1c90", - "sha256": "dab06042d5fa6737c106d573c3f7ae7392674c1b955d9bf65964fa362692ddb7", - "size": 1068704 - }, - "177": { - "releaseTime": "2012-08-11T17:20:10", - "sha1": "32cfe2f9b93ee0d4cd02089f573a12dcbeb37fa4", - "sha256": "627cd1d8fcf661457cb55f96b83221051159d0ecd7423baacb7432c1893ba7f2", - "size": 1068703 - }, - "178": { - "releaseTime": "2012-08-12T06:19:28", - "sha1": "eb19f25f008fd60e23db74eb5fbae1fbcca48dbf", - "sha256": "bc4b85d4d1f1a828dbce1ad9a46e0dc4a258f32ae463007328802a4d9f959c7a", - "size": 1071601 - }, - "179": { - "releaseTime": "2012-08-12T15:37:14", - "sha1": "aee8717d6781530b2e311b89a0a71fcca58b71fb", - "sha256": "6ee6271971e179158f232104c7a6c804661d71b09633a58229bfa6e4ac733da2", - "size": 1071601 - }, - "18": { - "releaseTime": "2012-02-21T17:14:26", - "sha1": "e348ff6d988c61d98b8a560d7cddc965e2d81482", - "sha256": "a639c9d4f68aefc3c6fe8ed32081e41c67fb6a489a87bcf6a42030c24a1bd136", - "size": 461226 - }, - "180": { - "releaseTime": "2012-08-12T21:46:22", - "sha1": "10dcdc2ea96ba2b86836e67f5569f0f1b895cb9a", - "sha256": "2a48a0d307111333f0030f1799f7e6a79c0efdb30b214060b3bf290d26e77f4b", - "size": 1072919 - }, - "181": { - "releaseTime": "2012-08-12T23:01:26", - "sha1": "f42f43f5562789b2da8eda6598b3d5cfd63720af", - "sha256": "f930595914b8ec50f5e8d9a6bd2842455017fa0802e0a7e09a03a1464b4fefe6", - "size": 1073492 - }, - "182": { - "releaseTime": "2012-08-13T14:20:16", - "sha1": "649fb921f3209dee50991bb8785b245d33e878a7", - "sha256": "f488e3d262d9445b853c8560035d303b03099fe562c0401313e403a913eb628a", - "size": 1073493 - }, - "183": { - "releaseTime": "2012-08-13T23:33:08", - "sha1": "6b278b91c68e8b013ae58c5796c4e2cb9cec7c37", - "sha256": "abccf353a3626161ccb6efd34c93fa1bb3d388ef28662524fbe2841f531b7ff4", - "size": 1106697 - }, - "184": { - "releaseTime": "2012-08-14T00:09:52", - "sha1": "6ce09190d2660c7ca25f60bba02a3ea70072cc60", - "sha256": "d1786b21227630227fa0db5dcc451b690e8e4522dc8f5b108d30dd13728bfd77", - "size": 1106701 - }, - "185": { - "releaseTime": "2012-08-14T04:44:38", - "sha1": "5e2cba3e9e81c1ab11b10c2c47b5b010a06e921d", - "sha256": "324d235979e59bfcaf1a2573b921231357d00940c83c1346b926fbde9e90c19c", - "size": 1106693 - }, - "186": { - "releaseTime": "2012-08-14T06:41:56", - "sha1": "89b4118b59459c9643b3de32373303d04a27e5df", - "sha256": "e0f4a04188d3950e3de4131a394b354d551b657d1fadfd0297b16d708a8156e2", - "size": 1106707 - }, - "187": { - "releaseTime": "2012-08-14T16:07:58", - "sha1": "a9afc5ba72b8224a91cdedc4f10f47ae5eecbe3e", - "sha256": "cc52a1c5cdf0539e86fb83535e30ac21d14d2bd2083c3667edd177101cbec94e", - "size": 1106910 - }, - "188": { - "releaseTime": "2012-08-15T01:04:26", - "sha1": "a8526b0b84ba5d853cacdb25a568a926e90f5674", - "sha256": "6f378334e5aff66e48d727e640db7c49067c932cccac018b333a8061870b1409", - "size": 1108814 - }, - "189": { - "releaseTime": "2012-08-15T02:00:36", - "sha1": "4ee137f2a60010981a021cd39705b773a86a342c", - "sha256": "999c0cda3d1f98cf1cb1ac3eea80ef2029d44d0ab7f200971453415c26383a6f", - "size": 1108815 - }, - "19": { - "releaseTime": "2012-02-22T12:45:24", - "sha1": "a543b0d8607847ab739ad0b4bc109d8b5eb9e36d", - "sha256": "9863223a74fb8b09a6de07818708c52113b951852b8354de2139fe24689a900e", - "size": 457000 - }, - "190": { - "releaseTime": "2012-08-15T03:59:52", - "sha1": "7c8e296dd20d0a099d4ffc0ed6aa2f528844c098", - "sha256": "32b390a19cafc75c66292c547fde2349326a93e0df4db261a26ce34745a77c00", - "size": 1114702 - }, - "191": { - "releaseTime": "2012-08-15T04:20:00", - "sha1": "35c3abea886ffc85f00234638953b24c52feabc8", - "sha256": "9c93b994cf3627833efc96d0b659aa11e4d65389f5cb03966a3c564a336799e0", - "size": 1114733 - }, - "192": { - "releaseTime": "2012-08-15T05:32:22", - "sha1": "3bfce4ff38d083e21ac7565435e11de73a1355b3", - "sha256": "6ee2d016c435d16d5025f50cf2fb37a6ef849627f8cf88d9df498a2591ffd15b", - "size": 1114783 - }, - "193": { - "releaseTime": "2012-08-15T05:41:58", - "sha1": "6f9560278fbf8ba6448aae4e9e314bfdd95f66d0", - "sha256": "437689a1bdd935a29ba5dcbc9883e1c0c014a8686fa40672115a4699dd3c7c3c", - "size": 1114790 - }, - "194": { - "releaseTime": "2012-08-15T17:07:10", - "sha1": "15506c8f8035238775e48c7f2b1c9604a7237567", - "sha256": "30cbe1c1aa0ae1c694765f044801cd9e041078f4e47938c26a8d4e4f5d174e68", - "size": 1116652 - }, - "195": { - "releaseTime": "2012-08-16T04:18:30", - "sha1": "8591aea55c6452626abdfef9a710f2912b071496", - "sha256": "078ddbbad79ea0a9c8fd4d83560a24b27fd14dbc0253b15811c6db3954517d21", - "size": 1117510 - }, - "196": { - "releaseTime": "2012-08-16T04:26:12", - "sha1": "4dc7d314e1d7e815745298d9849f16326d98a4cc", - "sha256": "82a2747bea9aa044ddd384e40229f4380e66544a27c77ff8611f0796571db3d2", - "size": 1117510 - }, - "197": { - "releaseTime": "2012-08-16T04:39:20", - "sha1": "06d558e96e443cd20f28890f60bd846b24a89345", - "sha256": "3bf063bffccc8203c8bb9b16410e38b73d7d061516fabe0d55d8ebec9b3d8341", - "size": 1117510 - }, - "198": { - "releaseTime": "2012-08-16T04:45:46", - "sha1": "ad7c3988568eba9b0a6fb28008fcc2ae7d492baf", - "sha256": "9a06b85b20fe04ce9dee8ddcdcb2984631f97dc277158cdd7dc00a7399d8fdf2", - "size": 1117510 - }, - "199": { - "releaseTime": "2012-08-16T06:51:58", - "sha1": "a43116a04d2653b21cf1482ab3127f5f2e1350df", - "sha256": "cd3f5e0c8052b1323f02f6fe95caecc0001faa1e4b7197e47d7938870c23697a", - "size": 1117518 - }, - "2": { - "releaseTime": "2012-02-07T03:25:24", - "sha1": "17729ac3f56a9c6b19884b0b9f6176c01b6577c9", - "sha256": "ac32701e81a26d81bde327648a11238bb252852fe47ebf5f1f1ba7d2e89732bd", - "size": 410393 - }, - "20": { - "releaseTime": "2012-02-22T16:59:28", - "sha1": "825fce2c50b8982ff8dc55c1726f809b355dbac0", - "sha256": "8435098217c1525f78fd0d496e7297925a3f19a0e3a5b1cdcac228ac4287f3c7", - "size": 460010 - }, - "200": { - "releaseTime": "2012-08-16T14:50:56", - "sha1": "13cd134bd2c71e8559485cf1f3ffb1bd6fe8db36", - "sha256": "7623739f26a54d6921459194e09019e5f0a1697aa84f6a73360dfd81f89aa179", - "size": 1118509 - }, - "204": { - "releaseTime": "2012-08-17T08:15:06", - "sha1": "44a706ddf785343411c042e1117b2514e6bb81a0", - "sha256": "02be25f1ffdcef9d1df61f4a5b7c72a2801c485b092f218be0fe534bd5f34df6", - "size": 1118645 - }, - "205": { - "releaseTime": "2012-08-17T14:36:38", - "sha1": "2dcd664c9f3d49e775139059def2fd34f473b500", - "sha256": "cc7341808da6852fe8f911faae63eb3fc15f29a0041be3054d719cdf0fd94c49", - "size": 1121958 - }, - "206": { - "releaseTime": "2012-08-17T15:11:38", - "sha1": "9dd3cd02e41d6ebdd4f4e6a27b8c623f1669f15a", - "sha256": "ac6522e7e98fbd1b3434d8cf017b6c99b410d2d9e9cebcaa21eccd22f41014c1", - "size": 1122529 - }, - "207": { - "releaseTime": "2012-08-18T00:54:36", - "sha1": "cabf2158a95d36514ac42877df9b324ff82cc692", - "sha256": "54554e8040ac82a63177c3c3f06b037076a1c4a74acf9dae8fbe143d5ab36726", - "size": 1122552 - }, - "208": { - "releaseTime": "2012-08-18T03:20:28", - "sha1": "6bc793175417d57ee6d8fe2953e80b622e51e30a", - "sha256": "0d4c2c845f26f03d05465ecc9d4dfe89e645d7915ae09d380724b8aefd4ad73e", - "size": 1127644 - }, - "209": { - "releaseTime": "2012-08-18T18:31:40", - "sha1": "1e2a7d448a81df1b87b92df5d7654c3b773ce3cb", - "sha256": "0a60f96c58726818a01b3e12d34ee2e64eaa52ab891be28b27319bffa3b25f24", - "size": 1128219 - }, - "21": { - "releaseTime": "2012-02-24T02:44:08", - "sha1": "a26524032331f99cc199c949845d9c21f7ca6220", - "sha256": "a763eaed63cc63795e147ed7fc0e718d50ae884daa0fe6344e2eadae04532716", - "size": 461387 - }, - "210": { - "releaseTime": "2012-08-18T19:06:16", - "sha1": "fb8a39877182075057ab635988a716779ce3c1df", - "sha256": "6e960c40d5ae23921b57dbfde8c90b3b3837219baf046aa110e35041f0922d0b", - "size": 1128955 - }, - "211": { - "releaseTime": "2012-08-18T22:11:36", - "sha1": "8bac076be4e2b1ca18bbc4a5a6dbf428ffe8a000", - "sha256": "de42413d21d609322a5601d5d461f9814bbf04142035a38035af614eede96bcb", - "size": 1128948 - }, - "212": { - "releaseTime": "2012-08-19T00:24:18", - "sha1": "660b131b8c7b5847928325495107d2bf18fc6252", - "sha256": "f4cc8b5a713a14e5712f5e981e9cdcebe1aa79b2f83719a67851d088a19dd176", - "size": 1131604 - }, - "213": { - "releaseTime": "2012-08-19T09:40:06", - "sha1": "a343280c7a069b665ad4892f1fc3efc0204ba273", - "sha256": "3068b0a7e105b7a3bcc40b04836735295c4932bf4e3f41671b00876523111fc6", - "size": 1144787 - }, - "214": { - "releaseTime": "2012-08-19T18:45:34", - "sha1": "9c7461c292717660c860c9dde3a998f80c9db3f9", - "sha256": "df7e911eca3b02cdb53f20bc25e91ff64df2b74e6485703a00834c4ac87949c8", - "size": 1144823 - }, - "215": { - "releaseTime": "2012-08-19T19:03:28", - "sha1": "772542b3aa274c40494aec474a9801e86e832bf3", - "sha256": "4ce688bcebd13c5b3ab37ed9a4ff3f8a8c315f2ddf3495e226e3f1edb9e757f7", - "size": 1144429 - }, - "216": { - "releaseTime": "2012-08-19T21:48:20", - "sha1": "34b05962c8aa58a60420d3276598a3e236ff5faf", - "sha256": "b01354ffa8e7b6f09ba4b8d6b37e2ede984e8bea64af23dbf44ab0905083e710", - "size": 1144496 - }, - "217": { - "releaseTime": "2012-08-19T22:10:42", - "sha1": "1abb0fac2833326264ca74c84b781e7044d52c26", - "sha256": "98ab579eb3ff4253770b676106619a542b27ddc526111bc956dc48d0bcff2339", - "size": 1144596 - }, - "22": { - "releaseTime": "2012-02-24T10:53:16", - "sha1": "f4f11608f49cbfeb025afbb938081540415fc9fd", - "sha256": "078689fbc3fac7d8f5496a1d8a22176d7637e9df7bd11a330727cd7879fff304", - "size": 461389 - }, - "220": { - "releaseTime": "2012-08-22T11:11:14", - "sha1": "0909743af1123f6fe96e01bbf67e4117dd2bb6a4", - "sha256": "d15f10ef045f95d18b7d3dbdcda06cc92148ddae9b21f5e949fa5666bc7ab7f9", - "size": 1156840 - }, - "221": { - "releaseTime": "2012-08-22T14:47:48", - "sha1": "17d16a72551dafcdb66cd8a2c2f1fd7ce5d9b202", - "sha256": "d84a778ddcfd327d3bb91ea80ad8b06c155659380d840e70dc2e4a4ad145c489", - "size": 1156896 - }, - "222": { - "releaseTime": "2012-08-22T14:51:48", - "sha1": "9134a4885e0dbd08d7a9c1b12f5900d1f3f5f7fd", - "sha256": "5b293663cfd379dee0941000331095230b77268bd0a930aee2ea91afacd309cd", - "size": 1156900 - }, - "223": { - "releaseTime": "2012-08-22T16:18:02", - "sha1": "dd89de55a4a0eadddd93a16a67eeab8d2c8e9d00", - "sha256": "8c838d0962c35b7b21dba8ba153241b7dabd30b6202a428f8763eb9951b3e991", - "size": 1160119 - }, - "224": { - "releaseTime": "2012-08-22T19:08:34", - "sha1": "7cbef6b2618c7b05af1327a0dc9d83205ddb47f2", - "sha256": "62348b5f57a64a386387f229f7ff43fc5ba28f3e3fdc0827d84404e3f680a19e", - "size": 1160691 - }, - "225": { - "releaseTime": "2012-08-22T19:38:16", - "sha1": "60d5a20dce93496201aabe29eab2cbd6e1ce7697", - "sha256": "9f587e629d1f68a92c2e908999a08f892bf8082e31a68dd3fabd01fbd93a718e", - "size": 1160681 - }, - "226": { - "releaseTime": "2012-08-23T07:24:58", - "sha1": "45c32c24fa82f2fdc58137ea2f0f91859bd99d02", - "sha256": "ace28642c14b394070c3a56069e67e380fe2374faf830953144ff820f34a8a89", - "size": 1167077 - }, - "227": { - "releaseTime": "2012-08-23T11:58:40", - "sha1": "efe8252c1f118e6dab54ddd3f718270dddfc7fab", - "sha256": "67c9b58b826939fd6d77f2f16a83df317dc2625aa43dd896dbd4bfb56ebf933c", - "size": 1170150 - }, - "228": { - "releaseTime": "2012-08-23T12:13:40", - "sha1": "8657c475ea0eaeda5c16af9098d07d26fa5780df", - "sha256": "0338dab67d7e77926d9e7ce407243f9b534798b83d6e57e17c57d25195888ced", - "size": 1170172 - }, - "229": { - "releaseTime": "2012-08-23T17:57:20", - "sha1": "7d706d763865779048b5cb612617f77947089c41", - "sha256": "1b98bf38c67a37797565caa5199921a50d3a516688fd5bc888ba9e4ea3b8363c", - "size": 1172234 - }, - "23": { - "releaseTime": "2012-02-24T12:49:32", - "sha1": "eb953b9fa97348e07e073b9013ac8c077f3af32c", - "sha256": "368ebff3d647b3d815395e1cb2ff6517414cb692bd25fa47d9f52cecbf80b0ec", - "size": 461398 - }, - "230": { - "releaseTime": "2012-08-24T15:09:36", - "sha1": "1d31483af924041f9737f21323152328a8ada6cc", - "sha256": "b41b781d5c9fcf05798790ae20ae593dc33f588975b8db88be13b0ff09d2bebb", - "size": 1172239 - }, - "231": { - "releaseTime": "2012-08-25T01:34:06", - "sha1": "398aa064fac7a8711bb611f34abee9450be7e426", - "sha256": "9f157b203662140d71384be689c3fadbfcc2bdeb8887085f3a0eeeae17c497e0", - "size": 1172327 - }, - "232": { - "releaseTime": "2012-08-25T07:15:30", - "sha1": "ab0fd12b1ce77ffb6ac24b1ebadb883087200e52", - "sha256": "c39d6d53e2ce7608f0c4263d23a0ffa59824ad767a4df0faf34f5ea4af525ecc", - "size": 1172236 - }, - "233": { - "releaseTime": "2012-08-26T11:34:16", - "sha1": "807402e42a377050fdc551e021ddd3130a6a3eff", - "sha256": "00a042267454a09179b30569dd2da4ae715d7d7f695a34afdb6cf34e5ab8b214", - "size": 1176543 - }, - "234": { - "releaseTime": "2012-08-26T20:35:54", - "sha1": "0bc0f8f52db177d403cc6aa7f74ae8ab341bc6c4", - "sha256": "b4e952468b1c690213d95885ee0c71c5c0323d135158fbb1e6ecc54565ceeae7", - "size": 1181438 - }, - "235": { - "releaseTime": "2012-08-27T21:50:54", - "sha1": "9406efb776d6317ab2c99a686d9eb32c724bdf45", - "sha256": "6eda7136f7c8c4c29fab4e0bf91989712f84cd5c5d5bf6512efbff5d2de9027c", - "size": 1181419 - }, - "236": { - "releaseTime": "2012-08-28T00:59:14", - "sha1": "40a2c71e07d6c108f4e70ed2f5e80669c03fb549", - "sha256": "302ec33f3f3e7a7101a8d60558d1cd43e491324056a46bd097b69d5281e7141d", - "size": 1181495 - }, - "237": { - "releaseTime": "2012-08-28T01:10:16", - "sha1": "8a9651513e473b3e70e13e14b44cdc799523a5e0", - "sha256": "8f4a4eaed30fa8b8bb9a9d83954fd33e8914a09f8c01202c38055286c995da88", - "size": 1181512 - }, - "238": { - "releaseTime": "2012-08-28T17:40:02", - "sha1": "3b5931dfa33f19686e14dff03e2851a7f6bfc8bc", - "sha256": "fee9770baa979f27a089d9608cfd60624000725290af9fb24108f8b26b22b756", - "size": 1181524 - }, - "239": { - "releaseTime": "2012-08-28T20:46:12", - "sha1": "e5d8cb507f2beeb472e966e8a117a3f28f38fe91", - "sha256": "4e99138dd45dd037fef09cc7f0116d82c771b3c9b6dad9d0796c0e9dc73f8b29", - "size": 1188988 - }, - "24": { - "releaseTime": "2012-02-24T22:19:12", - "sha1": "a3296fef41cf016dfe4133c5f284d88218897c6c", - "sha256": "f285d1a5c6f500ca137bcd34ab95453798400c65b429354b24efdfe6102fc9c7", - "size": 460666 - }, - "240": { - "releaseTime": "2012-08-29T13:46:12", - "sha1": "e7a49134aaa40d28432616a9ae1c216489403a9a", - "sha256": "230c37e867963112a9b4202d91bd0ce3dee6bc30d4d528e35eca81d9d35b3d72", - "size": 1189119 - }, - "241": { - "releaseTime": "2012-08-30T13:14:40", - "sha1": "cc37f754904050111c21a85d5554ee8032329c9e", - "sha256": "2d04f456b42c2c748f27baf2bda69bda316ed3a750eb501818736545b3057bba", - "size": 1189119 - }, - "242": { - "releaseTime": "2012-08-31T15:29:00", - "sha1": "27dc3883f07f26237a77372388b549efde958fc8", - "sha256": "ce40adcbbada923db4b7df1ee4d3a9145f83159945df97218b418a2dff903975", - "size": 1190637 - }, - "243": { - "releaseTime": "2012-08-31T15:40:00", - "sha1": "2846ba941a4e2cf5fe46f56e2fa465bb8eec7d2c", - "sha256": "93d67db0f8afbcdf9bc2d17e16a912925c578b1ccf52924a76a110e2ee6a290b", - "size": 1190764 - }, - "245": { - "releaseTime": "2012-09-02T11:15:32", - "sha1": "02e1248f238bbfc8e96be69adbd1213ae64cb595", - "sha256": "94d80d34a4f7ba7586c9f5e41cc846d6d9ccc8fa4c04a0abc7fc12ca7995cdb7", - "size": 1191348 - }, - "246": { - "releaseTime": "2012-09-03T20:30:50", - "sha1": "b8beb94f7491aab93a7227567c1a9fbfdf6b20b3", - "sha256": "983bfa9e67de68e8cb1a691075efef777e5c44e738d0e9a46869d4b84bf84f6e", - "size": 1192956 - }, - "247": { - "releaseTime": "2012-09-04T17:29:10", - "sha1": "4512823cb1bacd1e973e17c89e5cba03c1154fa3", - "sha256": "96727df14ddfe9a115490fe6a94c35848c1ca5019fe8929f676af1b6000aab4a", - "size": 1197219 - }, - "248": { - "releaseTime": "2012-09-05T23:25:52", - "sha1": "fba13830753463a40593edd07ca73c3eb1710cdf", - "sha256": "f01717142dbe7d2c09baab684c937b8c665df6f7d7f47c98f0b68eca0e3aeb7d", - "size": 1197218 - }, - "249": { - "releaseTime": "2012-09-06T21:09:10", - "sha1": "9123f06fc28d3d9d1347a012a1f490265384f70d", - "sha256": "fba2dec051596362f8a32bf6ec571b158f3363ad1fc1c10add548e529a2d4f56", - "size": 1203819 - }, - "250": { - "releaseTime": "2012-09-08T19:23:28", - "sha1": "64f1ebb51653de5e8c43851d58d760511076d283", - "sha256": "47442a0d27aca2e560329369e1c3c451868b9b3de6cb7c2a56c0198dc5dd2c37", - "size": 1207099 - }, - "251": { - "releaseTime": "2012-09-08T22:53:32", - "sha1": "47842089e4e19de881446c452fb7c13a4870756b", - "sha256": "d50d6b69d6124fa9fa75204a8dedcc761bc5331ffa721b59b24e0229974d0ac5", - "size": 1207098 - }, - "252": { - "releaseTime": "2012-09-09T11:39:20", - "sha1": "ad02718c6ca50313953afd8943ba8ccd8b61030d", - "sha256": "6584a2719b4e67ff3dc6b967730d10dff698b7ed50900c6a47331bda1d632a50", - "size": 1207177 - }, - "253": { - "releaseTime": "2012-09-11T13:51:04", - "sha1": "d224df2f61e8492cb8bc4cb6bd7f5b182ca75892", - "sha256": "285422a2b343cc0357b2bba12d6cdf934ac99aaaa2bbe82522598fcd81ce4434", - "size": 1207304 - }, - "254": { - "releaseTime": "2012-09-11T16:30:52", - "sha1": "48c4dc2d0d599bf586ec3631a73194bfcd760cf9", - "sha256": "4f6d04fe16a1bc1ae7fa0b9e5cd85627c72373682e7ae10ac43e8ad835b74c15", - "size": 1220519 - }, - "255": { - "releaseTime": "2012-09-11T16:55:22", - "sha1": "86cc35abd26f0e51e1f75c0cf5df7afe2fa37619", - "sha256": "eae12bb6dee60dc7522046e01d1483fd53cab07cd6b31cdaf12fec31e2204074", - "size": 1220564 - }, - "256": { - "releaseTime": "2012-09-11T17:13:10", - "sha1": "31736f46042ed8d674f4a5b6d07381cdf416f29f", - "sha256": "38f8d4a6132342bb263631bdb6e4e917321ab110d6b9ab14d889205e4c1f1bf5", - "size": 1220577 - }, - "257": { - "releaseTime": "2012-09-11T18:39:00", - "sha1": "c24ca8adb810e4ded4fb3a5a8e96c5dafe36b5a7", - "sha256": "c1d924bd6379b514a78ba1d6e6730d4c40ac4d6c7600acc79f1a1cab1a06fab0", - "size": 1221666 - }, - "258": { - "releaseTime": "2012-09-11T19:33:50", - "sha1": "c3bcb792058b55f7c4fc2d1bf08bc56eefe7a502", - "sha256": "62db5c51dee86894e5695c277773f03a1df4d5f8a228a71122e18ef21cf8a221", - "size": 1222130 - }, - "259": { - "releaseTime": "2012-09-11T20:20:30", - "sha1": "f5f059fa094272cc57a37b29e1f497d7b160723e", - "sha256": "493e697ffdddf636f072d7278c71fad04010a5a30b0aae18190bb27de37b986b", - "size": 1222138 - }, - "26": { - "releaseTime": "2012-02-25T15:44:56", - "sha1": "2f32d8d4fe7ff21a1134cd2336d292e44e3df4b2", - "sha256": "7af8a2d502bea9ad6e5559006a1e92a08401f2dcbdeeb7ddfc10c651c191139e", - "size": 460674 - }, - "260": { - "releaseTime": "2012-09-12T16:02:58", - "sha1": "d94a9fdd3695659255dd56efdf28971526befdbf", - "sha256": "37e34c0b3ad569cc11e9ec9d55b82bdf78e9306df78180379af1f0c03dc32719", - "size": 1305620 - }, - "261": { - "releaseTime": "2012-09-14T23:15:18", - "sha1": "de533442b141f1c250b17b93e111a30d057c02e1", - "sha256": "ea5593702bf95ac0373b9e926208aad24e05c947bc92c6cd7b9e1cc059063f9a", - "size": 1308626 - }, - "262": { - "releaseTime": "2012-09-15T20:51:08", - "sha1": "a28028cfb93f2616090a6dcbbfa16c8b96c140a6", - "sha256": "091a2a3a14353ec147b802052061477e82b96bb493b98499318b2c207aea0b30", - "size": 1313382 - }, - "263": { - "releaseTime": "2012-09-16T21:40:46", - "sha1": "30a7c5124f1d0a4f5f4bfaf6a8777c3247a220ff", - "sha256": "9286c9e90aed43ccc94ea88b61ded3fcbfcd09fd5b27b37cf4aa7ed1a58602de", - "size": 1314342 - }, - "264": { - "releaseTime": "2012-09-17T05:44:06", - "sha1": "6c785d1017bee9dcac4239749f7ac96495885365", - "sha256": "bbc74e6e951e68c94637a3a26a28e7a67883e91e5baecb82f50a0225aeef8f02", - "size": 1314347 - }, - "265": { - "releaseTime": "2012-09-17T05:59:50", - "sha1": "145240e8eef335df7765a42eb7433d7e9fe442f9", - "sha256": "779049bc88685d694db6d63749f34182211741918b0fd2730a91ac5d29467bad", - "size": 1314351 - }, - "266": { - "releaseTime": "2012-09-18T20:27:34", - "sha1": "3f346ded27f95dd013744fe3cd6e0c2d96c10b3c", - "sha256": "ce136d679ff863568703972c10dfe9d1d75160d4f26e01d7e8bcad0604a4fedf", - "size": 1316175 - }, - "267": { - "releaseTime": "2012-09-18T20:51:16", - "sha1": "8d73f34e62b70f7a88613a0308515cfbd77bfb34", - "sha256": "153609a14494ec17e74d914a9ef4a6a94a242fbb9e03b8dccd2bee4387333513", - "size": 1316171 - }, - "268": { - "releaseTime": "2012-09-18T21:03:10", - "sha1": "b9e7741f51d647af6de525c671270a636f8da77a", - "sha256": "4a982c7fc6181a26a846226152ff8db1b7fb3c716cd8523afb3e1e9a01370373", - "size": 1316170 - }, - "269": { - "releaseTime": "2012-09-18T22:35:02", - "sha1": "6025e36e12dfdc67aa5d5679fe43fdbb31b5a992", - "sha256": "6ed3322fdc785f23cbc32cf38a66301629bbd9fc21254ecccd6633cd3ffe5f6c", - "size": 1322458 - }, - "27": { - "releaseTime": "2012-02-28T18:57:58", - "sha1": "2d31fe2db3a0a1d3e4112b8a7593799b0000508b", - "sha256": "91df022c75d4ad218ff54bb397c8202da1b2c55ab0c75675f2e59502e197d0d2", - "size": 464730 - }, - "270": { - "releaseTime": "2012-09-20T19:50:52", - "sha1": "0c405297d5e32d30edc90eae9b1284d4e93758b4", - "sha256": "ce3814fafdc9e8f1d3c9ed2a3d8695c572d3b12c89de75596f4f9cf962ac6b91", - "size": 1343909 - }, - "271": { - "releaseTime": "2012-09-20T20:59:58", - "sha1": "6ccfb512d6f87bd37b6e85199d3789f548c53cba", - "sha256": "84d316aba81569e4fed43dc1831c32eda9d626471d22f1f04374b49ca3a5dec6", - "size": 1359878 - }, - "272": { - "releaseTime": "2012-09-21T06:40:22", - "sha1": "4557fa3fce875085402a53f74bd1b05bc0efad7f", - "sha256": "15d585a5dd3c667e33d18134115f223a5ec2c151fc25b968abf1e7d635ed83ec", - "size": 1359876 - }, - "274": { - "releaseTime": "2012-09-23T17:58:06", - "sha1": "6ec0b6f483df744accc5dd091a80b5948e63b8ff", - "sha256": "194acd06120c5669d440e7276b36bd30c1370d00118e9a389c801b92b800f069", - "size": 1359855 - }, - "275": { - "releaseTime": "2012-09-23T21:14:34", - "sha1": "e1da8d4fbcfb21627ad727e486e5fc176226567e", - "sha256": "797ca0b72c9405424e9cdb9079994ecdc94165b452fa3770ff1b404a607ef7b0", - "size": 1378357 - }, - "276": { - "releaseTime": "2012-09-24T19:17:42", - "sha1": "c8e7be4ed777f9eceac85775df2931a6e3930566", - "sha256": "fb39f7a37af11c00ec79c1c50f9cd0356f49c3886c03a3a85e0d84db5cdde3dc", - "size": 1379400 - }, - "277": { - "releaseTime": "2012-09-24T20:13:30", - "sha1": "14c6ec0bfff30f2a64c4be8c08fa19362e41e791", - "sha256": "31af93738a346fae8a8eb545625d57ef39939987dc04b2f0fa0782abe091d7c9", - "size": 1379499 - }, - "278": { - "releaseTime": "2012-09-24T21:20:46", - "sha1": "cb49775fe4c7e4b3ad8cbd0e545465d4554da3b5", - "sha256": "04c066b977f7abbe0c9a5b615de5c6cfc4bc8a59f701fe37f7b20f980e95b7de", - "size": 1380176 - }, - "279": { - "releaseTime": "2012-09-24T23:38:40", - "sha1": "7d61712d0a659e852ac966948dee1c9096437584", - "sha256": "e269294f5399aba12dd8bc55b0e14dd3397f7024e4c568f9de1389f74d80f14f", - "size": 1382733 - }, - "28": { - "releaseTime": "2012-02-29T02:33:32", - "sha1": "35151035d6694f7e58f2a38b86ad41605ba9eead", - "sha256": "29de2673b5b22b782d8cef432883f651ca295613fed51d1d96ff22a337ed0a66", - "size": 486646 - }, - "280": { - "releaseTime": "2012-09-24T23:52:36", - "sha1": "47743796a00274d650c48426e8a1cd4e7974717e", - "sha256": "5848521978f5967a995d16844ce50e5e260abfbab0311fd6f02f2dd21f1197d5", - "size": 1382958 - }, - "281": { - "releaseTime": "2012-09-25T06:09:10", - "sha1": "1138df5823018374c2805f381007002568812deb", - "sha256": "aa009dc61289bf4cd4616974ba15e2246ed562391952e925fc4e4d3a3290d61b", - "size": 1382960 - }, - "282": { - "releaseTime": "2012-09-25T07:37:12", - "sha1": "b9204db9e55c707c123ef96c34bce982cf6ac6eb", - "sha256": "8560e9cfa84ebd08812e6c81774103074c8db8bfb371f1b8fa7b52a5994a40bf", - "size": 1382961 - }, - "284": { - "releaseTime": "2012-09-25T19:51:46", - "sha1": "d041d3886bcdb568b96852fdc5cedcfcfabfd2ca", - "sha256": "57ef413d7562f44ad3125755ab31b3c9c60d909d0b90a89140ce6dedf6cb4a5b", - "size": 1383332 - }, - "285": { - "releaseTime": "2012-09-25T21:10:46", - "sha1": "1f7ab01768059ce5928fb0b6f1a527aafa4fc8d7", - "sha256": "f251c87ed68ae655567900f9e960eeca02daa1bf3aabe7bbb342093608824c5d", - "size": 1384679 - }, - "286": { - "releaseTime": "2012-09-26T02:49:22", - "sha1": "728b7e377c5f9bd0ef9ec66b382665f9b83340bd", - "sha256": "282808cb91384574aae591926cc778ed3a91eae18923eacfde99f3bb1ea31c48", - "size": 1384692 - }, - "287": { - "releaseTime": "2012-09-26T06:56:34", - "sha1": "fd68f31ce6d9e798d39eda31bc8a6ed3840bf036", - "sha256": "daf830444ab50cb61393843d6f489f7d358e09cb4dca5da72e5faa28bc66d416", - "size": 1385394 - }, - "288": { - "releaseTime": "2012-09-26T13:23:24", - "sha1": "f9943e9a126373b4afa55664f3ef882c8b02e4c3", - "sha256": "fbc87e2b5e473841cc5227856f71fdacfe76ace73fbf69ce003df8de322bae3d", - "size": 1385418 - }, - "289": { - "releaseTime": "2012-09-26T18:59:40", - "sha1": "1b91b9786878ac44121db168bd6163faa005be02", - "sha256": "fd1c33323f1202c5010c586091bd6dc5a4fca7718547b6475bddc17cc7227813", - "size": 1387742 - }, - "29": { - "releaseTime": "2012-03-01T09:43:22", - "sha1": "24afdde48a82edef65f089d7e98844444d6f368d", - "sha256": "deff2dee5718547a537148eb24f6130e6b145a360d3fbe82ab4c52d59d72ad6f", - "size": 486658 - }, - "290": { - "releaseTime": "2012-09-26T22:23:24", - "sha1": "038de0718c800c605deda3cc1ea63f1467cc0d85", - "sha256": "47118979ecc3f2c36d36b9d70bf96a5881837008b05aaa45a63c5206b203c6c2", - "size": 790109 - }, - "291": { - "releaseTime": "2012-09-26T23:17:06", - "sha1": "065b1fe40b67ddd5d8bcf14ae9f1c5596f75713d", - "sha256": "073b76291ab2507af08eafb1b61b4e9faf6d22ad62e3bac396f95b9aed68a216", - "size": 1395063 - }, - "292": { - "releaseTime": "2012-09-27T21:42:56", - "sha1": "a679d1084c73429a77c4ffb50b97ce777b4609b4", - "sha256": "3acd92ea7648db24593c114ce5686a943461febc01201ce5b9d7ee23cdfb524b", - "size": 1396837 - }, - "294": { - "releaseTime": "2012-09-28T01:06:32", - "sha1": "64f6f140b33e9e5f19875173fdd320287797e684", - "sha256": "0cc8414d0a807bfede8f5795b42e45bf841da38a52124335fda658403f75acfb", - "size": 1399300 - }, - "295": { - "releaseTime": "2012-09-28T22:40:30", - "sha1": "93a98657e5bcdfd5649f01f692f58c22da0e47bf", - "sha256": "94fb922756e6d65dc1f33b0ba3d55cc1a7b1164ff288be326459e710f859054d", - "size": 1403212 - }, - "296": { - "releaseTime": "2012-09-30T01:53:04", - "sha1": "fad0d621171c99f9caa0f41e123a58024f0e35ee", - "sha256": "024878d93bc75e2da4ead3658a1d100f613f6c9db5f453b31804b4f9826334cb", - "size": 1403299 - }, - "297": { - "releaseTime": "2012-09-30T02:05:30", - "sha1": "47e7ff030762ffe8e6ed354a119a08123a9173e5", - "sha256": "b11d5af17c75405368034f8e25e0a6f5e8ee8cd51002ceea0d6325b9e40bd880", - "size": 1403379 - }, - "298": { - "releaseTime": "2012-10-01T20:00:02", - "sha1": "4916d49e40f4fa54166886bac140355aef3566c4", - "sha256": "4950ddbed97db5e1c206117360ebcc5476d8766de01ff81a14d8bc721b6b1b2b", - "size": 1403428 - }, - "299": { - "releaseTime": "2012-10-03T01:15:02", - "sha1": "2ccd5e67834ed7398d9ac2640e099b62b5abca9f", - "sha256": "2110109759eecbc0620332d36da3f563928417e110d174f6dad5b7ea7f8ac706", - "size": 1424943 - }, - "3": { - "releaseTime": "2012-02-07T05:17:42", - "sha1": "3fe54181614b768989c3c7bf7511e155e6951b50", - "sha256": "58bece6eacb2ac1f1620cfb933a28091e29a54011b833bf4e237020ae5f7410a", - "size": 410382 - }, - "30": { - "releaseTime": "2012-03-05T13:41:18", - "sha1": "595e36215d90f21453aa9341229e912f24e34270", - "sha256": "7cc4d8665a7e53eebe8b464268aa87279e50fb72018a1a13b390a044d550ccb0", - "size": 491830 - }, - "300": { - "releaseTime": "2012-10-04T17:54:54", - "sha1": "86cd379f205b276f8c0324f68d2f2e8937385e9d", - "sha256": "ef233640f7f1355f1e75ee17028d25c907c0b6ee349e3b9627ca1399eba377f4", - "size": 1425269 - }, - "301": { - "releaseTime": "2012-10-04T18:13:16", - "sha1": "a2be7a5a53937cd1e9ba52d5c96000d65dc5dcd0", - "sha256": "1bab552c7fa6ec7e2b081a1588d4c52644e6af4704ec2e01e53fec4f6135cf23", - "size": 1425270 - }, - "302": { - "releaseTime": "2012-10-06T21:08:56", - "sha1": "f13bf3a018b054802e3a392d06f4fb4119ef9b20", - "sha256": "00292036a9eb6f604047712d63e11ee4b6fd6b3ed78ebea87ce0681c0047faa1", - "size": 1425356 - }, - "303": { - "releaseTime": "2012-10-06T22:33:42", - "sha1": "3889893893cb42d3a6152e776e9f6a180066dcaa", - "sha256": "e4a2b58ed312225e2695454736891bb41827ca554c84827023d33485656f0521", - "size": 1428414 - }, - "305": { - "releaseTime": "2012-10-07T19:21:12", - "sha1": "efd0fbfb3485a70ed9fb2af461a8ee2c5049fb3d", - "sha256": "2999f5efacaffc97feab6ac34d9fc912dd62f485afad14a712e0b88b42f4fcbc", - "size": 1428418 - }, - "306": { - "releaseTime": "2012-10-11T20:37:20", - "sha1": "ba1430d974407ef00969214c4390217b5ec64273", - "sha256": "2cd545363aac02da88b7885cec17523cf8b86daf6137cfbb465ea3c30477fa10", - "size": 1428541 - }, - "307": { - "releaseTime": "2012-10-12T07:06:42", - "sha1": "4abca56246431b36c149cd313e4835763ce8fd18", - "sha256": "a74f4c9a9fbfa40ad32cf1a80ad5440dc69742507746c1186b8c7cb93caedeea", - "size": 1428536 - }, - "31": { - "releaseTime": "2012-03-05T15:11:10", - "sha1": "4bb8573263e2d3e44fa5c6ef43f3e18ab5262562", - "sha256": "f8bdcc0c6024d76ea9e5e0e1344ac7241781afc3a231ce02da00906389880c90", - "size": 491816 - }, - "310": { - "releaseTime": "2012-10-14T13:21:20", - "sha1": "8052486df828c7cc6489d1f8a9ff0616c4d1d4fc", - "sha256": "7e530302923567d8e67dee84dea6495372a9fd583cfeb615410733f851598ce2", - "size": 1428709 - }, - "311": { - "releaseTime": "2012-10-14T21:04:00", - "sha1": "a040f2961a9f80d213dd63fc524a43c97a80ff81", - "sha256": "f85f541a15f45eec0e2d1729f723eec8d4aa4f61be174f7018385625baae58d2", - "size": 1432897 - }, - "312": { - "releaseTime": "2012-10-15T17:26:04", - "sha1": "b0cf805b556bab9117143b4a98a3858627d41e09", - "sha256": "2eac4812f955dfc247f10f2505e5ad571479ff073b8956f34d6f7ef2410ff987", - "size": 1440667 - }, - "313": { - "releaseTime": "2012-10-18T18:03:14", - "sha1": "fef9dcf979edcc958e88b6df81ef3c6389e8b337", - "sha256": "37bd8e7bd982b43b88e1812940e5b5dbd815da6a7ef0e497bd715e2d665512d1", - "size": 1440713 - }, - "314": { - "releaseTime": "2012-10-18T18:23:34", - "sha1": "0e6d656ad19cec0212bde20ab007aebfe307524f", - "sha256": "e2c45046b943ad8a0fddd1459f859c8f11daf55ddae79ee5bc915fab73ad9b71", - "size": 1444706 - }, - "315": { - "releaseTime": "2012-10-18T19:36:54", - "sha1": "d73efe944b56af1dec736a2841bf90b982fdcfda", - "sha256": "6a84beaca35ff12697c463325aac82047122d992ca30945689c735b81357c905", - "size": 1444954 - }, - "316": { - "releaseTime": "2012-10-19T07:33:54", - "sha1": "c6523c32c76347f4e524f2a62ffb818c1be100a0", - "sha256": "50c3dc888d807a521e159506439df28e9d1f607b51f9aa6f5e3351eeec37282d", - "size": 1445006 - }, - "317": { - "releaseTime": "2012-10-19T09:52:58", - "sha1": "953bcb1d58c2936bb09de2865087969a4c477b97", - "sha256": "301624aaf307f788af93c31d9a78a924fcd606c516f8250803594e413ca30794", - "size": 1455076 - }, - "318": { - "releaseTime": "2012-10-19T20:01:02", - "sha1": "a9aca7b4697197542b6d5af11a4f54aa4b052cb7", - "sha256": "5209fa33513733ea5466166354db2004c9b5373da59d45ecfa390f8870341b39", - "size": 1455002 - }, - "32": { - "releaseTime": "2012-03-05T20:08:08", - "sha1": "22acfcd17c076eb0d421c4dd3b954aeaaa9ac541", - "sha256": "ebe9955b45a3b57b9729ddb39cffefc84fac133df5b4faf5a16e8772e7643ac7", - "size": 491816 - }, - "320": { - "releaseTime": "2012-10-21T19:03:58", - "sha1": "2458eed5baf11e6cad3dd20cd1597eb21e6619da", - "sha256": "bfe7f3d609aabb8ef140ad7e440f3a5889d651a970076acfe3b418dd60ef544d", - "size": 1494316 - }, - "321": { - "releaseTime": "2012-10-21T19:10:42", - "sha1": "3cfbfacdb3187808752b41fc05281c10479d1d49", - "sha256": "ef596b1ad38833c2fa296f4f6ea0bc48e0ba477c1f7486daa8540674a6e98c41", - "size": 1494344 - }, - "322": { - "releaseTime": "2012-10-21T19:25:06", - "sha1": "7267e92a88bdc02609fe505498ef04ebab34e1b9", - "sha256": "73ad5c2751b5d582bb450b2803e3e3410bb71503b3a89e548f1f66995eff7789", - "size": 1494344 - }, - "323": { - "releaseTime": "2012-10-21T21:13:26", - "sha1": "609edfe719164418a648702d0d4886cfecae0af9", - "sha256": "62321c8a8ba3c75592929cb9b6f85093a53140066c77c44c1dfb3099a797f63c", - "size": 1494585 - }, - "324": { - "releaseTime": "2012-10-22T00:06:58", - "sha1": "1bc48563a4863659b9f4a7db7556bc34fbd759f6", - "sha256": "d4ba7ee24d4c96459f9ddac17f9ccc6f2b1cf1fa3f9db2ff35b2305664693f0f", - "size": 1494640 - }, - "325": { - "releaseTime": "2012-10-22T01:33:04", - "sha1": "c4fdc58df5f7fef44f1fc56c8e21b4c7eeed2e36", - "sha256": "42cb64e70fe45866f53fd1042a9ae547cc1b93f6ccc7c2f4ab7d2d0756514723", - "size": 1495067 - }, - "326": { - "releaseTime": "2012-10-23T07:33:54", - "sha1": "951d5d3be6a187f7d8083ab272490b611b83178d", - "sha256": "a3eb35d9315cb30dce07064eeddcdb501db6714248ee1275e1952f1705364fee", - "size": 1495169 - }, - "327": { - "releaseTime": "2012-10-23T17:11:18", - "sha1": "206f653b01decb7ed59856d8e5918aa2e29d7de7", - "sha256": "9b3b2f418c36341abb1772c58c2fb469b9791ec17d633f15f05299df360982a5", - "size": 1496510 - }, - "328": { - "releaseTime": "2012-10-23T19:58:42", - "sha1": "1f0adeb2906c5b36ea2e9aa38ffae6249fcc4fc4", - "sha256": "4117b0c4a84004bbd00707726541c554daaa7ae47d5c64756c4c2566a3d8f4f4", - "size": 1496526 - }, - "329": { - "releaseTime": "2012-10-24T04:58:42", - "sha1": "fdf61e473c34f7273962370da9a40dfac2554d28", - "sha256": "c10ffa5d4bd63737808d8273097678c256d961bf556f6f5f8bc2c283e95ab230", - "size": 1496508 - }, - "33": { - "releaseTime": "2012-03-06T00:33:56", - "sha1": "e0c02879e9986488810f4f54d4b7c3d71700daba", - "sha256": "6d28858969c5aa5b1151c73708d9996e154c0dbda3d7f526c503df5c7cd40f7a", - "size": 493289 - }, - "330": { - "releaseTime": "2012-10-24T15:06:52", - "sha1": "7b7c77d36bef706f655acac4507a1a731282c342", - "sha256": "b6215a0814bc50465b47d00497bf29a0d87e7b296470f532238208af5b5d00b1", - "size": 1503248 - }, - "331": { - "releaseTime": "2012-10-24T16:22:08", - "sha1": "6e943173b9889fb97d86a0dd27f2a4e85777aa92", - "sha256": "e34fe78f021948511a9ebf4fdaeab63e1095278ba61c3cb9d7e1d9f43591a191", - "size": 1498731 - }, - "332": { - "releaseTime": "2012-10-24T20:19:58", - "sha1": "65355d7e60accf48e78e9fa011bdbd9c90a57f9c", - "sha256": "0bb6f6d7b832fb02010711638be3c94ef9b7c305e720127353f7df9c0927f801", - "size": 1502361 - }, - "336": { - "releaseTime": "2012-10-25T12:50:48", - "sha1": "770038a5a35f4d615fa8329f2ce86e2244555295", - "sha256": "504a206d83df78ca2e0c1d4d2ac73a352bdbb95e10f23d85f6e1ab6cc67cda46", - "size": 1510583 - }, - "337": { - "releaseTime": "2012-10-25T14:06:30", - "sha1": "8ef4b1ee1783e504c963850e0388d7841a07d9f5", - "sha256": "1e384bd63602ae7c72e508869874d48479b4b84dde060eb0d421110a4ed29607", - "size": 1510581 - }, - "338": { - "releaseTime": "2012-10-26T22:14:56", - "sha1": "66639c2142007e828ace0e073e8bb6cee331b9a5", - "sha256": "03cf9db17993d4f7f65ca35f8417af1fc9009d89e915312c77c6770c9d9c823d", - "size": 1510621 - }, - "339": { - "releaseTime": "2012-10-26T23:42:06", - "sha1": "2b7c222c546aa1fb4970158cb73a3c7ee1a8752f", - "sha256": "066bb3a7e85f79956b1d63a05669f5341cd3bed037c82b51979e00097ef2eb4f", - "size": 1511938 - }, - "34": { - "releaseTime": "2012-03-06T12:16:10", - "sha1": "026c986f32243ea3717ef5588078cb24e205dc3f", - "sha256": "fa01b7da584bb1bd82ff172b7a0c20f0cc331cdedc8147ca73f4242650ba92d6", - "size": 493315 - }, - "341": { - "releaseTime": "2012-10-27T17:16:34", - "sha1": "e4803f22cd8658dad3d9fcfb0e1000d64a6d23bf", - "sha256": "1ec9689844eb2f0622b4b2202eda95be209d46e52b2974c0d209710a3d123fa6", - "size": 1512068 - }, - "342": { - "releaseTime": "2012-10-28T05:21:52", - "sha1": "5ed309d34f886909d155c2a9ce4ecf0c5773dd2d", - "sha256": "f619ad665ff333142023ad40f711aa1fecaa90be3fc441fbe26c88db60453f15", - "size": 1513794 - }, - "343": { - "releaseTime": "2012-10-28T05:56:26", - "sha1": "7e75505b38d43d8ddba72ca54a80a05d3f8421e0", - "sha256": "a05a4d0b1630434f8101b7e719e4234064bac07c051c69fc54c86649dfc427c7", - "size": 1514653 - }, - "345": { - "releaseTime": "2012-10-28T16:40:54", - "sha1": "3ea15e52020b3e2293ef51c0e94a6f9e7a5126f3", - "sha256": "1064de17fc5d2f395020da84cb14e590abf35874dfed266bcd270e44f24fb400", - "size": 1525523 - }, - "347": { - "releaseTime": "2012-10-28T20:10:44", - "sha1": "0b1205eaf6f091a06f340259f6f249ee76787e6e", - "sha256": "783555feb06393b22fa6639e40018ae647a50baec7bce2aa4aacd0827626e312", - "size": 1525525 - }, - "348": { - "releaseTime": "2012-10-28T22:58:56", - "sha1": "bc79e870e11fef61ddfba2c82eb4268af049a44a", - "sha256": "12d3bc2efd574c691c5cd1304be113605dc585157c2f9dc9759a36a5605d38ba", - "size": 1525392 - }, - "349": { - "releaseTime": "2012-10-28T23:11:02", - "sha1": "1cfb5f54ce72ddb174031b64d04c158f98892a51", - "sha256": "e47f59822872eca8e85a9fc5f5a3eed512109afc595201b245987b5ec4f32806", - "size": 1551747 - }, - "35": { - "releaseTime": "2012-03-06T14:22:22", - "sha1": "ba295b9285cc6be48d3dfa7fd37ea86213c45578", - "sha256": "28a1f00312db22a4cf21e8a2f44738816a86ae4f20ddfa722399539834436155", - "size": 495444 - }, - "350": { - "releaseTime": "2012-10-29T00:46:24", - "sha1": "5d9a4661d55b93221d6363a58dd5376474351c01", - "sha256": "6ef74924226dc59a37a3d718caeb152490de0f32caf06b832a5717b324fa57af", - "size": 1551798 - }, - "351": { - "releaseTime": "2012-10-30T07:34:28", - "sha1": "116fbdbc70e3dd7905bc5c591cf6a4969c126da1", - "sha256": "93d3daf31960dc9ed863037f02d078c2f52f3ebbc22ab16f91b3691834722a0a", - "size": 1556458 - }, - "353": { - "releaseTime": "2012-10-30T20:14:42", - "sha1": "dae9da6a5f388913fafb99f9c99fcf4b60e22f80", - "sha256": "565d5b12e452affca7965d1d0b6b7208bfe06522a1bd82002f416278d0f90cff", - "size": 1556757 - }, - "354": { - "releaseTime": "2012-10-31T11:20:58", - "sha1": "629cbcecc84e21703fee50093402da51573b073e", - "sha256": "75407b1dfe61f9a0722377f80eef7734c2567750c43b2950fcabf86995c7a77f", - "size": 1556800 - }, - "355": { - "releaseTime": "2012-11-02T12:52:28", - "sha1": "f7885f3ae3436d452a8bef4d9668f95298f7da7b", - "sha256": "b35d3cbe3a4e6a967fd97791be9e03014531aba1b2df6e365981436cc2dfbc6c", - "size": 1558322 - }, - "356": { - "releaseTime": "2012-11-02T23:37:06", - "sha1": "3f617c12e53ba1e3bb572e80d1b7665bae78baa3", - "sha256": "086d80575e3d80afd7f2eea8ec16f16b9f8c13ab3da7193c0c9f2f28792bcdce", - "size": 1568644 - }, - "357": { - "releaseTime": "2012-11-04T16:48:28", - "sha1": "eb0ae9e2504070958b6189483986e9104496b851", - "sha256": "befbd54a2a2d330d3023b43f680de88048d4ed9619ab271e5a94cb170ddc2aeb", - "size": 1568710 - }, - "358": { - "releaseTime": "2012-11-05T17:19:40", - "sha1": "04031bf441d7a634a85cc42013944a9210f38417", - "sha256": "7ed938631edfb68e4154b210246eaee2152d692e4dfc19aab14a241dbda26a9b", - "size": 1571298 - }, - "36": { - "releaseTime": "2012-03-06T15:09:00", - "sha1": "8ea8e6acd46548bd44e4065fcd298c6c8fe45bfa", - "sha256": "065e78e6c66fcc12ee0739ade8bc6c4de458d6146b2aa0268a27726846a27822", - "size": 495443 - }, - "360": { - "releaseTime": "2012-11-08T21:48:34", - "sha1": "39be64e9c2150f4fabc0b935f89d7eb4e98e768d", - "sha256": "93df1c8f6ef9df7a8a720498fc1d99c13a1d8d782425b4e1763e5465216c8a1d", - "size": 1570985 - }, - "361": { - "releaseTime": "2012-11-09T17:25:36", - "sha1": "f398db2d8385a3fd219bfe6c9497592e4d4c2e22", - "sha256": "cfd5bacca0ac58763208f506afd5a99ed729c73675adca26f9e5854bed620840", - "size": 1570879 - }, - "362": { - "releaseTime": "2012-11-09T19:04:06", - "sha1": "e87fbfea41cb8c1d45ed826d38ff7b956bacf080", - "sha256": "01b69b8250676214c6d6d4ec8750569cece3393925482b2cfe349b6e5781c17f", - "size": 1570970 - }, - "363": { - "releaseTime": "2012-11-09T20:56:32", - "sha1": "1771762757ed9d42f0037edb3676e77739a7a771", - "sha256": "4c05f84231bf150ba275f086857278b39bead1ace381553cb18bac4ccb61b93d", - "size": 1571054 - }, - "364": { - "releaseTime": "2012-11-10T19:33:58", - "sha1": "94e582f9b55f032a6acedcec16c78adf8dc5d491", - "sha256": "cbc34b9f02573e14a910d8a6dde8c99a7099da75a4be2ab096e6c5d5d81576e9", - "size": 1578038 - }, - "365": { - "releaseTime": "2012-11-12T18:44:30", - "sha1": "8777440f4e187005c0897b0210c927b9657334e7", - "sha256": "5ee66f082387f88eb932d1bdfce8d6d2c9fff7d062f28f76c3da9c08285c3254", - "size": 1559401 - }, - "366": { - "releaseTime": "2012-11-12T18:53:48", - "sha1": "ab553f5143e540886bef8f84d34fbc7fefd48db5", - "sha256": "a5ec60b85c40f16c282aa0c4148f2da10f404e27903be7a5f81418988e549a3c", - "size": 1559399 - }, - "367": { - "releaseTime": "2012-11-12T19:47:18", - "sha1": "496ebd0e668fe2d8d6407c3a451dc85822a5c542", - "sha256": "c91589bd1bde3969a2aac31aae08b9f66e1955c454eaadc204ff1094f8a02024", - "size": 1559438 - }, - "368": { - "releaseTime": "2012-11-13T05:16:32", - "sha1": "4a6ce155d69a0e77172bd33e8542843ba2fb5557", - "sha256": "936ea8b61d2569e41e18e9f1cf6e3f6bf62e96f3458f01bbde7035694b27b69b", - "size": 1572991 - }, - "369": { - "releaseTime": "2012-11-13T12:34:36", - "sha1": "ba531896a52058369d867a96ad471c33b196fbc8", - "sha256": "2465f0cc6bfc3a6ce1f1e7c4792ea3378d095c80feb7022dc7f34789e7b1ffd7", - "size": 1560273 - }, - "37": { - "releaseTime": "2012-03-06T19:04:38", - "sha1": "0fe737b9df40cab28f02c37590e424f67df083c4", - "sha256": "7262bf12856ad4843ba79af6b87893890da228afad5ef864ee8caad45d4f7630", - "size": 495444 - }, - "370": { - "releaseTime": "2012-11-13T13:09:52", - "sha1": "b2076adfc54efc8ae825730a64ed01279d44c211", - "sha256": "0c1744dbc69b89a48751270fb564eb6f4309da6bde626e1372d2d50e25e5f98a", - "size": 1560358 - }, - "371": { - "releaseTime": "2012-11-13T14:07:42", - "sha1": "b183e618cb2e48527f7a29b708fff9d58295f1e6", - "sha256": "13e8021d23a2d2fcb5ca9fc3df96b3455818069266587fb341843600467b1b8f", - "size": 1560418 - }, - "372": { - "releaseTime": "2012-11-13T19:58:58", - "sha1": "027d47d7976d01ccc3599e041dfcded3ec15eb2a", - "sha256": "1b844c29cec43e00e82b65e258f71f61c1cce5ca0d2b8356f50b47d9d6ef7932", - "size": 1561761 - }, - "373": { - "releaseTime": "2012-11-14T19:27:58", - "sha1": "fda4fbf2916207d55e98ec27ea61549c1826da54", - "sha256": "a0c437ddd2cc6c7be270fc6b88d6539829679b79bd01aff7f90e79a3bbfc148e", - "size": 1562217 - }, - "374": { - "releaseTime": "2012-11-15T04:49:52", - "sha1": "9de2d89f0531bcb1adc8267ee0a8baa008f33e85", - "sha256": "fa82a63bbd85cb7ae31956b637e735a8cc2febd981ee68b400a999691e1b0a7a", - "size": 1562900 - }, - "375": { - "releaseTime": "2012-11-15T15:28:26", - "sha1": "0d8966170b6962601e5a91b19b2d50e341712823", - "sha256": "4d13ace48459183ce6787de75d60b878a2af9953b62a613a54f3bfc46a65cb3c", - "size": 1563025 - }, - "376": { - "releaseTime": "2012-11-15T19:51:02", - "sha1": "e1b8b7bace6918a37d4d514cfc7fda2d52ed8026", - "sha256": "c9747e1904f643348284bd0a84f69fc39466f8cf294eb7e8bbb8dfa38fff3da0", - "size": 1563055 - }, - "377": { - "releaseTime": "2012-11-15T20:06:00", - "sha1": "780c95faaa1ba67abad4f3337400608c447cc58b", - "sha256": "6933de9c37497ddddbe75c097dec6bfb6cc2952a0b1f677395484b90246b3205", - "size": 1563101 - }, - "378": { - "releaseTime": "2012-11-15T23:33:32", - "sha1": "dce5007bd59c08b094a83f1f35b64e25f1996f78", - "sha256": "8530d8205c99537ed71b7252ed34f05326e88e901ac8950d34da36142619a9a5", - "size": 1566485 - }, - "379": { - "releaseTime": "2012-11-16T15:47:20", - "sha1": "b201f6af733fbfb0bd2c11c68774b31588257217", - "sha256": "0f4714124c33ee1d7531a385da2ca59bea742c668e8420eafba85cd1481cbe5c", - "size": 1566514 - }, - "38": { - "releaseTime": "2012-03-06T22:49:30", - "sha1": "d254fec60aafefafcb399790a28f27f69e67d56c", - "sha256": "f946b0050a736e47a115da5cc5a23a4cf80a8a54cf1adeb16afb21da332bbf37", - "size": 495443 - }, - "380": { - "releaseTime": "2012-11-16T17:12:00", - "sha1": "2307ad742e748fd12a8565bd5da3cb751a6432a9", - "sha256": "c3521e6ec808aae8d459ad0851d5888e3146aa934920ce2b7c3c9877a14f2689", - "size": 1569305 - }, - "381": { - "releaseTime": "2012-11-16T21:14:30", - "sha1": "4dda566adf78076414db2c141940e6aaaa41dbd5", - "sha256": "701a668032d4d621221caeb0a24d4f244394afa128e7f392679f9737e21acfb6", - "size": 1566513 - }, - "382": { - "releaseTime": "2012-11-17T18:56:40", - "sha1": "1f944700b9a13ac67691968da20f2535e3d77bca", - "sha256": "0bf4fbad7b07e72fba6f858fc115ebb8d0c9622f13b110f2d750a2aab70aae69", - "size": 1566687 - }, - "383": { - "releaseTime": "2012-11-17T22:21:40", - "sha1": "65e67841ce18c66bc1cde1ba97df287983a83bf8", - "sha256": "b6ba49202676310a9510ce41181edc018cfa373ee83d033692d4b00d53c4bcac", - "size": 1566646 - }, - "384": { - "releaseTime": "2012-11-18T00:03:10", - "sha1": "3c6adeef6acfc9b7abb0f199b395b98f711cb93d", - "sha256": "647d75ae381c37af8c025ef68f08da0722995785dde35df5f3f3da2a6b7818ed", - "size": 1566769 - }, - "385": { - "releaseTime": "2012-11-18T02:42:22", - "sha1": "a15a6f757d97b8f0eb8ad8d4ac7d3124c0321746", - "sha256": "c177bc64a849afcf08f47a1b840ac8374a97c282f5a36e5901beec293ad02b4a", - "size": 1566949 - }, - "386": { - "releaseTime": "2012-11-18T09:16:58", - "sha1": "99e1ab64ce488b7232c73208b16eb04f470fd9f5", - "sha256": "c9cd3f00e1f80eed295e5630a0be0074813f9d17f1113c1cc78bad733c43e556", - "size": 1567017 - }, - "387": { - "releaseTime": "2012-11-18T17:32:38", - "sha1": "2d91b92f77c2decd351b13e5d50019c2bc4af3e5", - "sha256": "68b80e96f6f9a346c1b15ee4fe169a5b2fcc2fae413b897dca8a5073b3f9a6ac", - "size": 1568405 - }, - "388": { - "releaseTime": "2012-11-18T19:26:58", - "sha1": "876479361328ed724181a07a30a1a103b600fb2c", - "sha256": "762580a61284d0c3740e577e1b76038fcb7866170f03eafd268a8b62f8d00a37", - "size": 1568457 - }, - "39": { - "releaseTime": "2012-03-07T09:49:42", - "sha1": "dde19ec058b2f6628763f1bc72648844155a67b8", - "sha256": "a321c4314b2cca490d977c37ef1fdb183e3a5371abc68aa01a3587e6ccdadd42", - "size": 495506 - }, - "390": { - "releaseTime": "2012-11-19T17:07:02", - "sha1": "c71d7e28ae162d29eb8806040f6f7fbf21708d14", - "sha256": "542cf72c16c210875f6eb55097165e7af472b306817506f8d5ab3778ff06f6cb", - "size": 1568504 - }, - "393": { - "releaseTime": "2012-11-19T22:03:40", - "sha1": "fed5072a6499574348eb2e1726fbb4599bd0a3ee", - "sha256": "21060ed45ea15c48c35c4977b9cf08b76a69ba26846b087df29a693f7378d090", - "size": 1568255 - }, - "394": { - "releaseTime": "2012-11-20T07:12:44", - "sha1": "66e56c512a992b0bb903a75ae84d06de354b5c28", - "sha256": "da4530a3d6587165c1a40f8fdbd2507d65b26d7c3793c3725abd1ea1aa331a34", - "size": 1565762 - }, - "395": { - "releaseTime": "2012-11-21T17:10:54", - "sha1": "5be9167d38845adbaf24e58e9171d582b1e9d612", - "sha256": "a29de2d2303298967ef3c3eeb0b0abe5d35c543cb4b885c77e82997e52288b35", - "size": 1565838 - }, - "396": { - "releaseTime": "2012-11-24T12:17:28", - "sha1": "3efd96ec4115072fc8ad5b5a202d27cf8ad56ac3", - "sha256": "571f1ead1b918d6326844c34e1f529007d890c30ad4831aab092b1d7b1c6007c", - "size": 1564970 - }, - "397": { - "releaseTime": "2012-11-26T22:28:56", - "sha1": "2f1a2fd2a5f9bbb7a39490bb4c029b39db80ce48", - "sha256": "7378bc6b9d96c22d277fe99c6f4ba0e9b8b72ee3c7ddb84e5f27ec640904b243", - "size": 1564930 - }, - "398": { - "releaseTime": "2012-11-27T00:49:16", - "sha1": "f5bc769ba675895c657804c7aa1574e993cedb39", - "sha256": "74141455ecb4964d04c19ac4c59b0fa4d3064121968d5249a3a914f1f1c3a9c3", - "size": 1570364 - }, - "399": { - "releaseTime": "2012-11-27T01:31:16", - "sha1": "3f81754b6649761afcc5f9ce17ac92a078ebc713", - "sha256": "563a12fb5c7a82974aeb427928fd3f2a4a77d58421d62519ee5640a3de57110f", - "size": 1570525 - }, - "4": { - "releaseTime": "2012-02-10T03:10:24", - "sha1": "0e36def24134f9ea0262d650d757a37375eb03a3", - "sha256": "e6cb1ccf475de90bc7455bfe7d3b22c48474d8f2f779ce15869b5f12aa97991a", - "size": 417875 - }, - "400": { - "releaseTime": "2012-11-27T03:09:46", - "sha1": "ffce011510bac3b35a704cba8bddad4ff77ac8b0", - "sha256": "234d9950ff347a9636f93a7e2ca5c13100a25c944fcb0e3d3575fccec207f8d9", - "size": 1571980 - }, - "401": { - "releaseTime": "2012-11-27T03:18:54", - "sha1": "d20d4215257451427feac211b007881c57e1259c", - "sha256": "6a849378fe84c62d2623b363a30686f16bfcf3cfccbe3ed0b0a35b02525a1b23", - "size": 1572151 - }, - "402": { - "releaseTime": "2012-11-27T13:28:34", - "sha1": "25889ddffbade3e9c467ffb0c5fab27f36078dd2", - "sha256": "66ef433a2c80bd59a874e9a3850247358a7b4dd2eca082eee86e721841d7ee87", - "size": 1572142 - }, - "403": { - "releaseTime": "2012-11-27T15:56:04", - "sha1": "3836f55df5e5b0ef820273d7eaef7392126fcb3a", - "sha256": "f25db24661de5f1bab385bba2552fdb6cb6ab000d43d27bc12524580d2c181f1", - "size": 1572392 - }, - "404": { - "releaseTime": "2012-11-27T16:06:34", - "sha1": "e958182912c91fe4c77fbab7fdb60148ff4efae8", - "sha256": "d9f855ef98c546e7213c1ed863909131a12ed20ffca479949009b7faaea6272a", - "size": 1572624 - }, - "405": { - "releaseTime": "2012-11-27T17:21:26", - "sha1": "78e964e525fdae2339787d5063c14668e4de18a7", - "sha256": "f8032efd8fbcd2c25a657b567934358e98557d92895e1d0094c5fb638ce68230", - "size": 1572753 - }, - "406": { - "releaseTime": "2012-11-27T17:55:00", - "sha1": "191d3a0768b892f4af6aa256639f0267cc4177b3", - "sha256": "88f276290ad3b4505e1c6a3486c6ce69a96db9416498e13d21886d948d05b60a", - "size": 1572983 - }, - "407": { - "releaseTime": "2012-11-27T23:46:16", - "sha1": "7b50df5d5782bf5568074836ee87342273d2c9d6", - "sha256": "5f11b6194292fecebea4ee1679c3ff8733d6111175f12a8abfe6b86b8dda55fc", - "size": 1573097 - }, - "408": { - "releaseTime": "2012-11-29T05:08:18", - "sha1": "3559c418690e0634bf2ef375d4356304f227620e", - "sha256": "be355580f79b976008c60abc11a1aedfe34b5409d852b6ab92e87f3c677a4e9a", - "size": 1573136 - }, - "409": { - "releaseTime": "2012-11-30T21:26:38", - "sha1": "632e8c6c84fcc6abe47cebff567a772c55ef6ab8", - "sha256": "4f52fef86901c8f1df14cdd1c388f0466f86c010fddae94f3b1f1b4bf5ba217e", - "size": 1573285 - }, - "41": { - "releaseTime": "2012-03-08T22:37:54", - "sha1": "464bda507ea2b70a27a168dceb26511fab3e97d3", - "sha256": "46df091f2436c079a881de6a7cfb8dafe8e79872bcedc21e4a6fe88ede672141", - "size": 499564 - }, - "410": { - "releaseTime": "2012-12-01T23:01:20", - "sha1": "a771d3f3823f2698477fcf09e695bfe2b85dab43", - "sha256": "243382beb46dc0092604dfba1ed518e0beeaca26d36287524646360428e596da", - "size": 1574333 - }, - "411": { - "releaseTime": "2012-12-02T20:10:38", - "sha1": "a07de9f69faf2403a0020cf02434b73ff661e19c", - "sha256": "d80d56f8a6c1d2064763fc9c073f07471e3c8d168784fa75f324b0aea8b979cd", - "size": 1574484 - }, - "413": { - "releaseTime": "2012-12-05T03:55:42", - "sha1": "b8c267d5e9490a08fa4200180a89f2dd6c0da65c", - "sha256": "a0dc646aafc7230d7257dfe5340c26d6dd960155b01a7663800d35fdd1c40808", - "size": 1574140 - }, - "414": { - "releaseTime": "2012-12-05T20:15:24", - "sha1": "6716fb10e4c917036f213b566031097b54c2a73c", - "sha256": "922da5ea5571d02c55d26e438ad8cb06642bc55c668e2bfc4929e8dead7a0066", - "size": 1573934 - }, - "416": { - "releaseTime": "2012-12-05T21:06:12", - "sha1": "4294dd76051274853c92390277f0ee6a449d4ee3", - "sha256": "9786265a6ffd025fa31dfc87d3f9d3d5f3740c670426bea6542b9170c41379c6", - "size": 1574377 - }, - "424": { - "releaseTime": "2012-12-06T07:18:32", - "sha1": "3086e9a8484bad60e86dc0493efaf578b6a56dd0", - "sha256": "fb709c1dc458ecfb06870da123c0ec1d59dca5578ad215d3a9dff4ec14fc3a8b", - "size": 1576166 - }, - "425": { - "releaseTime": "2012-12-06T14:19:06", - "sha1": "4fccda18239a1876f3d62f5c965d60b82dc91468", - "sha256": "7bb5e4b9c1aed20331b78635f15a2e801865490a1e5fa6f6a8f537349e39d700", - "size": 1576317 - }, - "426": { - "releaseTime": "2012-12-07T12:29:54", - "sha1": "8026a34475e6872234ac979b6a2c8099d423b7ea", - "sha256": "2938e6d0aa31b4e681815592f90ea49b433617be15cb4e50a4087c94c55e0dfe", - "size": 1576395 - }, - "428": { - "releaseTime": "2012-12-07T14:25:52", - "sha1": "4c352824ffec9ed14461d582f7329132a1c8df14", - "sha256": "e82d4cc3bb08a8dbe2d88bb4a9edf71350065861de4a19c72f74be949fab3c71", - "size": 1576422 - }, - "430": { - "releaseTime": "2012-12-07T14:46:08", - "sha1": "cf80d6a0ee80b8906c495eeea1def139a40a4987", - "sha256": "b86373c66c61b79b7f9e87be9ad1da33eef18dff6726f496d815e37adbb237bf", - "size": 1576422 - }, - "432": { - "releaseTime": "2012-12-09T15:13:24", - "sha1": "70b8b82c7ed7ec46c98db96762949e2671ba920e", - "sha256": "6d6539b0c4cdb5b342b4cbd68da0a3e6059fcac7ee6d3199efbfb307fb54a284", - "size": 1576278 - }, - "433": { - "releaseTime": "2012-12-09T15:19:16", - "sha1": "27f1997fc815e04b0f56f0015b078bf2c84fa7ec", - "sha256": "59271f90f8a6071fac3b934493c08524ecab56c8679b666ca242644482fd6fe4", - "size": 1576330 - }, - "434": { - "releaseTime": "2012-12-09T19:48:28", - "sha1": "8748888abd3d3c2adcf4d4313414c6295ec3e706", - "sha256": "0395f5aca0707016c9ec6a4e237ccdb5346b73c72f9e653934c29e6ad2f893fa", - "size": 1576349 - }, - "435": { - "releaseTime": "2012-12-09T20:01:56", - "sha1": "a1b84b450226f355d8dec28a3e8c1103cd9b37af", - "sha256": "bbb10267af0fcfadb9c5d7e1fe843394c4fe301eef0ef41068d31ead86dfb9a5", - "size": 1576377 - }, - "436": { - "releaseTime": "2012-12-10T16:59:08", - "sha1": "8c4b90d40e9793c3252c3f88c730422fb64669a9", - "sha256": "2073d3ab32a6aaa868b96d3980157c23952f78c8b6ec593e44dc57cf34660a8d", - "size": 1590738 - }, - "437": { - "releaseTime": "2012-12-11T22:46:36", - "sha1": "832c44b5e1c6e85d35ed566e4f123ed67e4b9778", - "sha256": "6cceba7d45ad61c1bc5c9bfbcdae0d24f2c268c2417724ccc701c5c7c8167a42", - "size": 1590956 - }, - "438": { - "releaseTime": "2012-12-12T03:55:14", - "sha1": "24c3852556e4a2172bd37de1cad18d4243a0b308", - "sha256": "f7a3057bdee5d5e48d1dd4231e53fb94e7fc6d679cbd6912b908e5a92baacd28", - "size": 1592071 - }, - "439": { - "releaseTime": "2012-12-12T15:35:04", - "sha1": "380e5ed60de266795ef3dee3c936621141cf0186", - "sha256": "e4ecef94ad2362bbbf3698603eb8a8326e6593b37561c68af568c5019eb57006", - "size": 1592612 - }, - "44": { - "releaseTime": "2012-03-09T14:31:00", - "sha1": "b52292f98704566d55ed5fbd4dc0405d8edb6e0b", - "sha256": "4d87f84695eec54608719f0eaaadb9cab0d552d73df6d3feab69a7ef3bfa512e", - "size": 499566 - }, - "441": { - "releaseTime": "2012-12-12T18:22:44", - "sha1": "bae8c4e99b9e2c0617550db52ad8eecc06ba2f6d", - "sha256": "6f6410d465f289369450fdcf3742f1f0c905272cdac58b6fee8f079dc54a41f6", - "size": 1593778 - }, - "442": { - "releaseTime": "2012-12-12T19:17:38", - "sha1": "a542808264f7a5f0d915c33e2cc3f2142f1fcc0b", - "sha256": "b2439f523dfcb813856fc862a4a3a1e6f8f6d803694b80f2a1da395982f0650c", - "size": 1660053 - }, - "443": { - "releaseTime": "2012-12-12T19:38:34", - "sha1": "ac0e17501a2925505c2e1ffa44a0f8eee0b9b845", - "sha256": "ccbc7994ab79325e5b591911f747e7ec58083f01794f3c865aee60e9d51ae2da", - "size": 1660189 - }, - "444": { - "releaseTime": "2012-12-13T00:54:08", - "sha1": "a1451b128695094b6b5cca335449e1d620de06fb", - "sha256": "ad3040529aa031dd3bc1fa6cbfe7d8f315205ba9c5df8a06bb6a3bbdd474c26e", - "size": 1669622 - }, - "445": { - "releaseTime": "2012-12-13T01:37:06", - "sha1": "b034cbad3f93b4dc7da0d1afbbe8541d53ab98a5", - "sha256": "c4ae11bc38717108e01dca4ca64f8649c64dbf471016c89859baa126421f1e21", - "size": 1669620 - }, - "446": { - "releaseTime": "2012-12-16T19:08:40", - "sha1": "21b69f42306a5a27cadfe6d80c334e0733ab52ac", - "sha256": "efcd28ce76ec40846e291476a3e9155cad3edbd838a40ff4a4f3074deb2d7ea8", - "size": 1669607 - }, - "447": { - "releaseTime": "2012-12-16T21:13:04", - "sha1": "8ea8676eff9c3c27cc98c1a713ef58e65744e765", - "sha256": "7e08e0f7b54d67f6f26c35336a629f724455856822441507649224689d28ec98", - "size": 1670780 - }, - "448": { - "releaseTime": "2012-12-17T09:01:44", - "sha1": "13a9f80d41adf293179a39e5b6a484871d14ac44", - "sha256": "0189e4a7f4a9c41924f2a52fffad0e40657b5442743ee4e4f43098d72adf25e8", - "size": 1670806 - }, - "45": { - "releaseTime": "2012-03-09T17:26:54", - "sha1": "801c29b3682f1af358166a262ff882085709e050", - "sha256": "025d932795079e1f305cdbcad4e2144334ccc91f1d028b619d71ef844e29373a", - "size": 499542 - }, - "451": { - "releaseTime": "2012-12-18T01:35:54", - "sha1": "421993ef8f69c3a9409eb4d5ed7fc2c425066c9b", - "sha256": "c9e195b010bd0e1c721e58270e7d3cb6beb5ceb18e95be60a5a04fccc19eb3f4", - "size": 1726000 - }, - "452": { - "releaseTime": "2012-12-18T06:33:42", - "sha1": "2a2c3d7656179a3576c68ef05593241cab30dc89", - "sha256": "894c384a989e22d644708a18dd4b2873c2d8d1a344a46fa268efb8453d6907a2", - "size": 1726210 - }, - "453": { - "releaseTime": "2012-12-18T07:25:04", - "sha1": "4efb68e5ba7e83f30e69e4e6417d937140a37843", - "sha256": "36c23bb5e8c524e4633b17feac709f499c7d4d44178f4fcfcf1e75a9f7034792", - "size": 1726167 - }, - "454": { - "releaseTime": "2012-12-18T07:59:58", - "sha1": "6a37494bc27f2a931ad7a55071d799b0c14d322e", - "sha256": "f52e50343683b49c102f25a595cb9298bf38d6bbb431d66b2d25edbb68f41875", - "size": 1726248 - }, - "455": { - "releaseTime": "2012-12-18T09:05:42", - "sha1": "a6769078d9dbeda08be78d1ff98e8398948db030", - "sha256": "fba9f76b198b90acff4b1e73ff313d13c6b7282aa40baf9b782bad7d65f8380e", - "size": 1726503 - }, - "456": { - "releaseTime": "2012-12-18T11:37:00", - "sha1": "0a04ca649837a9254daa96691d51011bb25da139", - "sha256": "b68b9b26db586479608c0b76054e345832d4e697933662664b7d26edfb9183a9", - "size": 1726508 - }, - "457": { - "releaseTime": "2012-12-18T12:23:28", - "sha1": "32815602e585fa49d469911f7afbc9477af3dd14", - "sha256": "f8ddcaacf7b1eec6d564608fd3a127e71ad50430fe00a9a689aea25ba9798d44", - "size": 1727433 - }, - "458": { - "releaseTime": "2012-12-18T15:13:42", - "sha1": "41ad6776ef46795e9d3fb219f0cc70deacc322fd", - "sha256": "47964bd168713ec45d60d0909ac004970d01acabb5f117d93bb67e2c36970064", - "size": 1727457 - }, - "459": { - "releaseTime": "2012-12-18T16:06:36", - "sha1": "a75f08410a16f34504503464fac3585d1cef9dad", - "sha256": "f05ca5f2e4e507cf1e9d117dfaf7f06a0c96cbb2ced0de2ad99b16421dae945b", - "size": 1727472 - }, - "46": { - "releaseTime": "2012-03-09T19:00:00", - "sha1": "249650d67d67be25f72835ab5ef7524f488f1804", - "sha256": "7c1b57a1e1297aa0766bd3a52dbe18f5d38d17e013622af681a11e3e8958014a", - "size": 499542 - }, - "460": { - "releaseTime": "2012-12-18T16:45:26", - "sha1": "82d3f2945980277af4e5562283b46d5c99c33192", - "sha256": "01c47f5cc5326ba08b1372abde90598e8fc47b557fe737f04db021f0607a5972", - "size": 1727478 - }, - "461": { - "releaseTime": "2012-12-18T20:15:42", - "sha1": "736ea6a5de8a8631f179958c727af63cde2534c3", - "sha256": "e772575ec613c557ed7e83e1fb55c855d9cc0cc3396636287e1609c63a78977f", - "size": 1733216 - }, - "462": { - "releaseTime": "2012-12-18T20:22:02", - "sha1": "c5870d3b28063d0e2c2e1320d47d1cd883953d27", - "sha256": "29b5e43ac1ebf8572cf8a426c51fc8eac132ebe62937b8297bb6a0bebe6495ed", - "size": 1733220 - }, - "463": { - "releaseTime": "2012-12-19T14:47:42", - "sha1": "8964d7dbdf6db684371b79f31f2708daf26a3d65", - "sha256": "61d212a885d5d9903fa3653246e492ad243afb191353c74fc5cf3e4ae02649cb", - "size": 1733227 - }, - "464": { - "releaseTime": "2012-12-20T06:29:08", - "sha1": "8f3649a5743184c0b1b09653749cff1aa2a817d3", - "sha256": "14206ed1f73ba0b305637a0870ef70ac7ad52d3b44961effca54ec36dc065753", - "size": 1733293 - }, - "465": { - "releaseTime": "2012-12-20T06:55:52", - "sha1": "2f8b54e20bd0968be3e54e2d6a160f325acd6b11", - "sha256": "e26f8e433197a05ec0e7e8d663bd0ed8ffba274c9c462af727275ea03f5e067f", - "size": 1733394 - }, - "466": { - "releaseTime": "2012-12-20T08:55:54", - "sha1": "a3aadc9017870b125e86aa174151f2f8e6c4bad0", - "sha256": "29ccb3022faad84e868df4d7106699c4ec04cc2aa042dc7e77a105e632d5ba6d", - "size": 1733369 - }, - "467": { - "releaseTime": "2012-12-20T16:07:14", - "sha1": "ebfb8b5a38998ac3d15a49ac421270399a35e9e6", - "sha256": "a8a1ea57487d9074247eacf61cf12ea62ff1de07e6bbe10a87492a54da4495a5", - "size": 1733972 - }, - "468": { - "releaseTime": "2012-12-20T19:45:14", - "sha1": "872cad36bf9fbd8b570c8839786665476d3d37e8", - "sha256": "4f1a56fc643c96fed83187c4c9caebd7c7ecd1e1abeae8eb2c4f20e04f341c39", - "size": 1734950 - }, - "469": { - "releaseTime": "2012-12-20T23:53:48", - "sha1": "7426aac26d35e178b3d2663b4d506a82d00a3f85", - "sha256": "7bfc916af6e0754c2cb8fa7775e22883af8766d1586d1214b9f88f0c47c5d237", - "size": 1734950 - }, - "47": { - "releaseTime": "2012-03-10T17:12:54", - "sha1": "658451d143a3e9acbfdb405bbb7e6a9d0cfd6bea", - "sha256": "201c8e614888d675355a780ba7e14ee630bc199b6ad5a7d0e4dae18f85236e01", - "size": 499538 - }, - "470": { - "releaseTime": "2012-12-21T01:20:06", - "sha1": "9df25c7d137cac8bb6f01fa947fa6f7cb1ed5730", - "sha256": "dc7585b24d6c54025f373908af901f63b2d460832c036ad4ee68f410b4c5cb6a", - "size": 1735047 - }, - "471": { - "releaseTime": "2012-12-21T07:29:44", - "sha1": "4efb1b18519a23f5c00f9067f2391b6d08d3a5f0", - "sha256": "090c3a55b08e8ad91b9b77cb85a53234687c9a94259557dbb723966cccb8cdb4", - "size": 1734974 - }, - "472": { - "releaseTime": "2012-12-21T13:51:46", - "sha1": "e6e08713a05d0848b69de728aee4657f3a3c5efe", - "sha256": "11d7bd50322b63c8dadb6b6b0b3b57c0e077fd1a62d08f18c4141466598e49ff", - "size": 1737294 - }, - "473": { - "releaseTime": "2012-12-22T05:13:46", - "sha1": "5c729491f944ae248bbbbfa4c3538ab55d8e3ad3", - "sha256": "45f164a5433be75743a271aa7ddd2489d2c2acaa11b39edd687c2c319ee22969", - "size": 1744124 - }, - "474": { - "releaseTime": "2012-12-23T13:37:12", - "sha1": "999bbcd15fa79c272a733b0cf66cbb894a1b3f68", - "sha256": "953721125acc90d1ba8e1092508b9dc844956a412d47c4448ce5150a5aca8c7d", - "size": 1744238 - }, - "475": { - "releaseTime": "2012-12-23T22:54:44", - "sha1": "3a1f3803a43b2e7c506a344b88c7832c808462ab", - "sha256": "3c18c13011d4274e56353e4ba04c1295e7a0d41f4f5dd2bb779df8ddea566862", - "size": 1741653 - }, - "476": { - "releaseTime": "2012-12-24T00:34:20", - "sha1": "2daa310149da3edcbb7d08faa58760a21c26a8c5", - "sha256": "9e7e4d1cbdc912c31c114e129217ddf97346e0be91fbf82c3ea5cc5832a800d8", - "size": 1741664 - }, - "477": { - "releaseTime": "2012-12-24T00:40:32", - "sha1": "bba7b620d135e62ff4158ab41252bcf9174b4110", - "sha256": "34f421c1a173ae1afe7cad37eb326560919c176e3b67031b698546e9707c40f8", - "size": 1744371 - }, - "478": { - "releaseTime": "2012-12-24T02:33:06", - "sha1": "e9a4f006c0bb89e12c6653d336441746e10ec0e1", - "sha256": "7ae27b002491dea6ce4563582a52da6c559a17896af281ad2a87e9dd6b87e72b", - "size": 1744491 - }, - "479": { - "releaseTime": "2012-12-24T02:42:26", - "sha1": "48678d934b09e484b66cdedd5ea02e8a34891418", - "sha256": "5ccd19915392c33809f26334f2bbc8c0c40dfcd221abea01f56efaaa00f83df1", - "size": 1744492 - }, - "48": { - "releaseTime": "2012-03-12T12:23:28", - "sha1": "9c64c3b621f2d2d3e0b9a45aeeb0c81e6994508f", - "sha256": "3cebc5d52ea6595868522a3643cb1b75067e86b6831ba69056aa0dae6ab202b1", - "size": 499538 - }, - "480": { - "releaseTime": "2012-12-24T02:58:50", - "sha1": "3d760ec785b329dc04fa59342b381dd357336811", - "sha256": "d06834960396f393714a92afcdad10a53ae774d086d6b03139e057905d28124f", - "size": 1744429 - }, - "481": { - "releaseTime": "2012-12-24T10:18:58", - "sha1": "1ff2196efd74a559216860a70b85f09e3e63de9d", - "sha256": "73dcf5b3f1744c61a43c0f9c676b3092dc1167687f3870ec8e49ed8e4c2692b4", - "size": 1745086 - }, - "482": { - "releaseTime": "2012-12-25T17:20:24", - "sha1": "699a44e90e186283858c06c26ae61591c0930ccf", - "sha256": "477e063f1ad9bd5bb82e373bd592d834d4379283f58e3c3add051c5381adcea5", - "size": 1745156 - }, - "483": { - "releaseTime": "2012-12-25T20:16:10", - "sha1": "3058f414ed26f7a17716dbfc714059634814af7a", - "sha256": "63ed21d141b96509b487741a9ee8b8eb91c5ae107737f813bc56037cd8a51920", - "size": 1745409 - }, - "484": { - "releaseTime": "2012-12-25T23:08:44", - "sha1": "22917af8817870ec59c31b47f444e3f3775f8dcf", - "sha256": "36be7238426914c4d6146d58c1961070d49cf69fb6ca5077fdd0f094e56dd36e", - "size": 1745586 - }, - "486": { - "releaseTime": "2012-12-25T23:32:22", - "sha1": "da305a3cea5057bf8ba153fd066631c11b05addc", - "sha256": "483741ff2cac45c6e4a18784b3940420af399598c4efd467dc73b9235dc891d3", - "size": 1745580 - }, - "487": { - "releaseTime": "2012-12-27T14:56:32", - "sha1": "610de83860eec1991f86c9965a76f87b89b08d12", - "sha256": "ff4b78cb32de1a57e7beb6fe6134033cce0defa90272dbc449745f224ad821a8", - "size": 1745542 - }, - "488": { - "releaseTime": "2012-12-27T21:24:56", - "sha1": "473485ee42c5a18ab47994bceff362da0a1bea55", - "sha256": "01f13df19856643460dc7cf95c57769ff34f1413187c6f88b858f43be28bb55e", - "size": 1745935 - }, - "489": { - "releaseTime": "2012-12-27T23:17:08", - "sha1": "ad4b1579edf9053d7c213fadcb7d10538c88a1ac", - "sha256": "241c88f0eec5b75d49a6a9561ef8af6dbe1caa3dac7977141fdc60fade59e758", - "size": 1745975 - }, - "490": { - "releaseTime": "2012-12-28T10:15:24", - "sha1": "12af97cacd54e55593e5879d5c214abe6ddd898c", - "sha256": "07ae2b7d06ef4c80c7d19e7bddf3ea610257f8989cd87016f6fc5135b49c9a57", - "size": 1745974 - }, - "491": { - "releaseTime": "2012-12-28T22:36:56", - "sha1": "5ab9a4f78adfb6b345bbca0cf8c92effee616f67", - "sha256": "17ddd3251dad9359d624fa5cd2e198561cafaa341ceb37c37a57f83f3ffbd66c", - "size": 1746029 - }, - "492": { - "releaseTime": "2012-12-30T21:03:42", - "sha1": "24dc432e3d6a7c1ff28900cfab9c7168c6e51530", - "sha256": "585981eac33151616981789662507f1019072c9891da48880e5ed48300d62e5f", - "size": 1746383 - }, - "493": { - "releaseTime": "2012-12-30T21:30:20", - "sha1": "01cf4d59115b3bf2b8cbe2e54d6703200016d2ec", - "sha256": "faef915c0307bfafb20f21db5e606a155470381e98c53f8de0f3748c859ab150", - "size": 1746349 - }, - "494": { - "releaseTime": "2012-12-30T22:09:10", - "sha1": "06b2c1905ca8de001b823b0f397d21b4b8c45dfd", - "sha256": "91d5fe316e253992c5c6b7be88e8f353bce4cbe8958a314a4c6242c6e5581828", - "size": 1747746 - }, - "495": { - "releaseTime": "2012-12-31T09:26:20", - "sha1": "90b567013a6cd3abd28f6acef8da13be80139309", - "sha256": "367de6a4bc90ad1cbf1fa4503cef59da1b00f46e9ae98c54dbca50d9a6a3039a", - "size": 1747783 - }, - "496": { - "releaseTime": "2013-01-01T22:02:56", - "sha1": "ec5da86e1eb98345401f289a677e22d9ff39b677", - "sha256": "036cfa78ffdced3f8d1e9d07a9a4cad8bfe6106ee6a2f323e0f46f7bb75cdb59", - "size": 1747767 - }, - "497": { - "releaseTime": "2013-01-01T23:23:56", - "sha1": "6734cd7a2de6fec77c0745a4fd054f56547f1b45", - "sha256": "b46dee407c06cf73bacd12a7d2ae3be48b6745f2b160c5d3853fe0c9d94914cb", - "size": 1750532 - }, - "499": { - "releaseTime": "2013-01-12T21:48:34", - "sha1": "3853b9b6c90063764d9cbcb7ff95c2bfbc2e40d3", - "sha256": "4afccd945b9536a3432136086b32e2383505bfe595a5a1e446eae032bdd98f8d", - "size": 1750887 - }, - "5": { - "releaseTime": "2012-02-10T04:05:56", - "sha1": "14c5933f019a36c72ac21447223922d225d8ca12", - "sha256": "65d74f1abb6bb748cc42f8e959974e768bcf4acc828122abf37b2c2cf8f3922b", - "size": 418025 - }, - "50": { - "releaseTime": "2012-03-12T17:00:18", - "sha1": "493cacd2e0fd442d22bf602ee630f662a94a09e9", - "sha256": "1e0b71714d6b755bb8b88833774ccf512119e4011f176921343bed43772bf0e2", - "size": 499533 - }, - "501": { - "releaseTime": "2013-01-20T09:04:36", - "sha1": "71e3564d1dd45c032f863f91ced3c5e0b31adb97", - "sha256": "f1152a34c0cfd6197a51e2ab11e0e9d792335d44334c7d4fd76b895d6d9bd5c4", - "size": 1751447 - }, - "502": { - "releaseTime": "2013-01-20T09:47:06", - "sha1": "9b5f5d1bde50cf315c59ac505b344598d31503ae", - "sha256": "f2fbe43bf2931d1c9ad60e44186c9246d3d62ed83b571faafb2662a4b5ad3ca3", - "size": 1751313 - }, - "503": { - "releaseTime": "2013-01-20T13:28:28", - "sha1": "2862ddfb1247e3fa63feaf75bb6eb89619641555", - "sha256": "4c7f9472f6ed96859baaa602f5d93a033066e6e584245bae85d44b884cd1c016", - "size": 1753210 - }, - "504": { - "releaseTime": "2013-01-20T16:53:24", - "sha1": "207a042ae365d8c57c8edca3116ade1b04ed558b", - "sha256": "eb99b88ceaf65b6090c5d1d2d8ebbacd17f363988ebef764639e038f5cde1f03", - "size": 1755376 - }, - "505": { - "releaseTime": "2013-01-21T20:03:18", - "sha1": "039029b9d3c5bca4459a2133d48488763b435391", - "sha256": "f2e15042fa418e6ac9380399a755739a4f9f8145e9f6d616516d5c0e6a594e87", - "size": 1755366 - }, - "506": { - "releaseTime": "2013-01-22T08:14:22", - "sha1": "5f3d3cba6c563334f585a0d3f2d1c1d3bfb673f5", - "sha256": "e36aa8cf1dd69e504ed58caabf140b804a172288b58b4dc343551f5d8d20af01", - "size": 1757249 - }, - "507": { - "releaseTime": "2013-01-22T11:59:02", - "sha1": "df4a34e476f7ee94a435ef8f26513b926afa770d", - "sha256": "3a2c6b8904c605c028465e4e64e71e0cb24121c705a7f271909b56b254af2de7", - "size": 1757663 - }, - "509": { - "releaseTime": "2013-01-23T21:44:32", - "sha1": "e7d8ea9367667e29a6fe3e0b56b888e34a7c6c2b", - "sha256": "6351f2bebfa1f5255f8310c06c274bcdc42ede5e262674bf7df7ef00c1a5b3ae", - "size": 1757812 - }, - "51": { - "releaseTime": "2012-03-14T11:57:34", - "sha1": "19428f0e666c4050a5f0d6ba066471fdd10a4e95", - "sha256": "b09b008c025b1a8ea35821c653fbb16aeb74a2b68a0113d5d46012c8fcd0d169", - "size": 499534 - }, - "510": { - "releaseTime": "2013-01-25T19:25:36", - "sha1": "bdbb8003de83e6c136e1ce523c12de6109726e54", - "sha256": "0b20a127a2d61edeec71ee1baba52aa92a35d82880e6c660c47cf750d0d83b32", - "size": 1758064 - }, - "511": { - "releaseTime": "2013-01-26T08:29:26", - "sha1": "37e54676fe4db1dc8cfb2b56f3d5344024aca44d", - "sha256": "06a0d1ebdb10344a1949d03cac65f73e88e59f364b4de7728dedf5e8e749221e", - "size": 1758076 - }, - "515": { - "releaseTime": "2013-01-26T12:16:40", - "sha1": "d09d5267e419bc6f35e065789eb87780bc69c767", - "sha256": "15a1c1b749c840e55ca27a2bef419f710d334351284b20526c3caab6730bfde4", - "size": 1758042 - }, - "516": { - "releaseTime": "2013-01-27T08:49:18", - "sha1": "c02c0f5e08e7c975b9b7685fb43ee41f992386c7", - "sha256": "6a7c899130ba3be06f421df8b5874f5347d28944ac2304ac321f8553345797a9", - "size": 1758848 - }, - "517": { - "releaseTime": "2013-01-28T19:23:52", - "sha1": "85730f2eab50431f06074f56fd45ac52f35e7888", - "sha256": "bdba524fdafb87e57b8c8e1beff2ae2d577a16518092198c49f4201fb8851539", - "size": 1761462 - }, - "518": { - "releaseTime": "2013-01-29T04:17:02", - "sha1": "2cd88ccf1af60465380efec07e0a3cef13f4c922", - "sha256": "05736dd9d54e6a92298a1e945da8319d88e0949bb4088b23c0575e87c0a5fa4f", - "size": 1761405 - }, - "52": { - "releaseTime": "2012-03-14T16:56:06", - "sha1": "a7a92d24b575d901506285511817bce22302bedf", - "sha256": "58dcce37e0a45cbbc79ce0efa5f19fb1f0cce4fed70fa1e34061c37c949bb32f", - "size": 500306 - }, - "521": { - "releaseTime": "2013-02-04T09:25:46", - "sha1": "087bdb006cd96f6ba343901cb49b62f10c3c1bcf", - "sha256": "648a9d61659d83d49e0f054913bd945b0d78493e5b3f939c71725e48fbd2b435", - "size": 1769480 - }, - "522": { - "releaseTime": "2013-02-04T12:03:06", - "sha1": "386872fe1744a35dec7e0311335977d9595bf2a7", - "sha256": "6550ed6b0828e93525b3186f7de2e90cf865c37fb308d9e48bad7d96ef91dcc6", - "size": 1769519 - }, - "523": { - "releaseTime": "2013-02-04T15:58:18", - "sha1": "cfe19e7ac7c15b6be821d5af5fd75beac7f1914f", - "sha256": "c8426060eb8bee5020afb0fbf029a4a2f45d2db8a6293d93d8e82cf73f144d8d", - "size": 1769094 - }, - "524": { - "releaseTime": "2013-02-06T18:36:06", - "sha1": "d86aded1f0e1cf6e6fac264be9ac3d26c1b0700f", - "sha256": "92a1c6faa1770fb2c785619834832e3a5825177206afa91d4c55a1b01d6a9622", - "size": 1769480 - }, - "527": { - "releaseTime": "2013-02-15T06:39:20", - "sha1": "6fbf800c40a7ae21cafd5355a7b8b4d8b46bf95f", - "sha256": "5dff0742023186542bdabd8019bbe58b8741328c9f88399fc4d808663781ae41", - "size": 1770314 - }, - "528": { - "releaseTime": "2013-02-22T16:12:28", - "sha1": "c81b6fbba954448137846b9b920203c7260a070c", - "sha256": "48e4bee76f2106ff36adc225c699f28d4ab7c72f420f3c3f97be5fbbb98dd38c", - "size": 1770590 - }, - "529": { - "releaseTime": "2013-02-23T12:27:12", - "sha1": "275c135f5f0617b6f5ace20d7a00f0668697d770", - "sha256": "216cce520e834f6e6239fbd0f3d5eb06344870d575115b680cbd1433814fda45", - "size": 1770653 - }, - "530": { - "releaseTime": "2013-02-23T13:23:34", - "sha1": "04a7307ba922860718b4700ca6c7858d24148f98", - "sha256": "675b7e15378c3b69483208065edace129ed313a4104c0e9a420241ac8a0e45da", - "size": 1771375 - }, - "531": { - "releaseTime": "2013-02-23T14:11:28", - "sha1": "932b3ced33034df13662f18994afaff9900c385c", - "sha256": "98fb1a46e54611e4829bf3c1434e44f4234949fc059fee564db78bc620e808c0", - "size": 1777234 - }, - "532": { - "releaseTime": "2013-02-23T15:00:26", - "sha1": "bcac19ccf60bfd4b13f6f20dab638c58cc043146", - "sha256": "36c55d2d17ac830fba3de5594b7f38c686a5f54933f0ea08aaeb9f95319c2d36", - "size": 1778535 - }, - "533": { - "releaseTime": "2013-02-23T15:25:20", - "sha1": "c3886f37a70edf593fd643db522afa1d1cbd9137", - "sha256": "3408ff09133b41cb2b3e7a667c9cbc79a4b201f30f98b889fffea8af55ce1f8b", - "size": 1778541 - }, - "534": { - "releaseTime": "2013-02-25T00:00:20", - "sha1": "bd0f40a78c18140265ff042a96d73f01c4f60906", - "sha256": "7ae860d3f7423b97b1fb5343a65fcc6866242fde23e1aa00c113dd9b61fa8187", - "size": 1778669 - }, - "55": { - "releaseTime": "2012-03-17T19:58:18", - "sha1": "4a921565b941fd8883513b79d27767622fd7440b", - "sha256": "d5baa47e296c2f18b2b69f5acf525bb3635bb728ba5c0e278c58fe71057d809b", - "size": 500341 - }, - "559": { - "releaseTime": "2013-03-09T10:59:20", - "sha1": "7cefe2301914b7859cd8282630a9a17f6c27d433", - "sha256": "7d7ab7709fbd637a51250aa2d8ee9a2eb6c6f62843d089bd90aed6b3a7ee71eb", - "size": 1799274 - }, - "56": { - "releaseTime": "2012-03-18T23:43:50", - "sha1": "21181f018ad9aad7bb173126fee729b3fb1bf51c", - "sha256": "7a64787f1c09dddbe48a3f61b283e3b2fa82b832b6a329561f45904a94547102", - "size": 500331 - }, - "560": { - "releaseTime": "2013-03-09T11:16:06", - "sha1": "513348c4938d80fcac62b8fcbfbf802671fb374c", - "sha256": "a0a3967f4371154520b5904630f51cb6eefd489c2df6aa6a5ada21f82df6c7a4", - "size": 1801695 - }, - "561": { - "releaseTime": "2013-03-09T12:20:34", - "sha1": "b64dbb4a6e5721354070ed43cc8e565f004f983c", - "sha256": "9f6a313add3dc0035bca35e227701b10df8bc3de48765c519c0ab8c324bdef6b", - "size": 1801871 - }, - "562": { - "releaseTime": "2013-03-09T13:02:44", - "sha1": "753e3a080941052cccd7375df5f63564a86b7fc3", - "sha256": "a3a65288216568e04c1195dc232fd469d0cf40a1ea65c085f5c4499076d72fc6", - "size": 1801898 - }, - "563": { - "releaseTime": "2013-03-09T13:35:42", - "sha1": "a3ac851d0aa5cd19b4f5015cf9cc1f0ccad1c3ea", - "sha256": "f3434b432994d59c16f3a73a432211a1a8064df619970f765e1d30541c0bf985", - "size": 1801948 - }, - "565": { - "releaseTime": "2013-03-09T16:04:34", - "sha1": "cccb6bf2733a4cda8b05d4a9176ab15deaa29b25", - "sha256": "0c5d591dba0d5a7589a953cb0c6e14b2a2b2f245f110f1afec909ad41bcad81c", - "size": 1802067 - }, - "566": { - "releaseTime": "2013-03-10T10:19:34", - "sha1": "471051946714e5a831d608d40f34ad09a0e81da3", - "sha256": "1c7fee319ec0bf88ad77c7ceb8f6d38095d8af9009bccdade5de1ad07ab9da69", - "size": 1802209 - }, - "567": { - "releaseTime": "2013-03-11T14:42:34", - "sha1": "85d19c0406314b6a1c931b905c8abd991342af53", - "sha256": "ea006ce61b4585283237e27995a3d5486fa26e4b0c221716ae9f320f6e2f6f4c", - "size": 1802207 - }, - "568": { - "releaseTime": "2013-03-11T15:48:22", - "sha1": "d49f2abbf3d4471d8039707e80df85d4f1a858dc", - "sha256": "e3759b326137fc5426dbc4f5606781641ed0f93266671fa653911a11cf7db770", - "size": 1802260 - }, - "569": { - "releaseTime": "2013-03-11T17:33:56", - "sha1": "895318254c2a15f84c31a4066a0c7e1d013f2bd5", - "sha256": "2ace28caa0c6bb929bf1c360699feeaef299d69ec5590d02a387e7fdfa585d81", - "size": 1802373 - }, - "57": { - "releaseTime": "2012-03-19T10:36:28", - "sha1": "3821f7764661d74ab8b84acd41c3145f595c9dd5", - "sha256": "cfb87dbd958a9cd46e1bd312a10df884f813fa738edd1db34a6a340563c50fa2", - "size": 500324 - }, - "571": { - "releaseTime": "2013-03-12T16:27:20", - "sha1": "256a746fdca6952208588476c8c1a67e214fcb5a", - "sha256": "20e49414075e9c980de3e9889eeb760b33d7696cdfff730bca8e4abd2b17fea3", - "size": 1802132 - }, - "572": { - "releaseTime": "2013-03-12T19:11:22", - "sha1": "5421a1e7613ec0c54dfe29fe78747dd4c3ed4ded", - "sha256": "e3e2cfdeb8f92d0b2961caed878ebfe8e3783a64539b03c016596ac9b90e5384", - "size": 1802718 - }, - "573": { - "releaseTime": "2013-03-12T19:22:56", - "sha1": "c4e36dfe96db003635afd8f5d0dd1ee9c9330b23", - "sha256": "dc403bfc35df2bd0ceaf91d3f33bff1f50e0fa51c01758f46a5bf61765ea543f", - "size": 1802799 - }, - "574": { - "releaseTime": "2013-03-12T19:48:20", - "sha1": "970862c9cbd70b7e31b52426ddd0cf948c9a9ce8", - "sha256": "04a7b09abd5a21eb5d75627d892b4b6971bf12f8dd1267fb902df46c35002bf1", - "size": 1803367 - }, - "575": { - "releaseTime": "2013-03-12T20:50:38", - "sha1": "0e727130e6492c26fcdea9866b91f2af8d0ed9e6", - "sha256": "13a50326c5d78cb3aea9f5fed7f415bc4499e33acb9bd41c7d30fd3e90ea3d17", - "size": 1803644 - }, - "576": { - "releaseTime": "2013-03-13T12:02:16", - "sha1": "88524debaac98b4a7e81713789a33278fe3b1dbb", - "sha256": "09ed456116397421fe20ecda9fd73e252ce953e5c9712f9ba3af5a1b5f7bb662", - "size": 1801710 - }, - "577": { - "releaseTime": "2013-03-13T12:57:32", - "sha1": "ff91a570c54f10922727007f1d89e83f73210d79", - "sha256": "7653623ab8f74478ffdfb422c5d021cc7a18906c96fd356fd90d7b0fef2d5988", - "size": 1801735 - }, - "578": { - "releaseTime": "2013-03-13T13:10:30", - "sha1": "e0cef279c9a067955e9519aaf5c28cb38c9fd45b", - "sha256": "ade4e84a7eaa1f5d5f7f9af945862ce7817f32628b800f9f86973eeb39ef343f", - "size": 1801793 - }, - "579": { - "releaseTime": "2013-03-13T13:22:36", - "sha1": "1249b4843235da3782d98d917c90d309b91bc4ca", - "sha256": "d4d4bb20f765c5c8e16f6ed9d32aa90c35c7f2c0e740b37396568c36a68f6ba6", - "size": 1801812 - }, - "58": { - "releaseTime": "2012-03-19T22:42:46", - "sha1": "9985d536259cebbb8f139f8ce3176b22039270ca", - "sha256": "06e87b5a04c7ff02c481195175d0a198e964285a9aa637e72eda0421c6018a9c", - "size": 501964 - }, - "580": { - "releaseTime": "2013-03-13T13:34:08", - "sha1": "d756a4fa056fb7b2f6768f7d0fe2d912c28b4c8f", - "sha256": "a7dc5fffffa88e4f8d0318ba7a844c63913a127926b9844104085d5450097527", - "size": 1802410 - }, - "581": { - "releaseTime": "2013-03-13T13:45:54", - "sha1": "3b3bed47c3f1779c5d2080310a20cef2474cf7c2", - "sha256": "8d3e539e593ccc4cb25845ef6901e64f309ace1072bfe43676c16afbc5827bf6", - "size": 1802422 - }, - "582": { - "releaseTime": "2013-03-13T14:20:52", - "sha1": "d38d55e839820418b8597a4c20a27926094da29a", - "sha256": "bcad9e4bb77021662a9934d03055a90d373c48e995f6a37ef09f74c984553015", - "size": 1802412 - }, - "583": { - "releaseTime": "2013-03-14T14:06:14", - "sha1": "2cbe8b97154514dbdda74c96118672356596c59c", - "sha256": "e59ec936b65388d4c757dddbe918410ef3628b406993e407d348e31ff1619b57", - "size": 1802447 - }, - "584": { - "releaseTime": "2013-03-15T21:35:12", - "sha1": "cc83161006e3001a0b6abbff6d5866c5997f122e", - "sha256": "cf35a38f6eb00d0b5939ffb6eb749f0bd0bc7efd7a5da129cca94b5bd052964b", - "size": 1802450 - }, - "585": { - "releaseTime": "2013-03-15T22:28:24", - "sha1": "67851281cd6d7300cfa4f6ed40d36ec91b3a93cb", - "sha256": "fe2ee5a25849e6772c37dab140a3025733145872bfc44048d0fa85bbe671d75f", - "size": 1802442 - }, - "586": { - "releaseTime": "2013-03-15T22:42:18", - "sha1": "28a200368e5e57b42b81515c665d547714e75feb", - "sha256": "c94fde4b5256d311b51f9a2b5df88e0f637baf7b600664f9303d43304dfdec8f", - "size": 1802483 - }, - "587": { - "releaseTime": "2013-03-16T11:52:38", - "sha1": "2cf449d932668dc49da5ceec7fd12b0bd0588670", - "sha256": "426c3326e475e5603311db05cf785809b6ea99597cf5fba9edbd718cdeaacb0b", - "size": 1802487 - }, - "588": { - "releaseTime": "2013-03-16T12:35:28", - "sha1": "9fbe0dbdf36173a5c2d873790148c533957af2c1", - "sha256": "c5d033bd0d05fef758c23a6374f1f628fba6c0102d88d0d2dcd2a313c81ec685", - "size": 1802499 - }, - "589": { - "releaseTime": "2013-03-16T13:59:58", - "sha1": "07cb240272a941a01b1314a99e3ea5dcf093a8df", - "sha256": "f23fb37f45c28e246c461fcedd135ce473d0aa3da62141408a759ce164a7c475", - "size": 1802541 - }, - "59": { - "releaseTime": "2012-03-20T06:50:10", - "sha1": "c22cb4824886aa26a95700f38768083cc84a0b70", - "sha256": "b00bdbdae11e16016759850278a79da857b7c19e91762b15b5cef2022834f532", - "size": 503801 - }, - "590": { - "releaseTime": "2013-03-16T23:21:04", - "sha1": "3c5c525447f98d3abeeceab5b68e3318273c25a8", - "sha256": "1f1e552ee329f4fbc9bec71060406dc52375aeaf0f4d25b8b585aa7268670e6e", - "size": 1806206 - }, - "591": { - "releaseTime": "2013-03-17T00:16:14", - "sha1": "75817e473b6f290c881e5de9ff7084c3807247d3", - "sha256": "3e9f5ddaebb29ee4c43f0b54b1859054b43dea5a9c4cc487f0f1706525e33e56", - "size": 1806210 - }, - "592": { - "releaseTime": "2013-03-17T13:11:16", - "sha1": "b6b44424f0c57a36d0b4d2fe38b3ddc837e0bc24", - "sha256": "978578203b4490875b4781511b0ce70f987a5c370c61b597c33aeb8168135f2a", - "size": 1806617 - }, - "593": { - "releaseTime": "2013-03-17T21:15:24", - "sha1": "868f3bd54310b460d99aa4fc948d814904834b6c", - "sha256": "3c05e042f959aa93de758811ba5c4fd6fcf2b1f8f88d014e3e4679f04bec7a33", - "size": 1808804 - }, - "594": { - "releaseTime": "2013-03-18T06:19:08", - "sha1": "05dcca538da1ba41ac5e59e74eb862121cb5be88", - "sha256": "6c6d1fbcdf7d7afd8ba6bdd085517b06c17f19122ed471505c9e87b2e27a7857", - "size": 1810025 - }, - "595": { - "releaseTime": "2013-03-18T15:37:20", - "sha1": "10fe3da7c4f5c5897e7dc1bea826529e9c6cd240", - "sha256": "9f3eee1df41b9de671fbd5ea43537d303be4c86366678b1fc2423ae1072fcb97", - "size": 1810024 - }, - "598": { - "releaseTime": "2013-03-20T19:59:44", - "sha1": "51fa60cdafaa9497465e792d3ec884c2fb411bd1", - "sha256": "ee98f47baa521a317f361ad44d3f62677343a8aa46605a949d8eac2c5a297f3f", - "size": 1810101 - }, - "6": { - "releaseTime": "2012-02-10T07:00:32", - "sha1": "469c7532e6e92ce5be68e850643a2b03b305c9df", - "sha256": "a1c33cb061da2fe86fdb7d46c8744f52b9661832de7422f22e64228eef4b323c", - "size": 421298 - }, - "60": { - "releaseTime": "2012-03-20T22:13:54", - "sha1": "3fb0ca0321285a9b7ec52bfe173ce905c45f6ef5", - "sha256": "c1bec94a7d15a2d761ca132b3191836a9cbc57df1757ac89778494699f45f63b", - "size": 502757 - }, - "600": { - "releaseTime": "2013-03-21T05:58:52", - "sha1": "f100c13093c7cbcc647d01db0e06b033857ecc44", - "sha256": "3490da99bf1a9d02ab3723b806ea4b2544df3ef760f4d3f3716e28d125f617d8", - "size": 1812847 - }, - "601": { - "releaseTime": "2013-03-22T00:00:40", - "sha1": "65b86fdcaf4f0d3ae39f4ef6060df038c0246a4d", - "sha256": "6b828b19a733beb784689c651f31576d49a4828a4bd1ab6d326028f8c75db4e0", - "size": 1812890 - }, - "602": { - "releaseTime": "2013-03-22T07:38:02", - "sha1": "02c4747b8f443a6baabd42808641901c7316d10c", - "sha256": "e992506a04eea308de41e0440acfcc2c5862aa815192864de874511213772ce2", - "size": 1812888 - }, - "603": { - "releaseTime": "2013-03-22T10:43:46", - "sha1": "035a390467f9f8fee7109ed68261b97ba4d3b4df", - "sha256": "87fa43b1060b04aedc0c51896605cb5218abe9286ec8213312e860da86abf782", - "size": 1817618 - }, - "604": { - "releaseTime": "2013-03-22T12:14:54", - "sha1": "d08a3ffc03ebe236906205dad90a172f6170eabe", - "sha256": "b88c74203121c64ec61db3b5c80ba684ce72ed9b81dbe30fe4c965c3a6bde6ca", - "size": 1823680 - }, - "605": { - "releaseTime": "2013-03-22T15:03:40", - "sha1": "4f500cf41d5c988df867232ca366f329b1bd59e7", - "sha256": "1ae4763067a05b6774ae49929f2f003ab239fdd8e8e63bbcb0d7eae2b25af426", - "size": 1823687 - }, - "608": { - "releaseTime": "2013-03-23T21:30:56", - "sha1": "decac58077e666780177384985f01079c4e2bab6", - "sha256": "01db87c37d61ea353d92edf8f97fba8b1cc8100f59e79208b2fd7ed7a57ba01f", - "size": 1841717 - }, - "609": { - "releaseTime": "2013-03-26T12:14:08", - "sha1": "487e2e3d063d55b585d0358822b7b62bd3f457de", - "sha256": "190a33807674e2d0f4d9ba40ecdc11efb99fd42582283d0c5b5ed0598757c57f", - "size": 1841499 - }, - "61": { - "releaseTime": "2012-03-22T20:01:10", - "sha1": "d0ba974da976e9348c3b8497a606d888839034ac", - "sha256": "0074d9e139b79f4f1bddcef86fef87b79c28cfc1fd7caa421a76fd66d8ed6ca9", - "size": 503013 - }, - "610": { - "releaseTime": "2013-03-26T12:32:10", - "sha1": "f19d03346de350b600a1485e3736ea722feec731", - "sha256": "8474514cfc245e9c9c7429552cf09ba80b5ed4a8b4eb04d37c76f9a86fa25d98", - "size": 1841597 - }, - "611": { - "releaseTime": "2013-03-26T21:59:42", - "sha1": "2b5c9e928b14eba5985fdf99141e0b4f36f4919b", - "sha256": "a10a3303eb45fb206fc86dca357cc6414b5de313882f34f5a9d7446e85b5bcd4", - "size": 1841630 - }, - "614": { - "releaseTime": "2013-03-27T17:34:36", - "sha1": "ad15e8ff0469a674421d8b91447543ad5ddae4e5", - "sha256": "f6fdf613e51cee90807544e96acf2b0ee71160fd11e4fb6cce43506254ed4229", - "size": 1842016 - }, - "615": { - "releaseTime": "2013-03-28T06:16:30", - "sha1": "2f846dac453503c38e94a2ec4b1912c4107ad6ea", - "sha256": "46fe09a4b47cfea1314406db10ec52446187bf9d4ee82d891fe445f06057e95a", - "size": 1841842 - }, - "616": { - "releaseTime": "2013-03-28T06:32:18", - "sha1": "e924ed455c1352274bf758b61290c5cddfccf16f", - "sha256": "905002cc9488c0e553b24f602280e672911de6a7d3e8c5d102b9d64c1ebab3bf", - "size": 1841905 - }, - "617": { - "releaseTime": "2013-03-28T15:50:34", - "sha1": "9293a9a74adb8991c6057b3cdfc985276ead3a71", - "sha256": "21ae46fb70a81ca1140a4e499b8971c66d8dfba5d2b37fd47ff4e209fc67d927", - "size": 1841930 - }, - "618": { - "releaseTime": "2013-03-29T10:54:14", - "sha1": "eacfb8930e7426c7aad65db03f1c4d47f9a629b4", - "sha256": "bb60011ad40b9967458f7f94dd38b169487f273f3063b29e6387ec9a101ec913", - "size": 1841693 - }, - "62": { - "releaseTime": "2012-03-25T23:38:34", - "sha1": "4764871665c79041b233e06b62951b6500693007", - "sha256": "0ab4b860362867ca3eb3f18db522a74876f1cbe8d9e9fb50892f8003a21691ca", - "size": 503894 - }, - "620": { - "releaseTime": "2013-03-29T14:30:48", - "sha1": "fba2fc79ab6adbf37543ba7c832ff69dd9e4bca8", - "sha256": "d64106428e99e04b2a8200f8bb1f7a5dd415c5e16e1c244a976eb8ca53bb5a64", - "size": 1842046 - }, - "621": { - "releaseTime": "2013-03-29T19:53:46", - "sha1": "2fd638d07a63d3d266dd1f355a0037d8a121a75f", - "sha256": "89eab9898290cf4361784c3f81ed6be8445483935fee900e5a19f1266ec71095", - "size": 1842165 - }, - "622": { - "releaseTime": "2013-03-30T10:26:26", - "sha1": "aa86d940795a19314a97225bfcfa58ad5f466384", - "sha256": "1716af38d742c935515879897795b4ae6b91066ab2dcafe9db1de1847b3baa44", - "size": 1842514 - }, - "623": { - "releaseTime": "2013-03-31T07:59:12", - "sha1": "8958c9643b16640342f0b63396c6f2cf2072099b", - "sha256": "5c9e09c1c5524db1a5eddb09ff57ff7078cebce970ac266bbc83f5732a73ce43", - "size": 1841475 - }, - "624": { - "releaseTime": "2013-03-31T08:34:44", - "sha1": "20aedfa6e7d255f99adfadf9f345c3ab9aa5a521", - "sha256": "756c0869814858979a866381e09f53565461e7964a86d97ed26602ff4b2a225b", - "size": 1841511 - }, - "625": { - "releaseTime": "2013-04-03T01:01:26", - "sha1": "985c86a6b349d03952897f0b516b4970782ccd97", - "sha256": "feb6b97edd2501de5825624311c90a5a05b23b67a85331d00b04132f7362f5e1", - "size": 1845610 - }, - "627": { - "releaseTime": "2013-04-03T03:17:22", - "sha1": "887556c1ee0c9cec4447ed38a4abf09858266aaa", - "sha256": "a1cfb5ed61fffd2291407da332876db576c5008eb3319c75e35773c50bedbe4c", - "size": 1845607 - }, - "628": { - "releaseTime": "2013-04-03T03:37:02", - "sha1": "686799aaadad7814253190bdb0a1fc7560451178", - "sha256": "3eaac663cc980ac9a4563e239dcbc134f2047cb700230424a5c558e996d9acf9", - "size": 1845673 - }, - "629": { - "releaseTime": "2013-04-03T05:16:26", - "sha1": "d3aa64bfdacbda1048ccaa9f5238f1f541528ad4", - "sha256": "1e356867221fa36ae1e60e4be61eade98675eecb1f92c82b30fe41fd27de7ecc", - "size": 1845744 - }, - "63": { - "releaseTime": "2012-03-26T02:56:50", - "sha1": "4fe8f595c76a6ac45d2243e610222b05f5d5696e", - "sha256": "fc55e2ba6f78afe8ca60dc6d2388e8510ba8262160c6acf11b1ff7b64bea6042", - "size": 503843 - }, - "630": { - "releaseTime": "2013-04-04T17:17:08", - "sha1": "67a728e15c95d5bf0c79c4bd2eb5a6cfe9ede6c0", - "sha256": "c3acf9e87f951770d71e4d4f082424f2c10523e2987d7201adfddfd047bf19d5", - "size": 1846619 - }, - "631": { - "releaseTime": "2013-04-04T18:39:42", - "sha1": "6444644de15fb9780b66a51008124dcc78bf36bb", - "sha256": "737d1307d2585a5ce50384476fc36b8f74e81db48af542737764a16c5c3f1c4c", - "size": 1847007 - }, - "632": { - "releaseTime": "2013-04-04T19:04:58", - "sha1": "315204071999b6f5b71ddc7e146a00462e68f2af", - "sha256": "8961e9275dfde5b55f4503b0ca12fa50dd79295ad7f6eb7edf6deeccfef7c25b", - "size": 1852106 - }, - "633": { - "releaseTime": "2013-04-04T19:22:44", - "sha1": "d52c199a6699a8a5c5192e2024d5f0b08c987a5c", - "sha256": "329ee4d1b752025c123df1511f120a36c76e58d9604558d7420ff9c58f10c2b4", - "size": 1853907 - }, - "634": { - "releaseTime": "2013-04-04T19:45:34", - "sha1": "19d4a565a3a3fa307d1a7691a18f15b7053ec9c3", - "sha256": "ea4473393f4fd4b05d136f09bede7f163cfb3ed349b90385cd9aee308de75a53", - "size": 1862442 - }, - "635": { - "releaseTime": "2013-04-04T20:03:00", - "sha1": "51b985a55285d32017de00f585b9f36142de6fce", - "sha256": "0013a81965e4a557753088da180a9117ccd15a399ca9f289be4ebeeccfa49300", - "size": 1864201 - }, - "636": { - "releaseTime": "2013-04-04T20:19:58", - "sha1": "ce0ff3cc72c656a36d574fcaa13c5e948d0e96ed", - "sha256": "6d5858ee8a582757b9d9e90466b741c360aadb19e7c9db0d7e03cf471ae8906a", - "size": 1864670 - }, - "637": { - "releaseTime": "2013-04-05T00:44:22", - "sha1": "63e4e9126f9db7d938d5172d9cd892f9e8570b71", - "sha256": "0e88cdfdc1bfc123ec1f3c171721d16b7ddcfef16710762b2ff3e549caf4535f", - "size": 1864839 - }, - "638": { - "releaseTime": "2013-04-05T11:40:16", - "sha1": "6b837529e509ce80bf67a708be7d9160d58a3b77", - "sha256": "6fb257167c1752f8d35ce73f3212b0648ed105c86bd60ce1d2f460b80c7ba55b", - "size": 1864944 - }, - "639": { - "releaseTime": "2013-04-05T16:21:02", - "sha1": "d49ebade7765363fa5d227cbef125969f0848407", - "sha256": "d6d5c05f335e67031e78637be76ada17eabca3f7de020f512104ce0301bd9ef9", - "size": 1864957 - }, - "64": { - "releaseTime": "2012-03-26T04:37:02", - "sha1": "e590a6e7f9cd6d0b683010abca34c69080893c28", - "sha256": "fff2343e68c5815b9aa664770d493543a4f016af5a0160556c9fb5a6b098e429", - "size": 503843 - }, - "640": { - "releaseTime": "2013-04-07T22:55:46", - "sha1": "e7c2fe9a95126c6c1a048df07f6a055aefad290d", - "sha256": "9b92c7b583c86186fe0e60515412389f5885c1f1962b3d8691f177051681f6e7", - "size": 1867592 - }, - "642": { - "releaseTime": "2013-04-09T19:28:00", - "sha1": "d5ba1d70d59d8a8b7840ce4dab9ae70c5a63de31", - "sha256": "496a0cb967490a83f15d439896809dd498da25a210b5ab34de9ada2fdde0adff", - "size": 1871955 - }, - "643": { - "releaseTime": "2013-04-09T22:12:00", - "sha1": "eb9b08f9fb309260302a7b3be845dd9e8168ebff", - "sha256": "e1d1e43d8592d4cd237a0b2528111a7f48f616554454ce8049a0d46e8b1121d2", - "size": 1874769 - }, - "644": { - "releaseTime": "2013-04-10T07:06:26", - "sha1": "efd54911c2ca6f4c300451f94b2840e93f5316b1", - "sha256": "d02b73facccf65d96b33c13e1d98965491e19117bc445b1f29279f844e713b0b", - "size": 1874656 - }, - "645": { - "releaseTime": "2013-04-10T12:14:10", - "sha1": "db855176a6c2d4e869a875cb51dcf0c244726fa9", - "sha256": "fc18fef4c1ee6f7eacde0f4ff6ce582123aeec6092407e9b4a5d23b47470f33e", - "size": 1874885 - }, - "646": { - "releaseTime": "2013-04-10T16:46:34", - "sha1": "0a4310d327dba9c1d1939a8da17a46015cfce441", - "sha256": "c70b0203184883682daafc854c0575fcc9291fe348858aa481d32c062692be8d", - "size": 1889074 - }, - "647": { - "releaseTime": "2013-04-10T17:01:26", - "sha1": "563345cc96844f8005374f64dae2dc78d989e43a", - "sha256": "0e4f5c0fc1c681eed6c84fc715d0e1aaa9ddaa46726837ddc3046a4c8c70810f", - "size": 1889074 - }, - "648": { - "releaseTime": "2013-04-10T17:42:02", - "sha1": "dd37e5b9ad13c7b07983f872818f86f42896c437", - "sha256": "b83d160c0d210f99fd32a510dbd39af972ad65d4813a7efb0f6b6fe32f1c26b6", - "size": 1889326 - }, - "649": { - "releaseTime": "2013-04-10T18:05:30", - "sha1": "fc44d88885a297f2fcaae01262beb460d9044840", - "sha256": "1141912de80faedc8ded1128cb6c73428dbf4223b525f050e26b94def2551ce2", - "size": 1893066 - }, - "65": { - "releaseTime": "2012-03-27T00:44:54", - "sha1": "fdf2e7bdc7ca3cd179b82c4b690e208f9a62bcaa", - "sha256": "d70dabe8ee2f6440b0f612fe61be8e6e990dd97eed60c7dbb98b7820eab16a7a", - "size": 503852 - }, - "650": { - "releaseTime": "2013-04-10T18:33:56", - "sha1": "f862748c96233f922bf2983198251c0d4466cfa1", - "sha256": "78b95b183f8387f6f031f81ebe2556765931302c4b74a0e4d1098e2c1f198e08", - "size": 1893143 - }, - "651": { - "releaseTime": "2013-04-11T12:49:12", - "sha1": "076eeff722342a367058fe5ab60ce355335fe676", - "sha256": "4a30217b29fc967fed7065c5c00bf045e9512eccc68324db44e0b480d12bbf93", - "size": 1900288 - }, - "652": { - "releaseTime": "2013-04-12T15:23:20", - "sha1": "680fc079a7ed7a92cc30db07a50d7318febdfbcf", - "sha256": "7cd5153a145b8d5affda63beeba6dfda738ccda225277c21e0550caac073acd7", - "size": 1898972 - }, - "653": { - "releaseTime": "2013-04-14T22:50:24", - "sha1": "02297c606a18a47ef0159b743f107ce8c4c796b1", - "sha256": "d3cb69d82969dbc8a62858d2fbf54d30d7d088a7d8fea79b194f6e5b0465f584", - "size": 1901921 - }, - "654": { - "releaseTime": "2013-04-15T11:24:44", - "sha1": "79952eda8d6f6350f8d9dbfb775b9f3c9f7a6b45", - "sha256": "1cc0106a37883f7eeefc73e81c4078056f603d99a6c66c6c9f1fdad5d7ca1410", - "size": 1901953 - }, - "655": { - "releaseTime": "2013-04-15T17:11:20", - "sha1": "f070ee134a478cf2c04457e38523ecfce8b6c46f", - "sha256": "b2af5209824736919c5fe6dc2a77a19ebd3c1c80c127db6ea08058219fceacc9", - "size": 1902601 - }, - "656": { - "releaseTime": "2013-04-16T12:03:34", - "sha1": "a893fec9952765389312a7af9a71180774258051", - "sha256": "e3ea6746adca859367fa05aad6257a81e6b10052a34a116fa92bfd99eefab6d3", - "size": 1903303 - }, - "657": { - "releaseTime": "2013-04-17T15:09:52", - "sha1": "70dce35b96dc4d8de33cce93219caa0b3eae98ab", - "sha256": "87fd6f594e94d8ca6a806911f1da5897a9feaede5daf63f899868254adcdd084", - "size": 1903009 - }, - "659": { - "releaseTime": "2013-04-17T20:27:52", - "sha1": "0318a86dafe9b34f17d469f4db59254370e53d16", - "sha256": "8b55ceba1e73e9e10c45da5368554c1996102907de265a58110c258eff8dc853", - "size": 1903124 - }, - "66": { - "releaseTime": "2012-03-27T01:04:54", - "sha1": "ff7197ad0ee80015b31109a7b042d57627ec1248", - "sha256": "0b0fd015dbe8d2ca139ca4b95800cd8e61499ed55bce18b94333811b6109042f", - "size": 503851 - }, - "660": { - "releaseTime": "2013-04-18T15:28:58", - "sha1": "ff188d20471985d2f2e5fd73859271ad0ed6d519", - "sha256": "a17d872ef84e533b369a4b8d4b83d5564d397c29054c16c021af80357e1f0eea", - "size": 1903328 - }, - "661": { - "releaseTime": "2013-04-19T11:59:40", - "sha1": "29d1a1aec78fe793d96e41cec7d3d7caecfa7787", - "sha256": "73a6e3aa3a9346491299761ab0558cbcedf056256ff97ac1b8680ecd3aada47a", - "size": 1903438 - }, - "662": { - "releaseTime": "2013-04-19T23:14:02", - "sha1": "f77e0c8e14c80c07b42161218b59be8fde0bb341", - "sha256": "ceaaae977aac1edb3c518f77efbccecf459ab93b3c77ff2ba002302044f8113b", - "size": 1903425 - }, - "663": { - "releaseTime": "2013-04-20T12:31:26", - "sha1": "61399f70ca08255d09b3ff09b30083d2e9de471c", - "sha256": "3ae90dce0661a86b10a85c80ab487272f97dffc2c65fbf84ae5c1fa0cc91524d", - "size": 1905710 - }, - "664": { - "releaseTime": "2013-04-21T01:20:58", - "sha1": "5c9759fb7183a96d86faf8a5b715afebe2254306", - "sha256": "23ff1c9d97b9fff49223a08207137a9d70081d94b52f8827932029dc06963b5c", - "size": 1905898 - }, - "665": { - "releaseTime": "2013-04-21T11:47:24", - "sha1": "d55b620f5550af53bb7f6a8b9289c87240ce2519", - "sha256": "e4b9bf245caf46efd9643bac2e035c2b422bf445ba599b451d3f4bc24a49deb8", - "size": 1921258 - }, - "666": { - "releaseTime": "2013-04-21T15:01:28", - "sha1": "b09a58b89476fd18e461dec1bedb9a60889ee192", - "sha256": "db41ae60dce1e47363d3b046b68d7ab15b5fe1b42c84c153246b3a23e83d19ec", - "size": 1922439 - }, - "667": { - "releaseTime": "2013-04-22T19:21:50", - "sha1": "7556b581a57f140413b3467dcc6d9139b3f15bdc", - "sha256": "d491dd5c2026bdbcd7b545ebb830db0d1a23caeac03351b2ce299be5f34935a4", - "size": 1922690 - }, - "67": { - "releaseTime": "2012-03-27T07:32:36", - "sha1": "9558cb918a1766d2e11ebba352eff9fcc5a23437", - "sha256": "a979d8479974c422973970d1c27c1b57fe9b3721a1b082f42e327c69c36486d9", - "size": 503826 - }, - "672": { - "releaseTime": "2013-04-23T20:56:40", - "sha1": "1738bc1cf39d465cf78d24b8f31784cb3568ea13", - "sha256": "259a465b177aad0724da4815619f046635881367ca93b525ed305001a4134bd0", - "size": 1923182 - }, - "673": { - "releaseTime": "2013-04-23T21:42:26", - "sha1": "d3f2eb1683bf8ab158aabcff2f2eb3daa0deb31d", - "sha256": "4131973e4eb330e64a135ca7687efe66eb6d49ddc958b3b90ddbb7af511fa61e", - "size": 1923226 - }, - "674": { - "releaseTime": "2013-04-24T11:58:00", - "sha1": "a8aba7c84b23427100b9d60d7337165430abd034", - "sha256": "af174f6c991ea67c3d85bb122f13ae5e7764abfe745783af0ae719356d5ff9aa", - "size": 1973350 - }, - "675": { - "releaseTime": "2013-04-25T19:51:18", - "sha1": "fd98cd49077ce57749235316d7a428545ba4d2b4", - "sha256": "7e112989d08179b444f7aba1f6b1441654121d92c2e9eaf661dcef3f04203edc", - "size": 1973642 - }, - "676": { - "releaseTime": "2013-04-26T14:15:34", - "sha1": "4a80718c75542fed023bb178c11695373539d329", - "sha256": "cada7dad8f5966da437187416413ac8e72cbf2824bbb99314b3bf9e1df5bfe4f", - "size": 1973741 - }, - "678": { - "releaseTime": "2013-04-28T15:27:56", - "sha1": "01bc4839acb7b32a5214906d5f7c1612da1fd5f4", - "sha256": "df6647bd1e408ebc55a9779c1d5b660a24855c2189ca0d04bc0bf4cbd62b37b7", - "size": 1973777 - }, - "679": { - "releaseTime": "2013-04-28T16:41:22", - "sha1": "94fbbdbe7dea9ec402fb821cf1a1472507b67a18", - "sha256": "6b54ce0df3f2f97d02233c0ce13e6dbd40b9c2402888fc1e107488ba9bf88042", - "size": 1973698 - }, - "68": { - "releaseTime": "2012-04-02T02:32:02", - "sha1": "472933267af1bd5693f2aa4e89aaad48cfe2d629", - "sha256": "9c9c26dabe099bca7ec29eed9ce8b90f4d55b91b39693170b171084a7b53ed8d", - "size": 504946 - }, - "682": { - "releaseTime": "2013-04-30T21:26:14", - "sha1": "2832ae601b5aac519f82ef4f784d6029b4e6b806", - "sha256": "201cc3b2af2175ef7ee6bc347bbfdcc9cff6e2cfa27ab30eef53aaf62de8e339", - "size": 1973847 - }, - "684": { - "releaseTime": "2013-05-02T10:24:50", - "sha1": "90c15460f12138f90d0ebe23cc32aaf589b3cf1f", - "sha256": "3383e9062ad778d867405eb04eaf7a3ac9b0bcccd3b7b47ce96cdc535725f415", - "size": 1975130 - }, - "685": { - "releaseTime": "2013-05-03T15:46:32", - "sha1": "50b4d98c368340f96e1d85c6a1c98f8158b39f66", - "sha256": "0ceab9100977dc466efe00ce5e65db2261530a7f2fae9a4376abd674478cd45a", - "size": 1975158 - }, - "686": { - "releaseTime": "2013-05-04T18:49:10", - "sha1": "8a176209473781a6870b9c600c33891807a51d23", - "sha256": "9f28c0dd3737df5911d53442b821768ac373e0db618211e60baf31823ff92df3", - "size": 1981647 - }, - "687": { - "releaseTime": "2013-05-06T20:16:46", - "sha1": "015aef26f6a8eb2ae95485c65e8cfa814715e647", - "sha256": "acc3869918a12f3d97506f9eaab9d9029a2d573cf736ffc67b9e9de2825ba8d2", - "size": 1981935 - }, - "688": { - "releaseTime": "2013-05-06T20:32:26", - "sha1": "3226d1cce1245b1c1e78da9fcbccf9918a8325fd", - "sha256": "8c2ac223476f8e37fa58fb93e0966704aee0a3a9bfafff7207a27fa1fbb0dd0d", - "size": 1982018 - }, - "689": { - "releaseTime": "2013-05-08T17:40:56", - "sha1": "710184c7c19b2be41ae111a930ad878089e1f851", - "sha256": "94bbce5bc8cfbd311cd031391e618dd6aa940bd83735f4a574c890360f706eb8", - "size": 1996416 - }, - "69": { - "releaseTime": "2012-04-07T04:32:06", - "sha1": "75f13154c3196f749bd0db90d9cfeb08273882c0", - "sha256": "5346560a1c8feb740834a06d3e621bbb952aeef734a661a4f937b694770e02be", - "size": 503459 - }, - "690": { - "releaseTime": "2013-05-08T18:19:54", - "sha1": "d4d81fa3ee06a0376f1ea988d4d5ce01bdb87d38", - "sha256": "8aa17bfad0efd2b681c24cb2c361e5b42b645121ea856b650f3d66e9765f4783", - "size": 1996762 - }, - "691": { - "releaseTime": "2013-05-09T02:10:34", - "sha1": "d26816531b8a602b1017fc12c5751b3f0c898f91", - "sha256": "164b63443db99450ffb21e210e2c4cff5b6ac1811274ca22b099048a53b13316", - "size": 1996885 - }, - "692": { - "releaseTime": "2013-05-11T02:12:34", - "sha1": "a6db5508997a1c7da4967be62566a8a9ecbd76a8", - "sha256": "04baab4a61ac567b19a16ccabc2d24621246ec5a8ead0de6964311640bcecbfa", - "size": 1996907 - }, - "693": { - "releaseTime": "2013-05-11T11:05:56", - "sha1": "929858c287ebf13a0dbdbae880cee535031593a8", - "sha256": "bbf24f529798daaf1853bf30b5f716b9d223be7aaa9e75a21d681fb704971593", - "size": 1996968 - }, - "694": { - "releaseTime": "2013-05-11T11:21:40", - "sha1": "d0aaf895840de87de21ac2e39b402b2462108365", - "sha256": "8cc42ebd28541937c1ab671f88d536f2904fc0dba8706761703266076009d897", - "size": 1997048 - }, - "695": { - "releaseTime": "2013-05-11T12:05:32", - "sha1": "df03ea2882aba13d16a806a25c487b0b63d80e12", - "sha256": "2fd71dbf432d2602f884e457f981285725fab90d6461d15b663afdc776b30ef6", - "size": 1998522 - }, - "696": { - "releaseTime": "2013-05-11T13:23:26", - "sha1": "63ca0f99d1cbfa1aef0cb3464d72f1bdb675fe8f", - "sha256": "8675a75da788e107451398ebabba25b8e6b8ed74ab5b75f47c4447019ff4d180", - "size": 1998669 - }, - "697": { - "releaseTime": "2013-05-13T21:40:24", - "sha1": "a67ec8dab25c86822284b73b9be0d895548191bb", - "sha256": "be9e0180ccb4481193d2a99e1327c21c6e3b0248a30c90003f7383a4d6cd20e1", - "size": 2001775 - }, - "698": { - "releaseTime": "2013-05-13T22:11:38", - "sha1": "23476d809fea3460ef2cd61e6198806ec826c2d8", - "sha256": "7232431f16d42899b6a2a56dbe049e23d30489fb66f98406da1893ce0d7b4cc9", - "size": 2001837 - }, - "699": { - "releaseTime": "2013-05-13T22:27:50", - "sha1": "b1c584f190dd2a3802fac3323ac2f939ccf1539e", - "sha256": "ee6e58c5d956d61ebcdaf76ae5693bc2ccb56fa11da67db7c149392aa589058f", - "size": 2001888 - }, - "7": { - "releaseTime": "2012-02-10T07:13:14", - "sha1": "9f74f177ac12b2b99d5418133a48d829c7065163", - "sha256": "5bf54ac1cccba02d30c2f1bf39b06c18f1e7fbdccfb80a60bae2dcbed2e6d111", - "size": 421307 - }, - "70": { - "releaseTime": "2012-04-07T08:10:50", - "sha1": "76b6d4414355a4451f568223f8ed8a0707ab5c0c", - "sha256": "15e2fc339c8bd32383cefa4b3964af35decfc94872f65b039327a0c491753ea0", - "size": 503473 - }, - "700": { - "releaseTime": "2013-05-13T22:44:34", - "sha1": "ce3831b7f357872c476221e28facfa430e9f84f9", - "sha256": "d3c2e269d14b40bfc330f0d532d5c117201b409bae9dfb344ab5373cd2b9001d", - "size": 2002002 - }, - "701": { - "releaseTime": "2013-05-15T18:36:52", - "sha1": "5f7141eefcb4ed3fcb87e638cd7d2eefa0457e2a", - "sha256": "5ac8b8c591cce7ad7623aa62bf569ced84dca30574bc268f8e2de6f80e3ca54e", - "size": 2004225 - }, - "702": { - "releaseTime": "2013-05-15T18:58:42", - "sha1": "8c1422010f057f81d3ea0fbc73bc8e04e04ecb45", - "sha256": "ce2852ad64cf8f6315aff0a294091b586a313da6fa5dcefe956766247c56cd51", - "size": 2004573 - }, - "703": { - "releaseTime": "2013-05-16T08:19:28", - "sha1": "39bb7c0c79e942046675d85e3b60ece4dc7b4a58", - "sha256": "4581ed106a8f9819fde5b7c76a575ab3428b3970bb767c2acd73a906bb90bcfd", - "size": 2004639 - }, - "704": { - "releaseTime": "2013-05-19T14:37:58", - "sha1": "c3948bab0718823ff488bbd7c15e5f3fd79fdfa2", - "sha256": "5be44a78b162876127971f551f6306460a20b9e87fc5b87a7872d590c35f3aa4", - "size": 2004691 - }, - "705": { - "releaseTime": "2013-05-19T14:55:40", - "sha1": "fb0fb76a907588402ac8416d3d37725da8ac7e8d", - "sha256": "249c828331f213d92e4d4484eaf4d0fb6dda8db572551a6b7c3727907124c715", - "size": 2004808 - }, - "706": { - "releaseTime": "2013-05-20T19:58:56", - "sha1": "3c12441da278d3cd993afd3822585797a5d788cc", - "sha256": "74a22bca0f957f7328b158d14e991adc7f26a2bd7cc95c8f23e2dc4a0fb2cf82", - "size": 2008262 - }, - "707": { - "releaseTime": "2013-05-20T20:31:34", - "sha1": "b079436f13cc59cdce6f54e0409d99c0222130f3", - "sha256": "f4b435c84e3a8a44802dc8ba476027c5d7b379852713677b403a38dcc411b115", - "size": 2008384 - }, - "708": { - "releaseTime": "2013-05-21T09:10:24", - "sha1": "ed6c6e9bb5b8b3ab7d6281717ef67359d687c326", - "sha256": "fbdc9297bb1ba5760928d1ef77f610d295a49ba15f1d937e4db87ea76a03e552", - "size": 2008476 - }, - "71": { - "releaseTime": "2012-04-07T21:15:22", - "sha1": "43034ab1176c672ff81b658d8071cd7955a50fcd", - "sha256": "4c7d2eaf146ad1d492434b03a4b7f46c7e91469edda17e3f1cfac270bd4a95e7", - "size": 503475 - }, - "710": { - "releaseTime": "2013-05-21T21:20:08", - "sha1": "0b8d1daccad003be2e930b9391fa87aec2c9d8bf", - "sha256": "d0eef0327f00aadf59c7215d834f9ea7230bbce84e303cea0cbb9ec32eed3440", - "size": 2012979 - }, - "711": { - "releaseTime": "2013-05-23T23:14:24", - "sha1": "c78c3775b880b2b45e8b6b14769da6d2b4748037", - "sha256": "c247dd77fbff8c16a8834fce812f618d34ed4663ead3c7f3f3b1f4a88b446be1", - "size": 2014309 - }, - "712": { - "releaseTime": "2013-05-23T23:31:14", - "sha1": "228c0999c5a224d8290e29823c4dd31b5679866b", - "sha256": "b52b2f0cf5b2dedc06185c500c215ab9e7426f7342d8a4f2fe4f2dd0d7f6fadd", - "size": 2014600 - }, - "713": { - "releaseTime": "2013-05-27T09:17:32", - "sha1": "51f931ead831c564033b17cc835e3c2edab1e24b", - "sha256": "cd79d0b0c55ce044664177c201fc8036a0f18431b67b7e97570ac1b991f0bff6", - "size": 2017084 - }, - "715": { - "releaseTime": "2013-05-27T17:19:28", - "sha1": "00700cefeb2effc71737f65a6cbb204effd5f300", - "sha256": "b3fad160a0d59a27a73b8ebedc40fce8c9885d7ef20fb291e820a4642eb97982", - "size": 2017367 - }, - "716": { - "releaseTime": "2013-05-28T21:44:14", - "sha1": "6118150c8c0e15a6926c62e8525f9014d14dc34e", - "sha256": "71987c72116cd81bd0e7e55ca01755946d4a0a42cc93e264b977daf6abe91f78", - "size": 2021922 - }, - "719": { - "releaseTime": "2013-06-02T17:33:16", - "sha1": "6b90d931a20413bb13c31e08e543f39dd7155d59", - "sha256": "e8dea27918aa6b5573571c8f3f008a576aa11b777d7aa292bf20b7dba0c4d4b6", - "size": 1969868 - }, - "72": { - "releaseTime": "2012-04-08T04:34:02", - "sha1": "8d3179e614985a5d8604b5e28008d36edd8795c9", - "sha256": "81c65151bdae9e7effde9df1bb281b6eda6a409340a45c5f721186f5dccc9d25", - "size": 503474 - }, - "720": { - "releaseTime": "2013-06-02T22:35:34", - "sha1": "56f9d5a36821e3deb3e8d8e5c7c12d26b007f744", - "sha256": "cc4df5646f71a005f0696d4de9ebeb558bd553cd746524e06262f40ab423dbb8", - "size": 1970132 - }, - "721": { - "releaseTime": "2013-06-02T22:56:08", - "sha1": "02323336f7d1e8e68a3feab3123ad1aaf935e756", - "sha256": "d0f1422ceaf76e44b7dfb11fa651689f43a3367863b799610a947191ec540690", - "size": 1970162 - }, - "722": { - "releaseTime": "2013-06-03T13:30:32", - "sha1": "573149c42a161efbe95627850629c801c9107e83", - "sha256": "8b8e6a0dfcf085e4687548b68fa600d8126b84066033f3ddf266c1761fbf71df", - "size": 1970177 - }, - "723": { - "releaseTime": "2013-06-04T18:24:30", - "sha1": "9d0686ede1e00c46b6540cdf9d9354d701fc1fe9", - "sha256": "399da9a77a7a90792b761a007f4fdd8ddfbb15729b0a701edfb46ec02d23fe35", - "size": 1970645 - }, - "725": { - "releaseTime": "2013-06-06T10:24:40", - "sha1": "23126c578162a9675aa80160c5f45ed602b6a546", - "sha256": "cbdd44edc72118d851521d3f65c8c3d93c7eafa88b0c22420cd726962641f803", - "size": 1970914 - }, - "726": { - "releaseTime": "2013-06-08T13:28:12", - "sha1": "68a5d447ad321f5f993a5bedd820fe4349fc4fe4", - "sha256": "9b12289096fb79acefb402d21306f0211e6d8a1ad23d4286c7491b1d11c909b3", - "size": 1970976 - }, - "727": { - "releaseTime": "2013-06-08T15:09:38", - "sha1": "50e7d54fd520da847acf2841915fbfc3aba180bc", - "sha256": "62b5ef66f76390cf5f8267a899de64bc6ab201059af5bf36d7926fb18ee35af3", - "size": 1971222 - }, - "728": { - "releaseTime": "2013-06-08T19:45:40", - "sha1": "dccd0e8722a5dd394fe8c8b3d03f631bd92aea00", - "sha256": "8c95ff2b90b1d20cfc1dbdb36b562c6de95a9bc0b73b17132a4aba39002ba3a1", - "size": 1971257 - }, - "729": { - "releaseTime": "2013-06-08T20:43:38", - "sha1": "94f3f2912a8b02cf96102c6e6d113a7892a745eb", - "sha256": "837f3081f2b570b4fd46f6c9454a3cdb3fe6221e98a1c10528b5849ed9a1ee78", - "size": 1971301 - }, - "73": { - "releaseTime": "2012-04-09T23:01:20", - "sha1": "73c54a203bda1ac2e2b99e5209a122938db118bd", - "sha256": "aaae6d2eb7d882f0bf4496687a7fd4ba9a286006b73ec2b7f896d616f5755848", - "size": 505435 - }, - "730": { - "releaseTime": "2013-06-10T02:45:26", - "sha1": "f75107ac5491862f90d446d955d064350b9ec2e3", - "sha256": "00b98fda45ca4dc97de7ec581cf3abb73b59b5f1230e30aab86f5783a4df9127", - "size": 1971321 - }, - "731": { - "releaseTime": "2013-06-10T03:14:12", - "sha1": "58c8ca5c9f80db437c5d1b6a7617616a869ff86a", - "sha256": "704ebecb955f25eb6bcce50c5fb5e8992b394f27bee610b923cb541914827604", - "size": 1971325 - }, - "732": { - "releaseTime": "2013-06-10T03:35:28", - "sha1": "4794e92c949150dcd742232dc54b340361121e65", - "sha256": "7edbd0b24a16c9fc82c3c213f7deecb18f74560218bf3231638a3d13849f1dd1", - "size": 2027315 - }, - "733": { - "releaseTime": "2013-06-10T15:06:34", - "sha1": "b15e7357fc4cd580df113b31b01d2ab096322eb2", - "sha256": "01a36247c9eca10edc6dbc833e88571063ced5ce8a327e1e3fc3a3ffe0bbc2b1", - "size": 2030486 - }, - "734": { - "releaseTime": "2013-06-11T13:06:00", - "sha1": "6c928588eb71df046994d90f1d080fdf0ddc7aa9", - "sha256": "1cd22d0160ea0e0ba73570b89d506e6bc51234e6fd819b425e527492df4d443c", - "size": 2030872 - }, - "735": { - "releaseTime": "2013-06-14T12:39:28", - "sha1": "82a1dabe45e2261606da04994cf4a68d9ba06f94", - "sha256": "7bebf6b5d546062f47b7427fcced5b3fb55618de6697ba2803fb082433816953", - "size": 2031022 - }, - "736": { - "releaseTime": "2013-06-14T13:17:30", - "sha1": "bc07940c37813839c8137ff07ef616515d75e3c6", - "sha256": "db5a8de955581d386254240cdf71191e59be2b1a17d66ecaad61f404ba792ef7", - "size": 2032700 - }, - "737": { - "releaseTime": "2013-06-15T01:26:46", - "sha1": "7b36d45f87a89071c6252f4cd50e632e7d285ecd", - "sha256": "988072f14ba1f70392e7d2305f6193f7c96399ed004896f5f489c3e04b5c6260", - "size": 2032810 - }, - "738": { - "releaseTime": "2013-06-17T09:35:38", - "sha1": "76223709288287a6a8d22ab16b43a6ab2a284a0d", - "sha256": "5758f6b77d3192cf5fe6d718a522c66fb2a4ddbc375d4b66f4b0019190d07f98", - "size": 2033732 - }, - "74": { - "releaseTime": "2012-04-10T00:47:32", - "sha1": "26e3a344b4aa38f8201109a7d965ac914c3d166c", - "sha256": "5566dea1974860dbf2d74e24ff93eeffef32c9a110e69840e40ef2a4bc339387", - "size": 509139 - }, - "75": { - "releaseTime": "2012-04-10T01:06:54", - "sha1": "8cbf482dcb0722632fd89543f623cf148c53e641", - "sha256": "c3de9491468598a5e69ace5eec1dd99489a88ee188f7cefcd0fa5f053665f466", - "size": 509659 - }, - "77": { - "releaseTime": "2012-04-12T00:51:04", - "sha1": "677b006d34ea06e3cf5aa636717142ebb2e0f8bd", - "sha256": "5a055de2522561542a0ab8aea8cf7d153787222ff81d6cd642a67cc356de8f3f", - "size": 509761 - }, - "78": { - "releaseTime": "2012-04-12T21:50:42", - "sha1": "e78981327efff67efad73471fd22218c9f98d29c", - "sha256": "a5a6efec545b7f068ac989f0ecc73de0b769f319d5b3796b09d6c8666c0a67b8", - "size": 509780 - }, - "79": { - "releaseTime": "2012-04-12T23:40:58", - "sha1": "4261e979e992ad6bfb5d76bbf6aae773774895c5", - "sha256": "603b5cd9226564b5b9217e2f45ae43fbb8636b43a62af249679ddcf42d05f196", - "size": 509886 - }, - "8": { - "releaseTime": "2012-02-13T04:20:56", - "sha1": "82de2ba21c06a352b571ea1374e428e63a91239b", - "sha256": "eacdb5ff32dc902f38e1c5fbde3e29a2a401722378f47f2a76396f13462a572c", - "size": 435800 - }, - "80": { - "releaseTime": "2012-04-13T09:56:58", - "sha1": "24e00e4620341bcceb50cd68f4f24aec2c2f8435", - "sha256": "f0bf7269da20eaff1f7c4a6d967685c65c8a70fe3cd4afc9900f2784355e3efa", - "size": 509886 - }, - "81": { - "releaseTime": "2012-04-13T10:35:16", - "sha1": "185629be371faedee1259e749921fe134c24c82c", - "sha256": "f2b22173dd2d683a05cc212db097388756adba1256eef6410901fe68e01eadd0", - "size": 509833 - }, - "82": { - "releaseTime": "2012-04-14T13:10:58", - "sha1": "f83a1d16d6b0a6f126e6da1084b53d45718e0f7a", - "sha256": "5aa92446463dd6873a71d0477e3933eae094f900e0b26b483d4304d838f351ae", - "size": 509874 - }, - "83": { - "releaseTime": "2012-04-15T07:40:04", - "sha1": "3b16bd8a6cb0c576e0c9d2c32bb063beda71fc1e", - "sha256": "3787eb348373d6cf60cd63dcd8182998e68d3c5fc71f36600546643d60c8e803", - "size": 510336 - }, - "84": { - "releaseTime": "2012-04-15T08:38:52", - "sha1": "c1320821760b73bdb195dd47cddc57f11bde9bc2", - "sha256": "e493a1d690b0b84e8088ab6047391221efec056e98d360d4a03dd9ef2ff11429", - "size": 510337 - }, - "85": { - "releaseTime": "2012-04-16T15:21:44", - "sha1": "24ad84c2b8a29a4cac503bfb40337c2246baec08", - "sha256": "5a006be9b3d6f6ad96697229a2ca413d7675c3bc9da904dc98a26edc46063bce", - "size": 510341 - }, - "86": { - "releaseTime": "2012-04-17T08:50:44", - "sha1": "9226f1ea2b7528b14b46a1550df63a941d02d4a7", - "sha256": "78202fecf9aa24e66c8c24fb5edd3fe85806135db85596ac9e36dee7454c0de4", - "size": 510362 - }, - "87": { - "releaseTime": "2012-04-17T10:30:58", - "sha1": "0822f3f25056be30419e187cdc3e4545bc837c06", - "sha256": "4b5b66c3c26a706a6c2b61b919e5f1bc418a3cca19fb6630d1bc1ed4f90729db", - "size": 510360 - }, - "88": { - "releaseTime": "2012-04-17T11:49:12", - "sha1": "cbf82171afecf4be0f0277ff0bef6646466e8900", - "sha256": "5c501a2f00233812bd746b737e4f3936044555f421f1b82a623a54ee711f3f5e", - "size": 517391 - }, - "89": { - "releaseTime": "2012-04-18T19:46:12", - "sha1": "ba77728f246cc494e84e1754f0f3ce03acb51a9c", - "sha256": "934dc21dfcdd5362554a83239669654a2e964d8621cc8165133099ff6691751e", - "size": 520417 - }, - "9": { - "releaseTime": "2012-02-14T10:43:10", - "sha1": "da9c0bad1054c5c8da8a22bf9394e14f3f70f8f2", - "sha256": "41c3ed9c7caf5d08e9d47dab1a36ce07d3c7ab1219da79fed0f486be61b38ee2", - "size": 446478 - }, - "90": { - "releaseTime": "2012-04-18T21:22:14", - "sha1": "d57947d579fe7441b65c6c1e0df7d3f8c62bed0a", - "sha256": "1ce05a2727edca09e7abca9ffe067feba6ece29de1bdd8473f7a5de4ecb4f9be", - "size": 522552 - }, - "91": { - "releaseTime": "2012-04-19T10:29:24", - "sha1": "513bf2fd928db15bde37aa31783bf243cc1e66b5", - "sha256": "c0843a2ecae1614bb18893633a47539c5ebabdd6c6e421d3de91723f850196bf", - "size": 522849 - }, - "92": { - "releaseTime": "2012-04-19T15:46:52", - "sha1": "3726362c75145a17bfd4d86bbdbc5d2770fc548d", - "sha256": "78065abadccafc87468f50013f7db8f021b00dae0a1640b222f7f3ec68a81b33", - "size": 523485 - }, - "93": { - "releaseTime": "2012-04-19T22:15:26", - "sha1": "246407ad677b342757ed635e0ff27574eed187ae", - "sha256": "2fcfadc16a4c171730e205fee1e7cd169037ac2ddcdc618f37775d1cda75d8ea", - "size": 525255 - }, - "94": { - "releaseTime": "2012-04-20T12:13:26", - "sha1": "17d961b3b62d2a050b3dfcc3598c7ea3fa200680", - "sha256": "4963274a498620988b13a142c02f6092a2b55681a0aa58309bbe0e034657bf44", - "size": 525307 - }, - "95": { - "releaseTime": "2012-04-22T19:56:48", - "sha1": "ce95bd720b3b40360dc0e8c3d1c139b22ff41819", - "sha256": "db66f23cda2d3b2a7490bde96c6105fe5ec184a89d95bab9d7a9451d1c861017", - "size": 534102 - }, - "96": { - "releaseTime": "2012-04-23T10:22:12", - "sha1": "7eb8bbd96e3dffba57cbf54b7945f1a971582496", - "sha256": "7bda8102696ca29c23edfa0889bafe062a66c31a9141e7ac5bc1a60f98545b1f", - "size": 534131 - }, - "97": { - "releaseTime": "2012-04-23T19:21:40", - "sha1": "41b4f307950fdcf862d4cdbda55384cd0af92eed", - "sha256": "fda396ff176e4cf52a9ab308ed0f1cc9883ee1223b8128546e4b49f5a8129e3d", - "size": 534216 - }, - "98": { - "releaseTime": "2012-04-25T01:41:00", - "sha1": "70c6e3b3bf059dffed3d75d1b6b83d2ddd8f4513", - "sha256": "ea6717dd33d9345ed71753278e3bc393adefb69219217f2c456657476a78a6e9", - "size": 535244 - }, - "99": { - "releaseTime": "2012-04-25T01:48:48", - "sha1": "bbeabcea70aa1bd7a24141fd34af67cf259a9270", - "sha256": "62756c8436b22a43ad56096da5e5a406daa416ba106a75ac61f165151cf55b23", - "size": 535241 - } - } -} \ No newline at end of file diff --git a/static/forge/forge-legacyinfo.json b/static/forge/forge-legacyinfo.json new file mode 100644 index 0000000000..28e45244f8 --- /dev/null +++ b/static/forge/forge-legacyinfo.json @@ -0,0 +1,3712 @@ +{ + "number": { + "1": { + "releaseTime": "2012-02-03T03:43:02", + "sha1": "3b67ffda89f4d8c7625a00aee23c270ffef642c8", + "sha256": "090bc30701b942efcfcbca6ccc22cb16aca74e12f16d47e0c026508d1e115cb3", + "size": 385340 + }, + "10": { + "releaseTime": "2012-02-14T11:17:12", + "sha1": "b08fd9b88a7c4f2773462a501ec2a37e8a71f177", + "sha256": "a93fbce5ebf0046cec068db167ca380b207b6a2092b2487d438bf0b6c14b4509", + "size": 446516 + }, + "100": { + "releaseTime": "2012-04-26T14:52:52", + "sha1": "9107451e325dd60b21fd31db956e2cba7ad78777", + "sha256": "09e6242404f8f1d1bff77fc1a88ebc650a5db5afd61c1bcaf155a7cccbc38dc4", + "size": 535241 + }, + "101": { + "releaseTime": "2012-04-26T19:15:44", + "sha1": "1ec31c6def402042b240b78b29f62d282dda9245", + "sha256": "6ba717cbb338d02bc517026dde1046ee32b99df869ce444f2c524766cf587ac1", + "size": 539903 + }, + "102": { + "releaseTime": "2012-04-29T03:15:02", + "sha1": "7d27b1cf0bba9084ca9dd40836a591a6f549ab99", + "sha256": "b7d54a5bf528e197b84176feca4c6dfc39e7510dd2b934c01bba4d20b3fd5a05", + "size": 539984 + }, + "103": { + "releaseTime": "2012-05-01T17:41:18", + "sha1": "ff0f5ba142f93216e3414a62a35bc0ea63c04e2b", + "sha256": "035dc0c527456593aabf95e5af6a353244deba2c7dd42abc512e87877be09a21", + "size": 539984 + }, + "104": { + "releaseTime": "2012-05-02T10:40:54", + "sha1": "1267987ae92e7b33807f64cb878bd69d0237929e", + "sha256": "cfc17f996343fa607af6913804e7aee3a88ec75b70c5e95d5189b96fbadf9312", + "size": 540020 + }, + "105": { + "releaseTime": "2012-05-02T11:15:28", + "sha1": "3107da18680cc7a4c8da48a87987c6b54c1cdbd3", + "sha256": "fe79e721c75454eec6b9c4fea77f07ca5ed9ed6a5f89d7339f13bf665e9fe044", + "size": 540020 + }, + "106": { + "releaseTime": "2012-05-05T21:26:20", + "sha1": "073fe35f1465b042cc1a404ee162a78be07a3118", + "sha256": "699943f76f8eba5bece28bad466c2510513432b5916831d8eb873ba9e55f8f07", + "size": 540033 + }, + "107": { + "releaseTime": "2012-05-05T21:48:02", + "sha1": "5a94773af77831db154836b33c31b0572f906e2f", + "sha256": "450496d301b3a5929c833561ef860aa845fe42a48b7ba40628134cffd6324480", + "size": 540049 + }, + "108": { + "releaseTime": "2012-05-26T20:33:00", + "sha1": "91a5cb7e60c573c6f5700afc9a61dc987c90837e", + "sha256": "88b9d9050a889839ff260accfc1f2cb70320891b88f74f23ef7630000755e59c", + "size": 540051 + }, + "110": { + "releaseTime": "2012-05-27T05:14:54", + "sha1": "f14ac41dc2c3dfcbb31ca9625b0ddde5ee50e60c", + "sha256": "b421c75a9635633c2406779d94ac185fd907cba9e398d7f40d1397e9493111b1", + "size": 682378 + }, + "111": { + "releaseTime": "2012-05-27T05:52:26", + "sha1": "37ea7bd0a7a4643e405d1930306e0ae48eb6fa72", + "sha256": "844cf9d1a842f680c40aa64b442e08575ff14c776732bfef02fb836d7150336c", + "size": 692653 + }, + "114": { + "releaseTime": "2012-05-27T07:49:00", + "sha1": "6656816ca2a9b8ee781b21ffe397351c1cff242b", + "sha256": "7b4d0d01792533479630ec61caa056821d5faf49a94976de6809b5bc5ea6407d", + "size": 692890 + }, + "115": { + "releaseTime": "2012-06-02T17:05:10", + "sha1": "fa56c8a9ba515b4ebafa29a9d8b463844d8cefbf", + "sha256": "28376c420dc439a2972aee59fbf5369e4662abb9f4255f215efbc07aa43103f5", + "size": 699345 + }, + "116": { + "releaseTime": "2012-06-02T19:29:02", + "sha1": "a0bc1631878d6c82e90cc8c8428d531e616d0b4d", + "sha256": "3689d1c1d54d408872909b6864b91c16822f13b6c000aa6d4b7c50fc0ee103a5", + "size": 771433 + }, + "117": { + "releaseTime": "2012-06-03T00:39:56", + "sha1": "fad26f06303d49516f30bd9787c60254b9d64832", + "sha256": "0f6ab352cbdde133519af2446cb1e95596ee83bd7862d0396ce176fe6f58a289", + "size": 793622 + }, + "118": { + "releaseTime": "2012-06-03T01:06:46", + "sha1": "2417311461424c258b1ae75b3c2aca5ed8a93212", + "sha256": "750ce4702906336213c8cebf38f51f42ab32a5097b54850b8a9c2da6cba4f165", + "size": 795988 + }, + "119": { + "releaseTime": "2012-06-03T11:46:04", + "sha1": "9a729ba30e68d06dc1299bf7e2c11f0df2014076", + "sha256": "9eee8d3488c055f54741c865dba925ed0f20fc0fbc93beee930137dff6524099", + "size": 795981 + }, + "12": { + "releaseTime": "2012-02-15T07:01:32", + "sha1": "7a5585b8d63e14d27550a0caa326da98842ba75b", + "sha256": "bff27ad5c4370e4f1b83766f57f193cd69e9ee4918fec123230144f36fd0779d", + "size": 446491 + }, + "120": { + "releaseTime": "2012-06-05T00:26:38", + "sha1": "e46ce772d92952ed79f4dfc4ab3a401855f9ac45", + "sha256": "ac7b487bc153a2d0de283e644e5c573c4937d5c2ee436751d2e5d3f99a91bbbc", + "size": 795970 + }, + "121": { + "releaseTime": "2012-06-06T02:03:28", + "sha1": "4106e1a59253e2cc4ba3c553e1bcfd9363838215", + "sha256": "bdcc1bfa0bf290592de5da011b998b30b88b911a4e1d00ff4a2bd882eb1e1b96", + "size": 796825 + }, + "122": { + "releaseTime": "2012-06-06T07:11:36", + "sha1": "5e9dc2ee5aae4b6dbebc2d03200f0a2e36dfc6ef", + "sha256": "002c98545240753ae60a8e9f0d6067056332b02ab313e5da11749e2c68ab82c1", + "size": 796287 + }, + "123": { + "releaseTime": "2012-06-06T08:16:50", + "sha1": "b8e119c79d6c45a1f8b9816f916426b5015b2a03", + "sha256": "b7ebbaf7f9f6d8070746cac75659bfa55fe7007ec5f8297d7ea7ab4578a48dea", + "size": 796331 + }, + "124": { + "releaseTime": "2012-06-06T09:12:32", + "sha1": "cd06a21016af921260658e2bb72bac0278bd19f1", + "sha256": "3510025daeab7f07afe9f8c454d201c21a0256c00ce5944472291bd6986403b1", + "size": 796364 + }, + "125": { + "releaseTime": "2012-06-06T10:39:50", + "sha1": "730910dbf2756723b0bda64b23d1b86e6e2e360c", + "sha256": "00488c996a010a6544b0c9567cbf52576a09ca960a5071f0d0c96ed3610a3fa1", + "size": 796361 + }, + "126": { + "releaseTime": "2012-06-09T18:07:04", + "sha1": "f936f629b58aa9a26423e7d31fac1016df2ed43e", + "sha256": "c43a7b4dfd7fdf9ce1de709568323933d195ce5d091076183023221ea7868e9e", + "size": 798733 + }, + "127": { + "releaseTime": "2012-06-09T23:23:20", + "sha1": "277b3a9e14efb646541225de6fdb4ac22439a6c0", + "sha256": "8e6bda4d4c0b323729a158f11c8b384429eeb37c5edc770ded4d54c35a8e9345", + "size": 805738 + }, + "128": { + "releaseTime": "2012-06-10T01:57:00", + "sha1": "cf44068b9c694278dc56bf3e912bfb42915a0910", + "sha256": "cfa22e39605b31af73f9dcce17d26c575a5e11d878afaf27dc50b6237f5c05c4", + "size": 805907 + }, + "129": { + "releaseTime": "2012-06-11T14:16:08", + "sha1": "25c1928a77454207548479ed3365b9ac5b6cb724", + "sha256": "a346c164275e470e84e02547c5b78c1ecb9e7a5c273340f7f5722f3639a6cac7", + "size": 806759 + }, + "13": { + "releaseTime": "2012-02-16T20:12:54", + "sha1": "7d833787cd732c36183e83078d5059abf9d2d86f", + "sha256": "c2f2f379cc9eb550eb3db1eb36ecaf2f99fefa0ae34a6db3e565beedfddf7f79", + "size": 446490 + }, + "130": { + "releaseTime": "2012-06-11T14:45:56", + "sha1": "646de970a77cecb90cb4e95a0f20dcd6836ea427", + "sha256": "21e8559b168e199d00a8d107c89ed683b7e430690c2682abc0d510e850084b23", + "size": 806775 + }, + "131": { + "releaseTime": "2012-06-11T15:50:10", + "sha1": "e52706d1ffa3958da1d1ca7dbb4c98c6a91c00c2", + "sha256": "2a90471ccb7636fb65fe3604490c24e1dcb412236883a5d691586146636029c8", + "size": 806773 + }, + "132": { + "releaseTime": "2012-06-12T15:51:22", + "sha1": "c74ac5310eb0459799bc5916564b595f9c8a0558", + "sha256": "1610df104d38406d0f241918a893210503202d1a28f6510029ba612efa5abb1f", + "size": 806787 + }, + "133": { + "releaseTime": "2012-06-13T21:54:32", + "sha1": "9a765110a452eb1c729cd9d1dd72b75ac46a9cc5", + "sha256": "855ecc4c169efca986dea547ba94aeb52d6c8ca696aa94ef727351f92350ea23", + "size": 807737 + }, + "134": { + "releaseTime": "2012-06-13T22:13:02", + "sha1": "3859eb4e96ad8b596648c654603be8c7a2880aed", + "sha256": "237814d9e0f086c066659578fe42ff7cada5dd93b9a2fb9076551d5cac7ae22d", + "size": 807730 + }, + "135": { + "releaseTime": "2012-06-13T23:11:14", + "sha1": "7ca221567a9b8be19ed242cf3027ef85cb5831b5", + "sha256": "ca358444aca70dd229688f4f9aa5c69f6f54362f232f1ff745a15055137e6a72", + "size": 807734 + }, + "136": { + "releaseTime": "2012-06-15T21:13:22", + "sha1": "351d8168796136b453ff07ca3498d079005eecf2", + "sha256": "123c1e3e77f6709bf1074ff8186793ab1574ebb8c137d829a44757b46e1e593e", + "size": 820929 + }, + "137": { + "releaseTime": "2012-06-16T01:31:16", + "sha1": "43b5cedd31124e38d9ac45278f49c3c1b760bc91", + "sha256": "17380821b55e688afe499cd58e1ffa8d08ad1c5a6d0d709a0323a1ee8d615be7", + "size": 820938 + }, + "138": { + "releaseTime": "2012-06-16T13:29:30", + "sha1": "bb06fb63150c309298b5d13fd1386f815a8cb58c", + "sha256": "e7f981301aa518465c22530b8987ca64fc8ef732037ef1e868c7a30effee8303", + "size": 820935 + }, + "139": { + "releaseTime": "2012-06-18T20:20:22", + "sha1": "fa14db691e5caecf901bc03db26f62a41398f0bf", + "sha256": "3745c6f8ec04beb978d3ffefab8093233160fa16c44a14c77ec3ce23b4f864f4", + "size": 824101 + }, + "14": { + "releaseTime": "2012-02-18T10:59:08", + "sha1": "a2e9d478829c8eeef907a2e9fb026b7f7b06d503", + "sha256": "4d8639e623029834b8facb5e773a099ec9b5137e9b5c66acf8d38f9cf08213b1", + "size": 446490 + }, + "140": { + "releaseTime": "2012-06-19T13:54:46", + "sha1": "0393025b622c1963789de2de8cae76bb80a9a40c", + "sha256": "4aa5efe6548af749acdf3805fc6dbbcd78c1dd12f19bbff89e2bab84662242fa", + "size": 824100 + }, + "141": { + "releaseTime": "2012-06-19T14:33:18", + "sha1": "172f03f6df59bc600a325e2eed9252f1466218ca", + "sha256": "3b256df597d86d8650e808846d363e667dce2f467db84576397944fbc4d83522", + "size": 824099 + }, + "142": { + "releaseTime": "2012-06-19T20:50:12", + "sha1": "9bb6c62055657637755ebdfb2c01f1d5be4eb86f", + "sha256": "43661e039a129d00f44ccef4a383c134ba5bb8f66e22252576fd5ae8e91b349b", + "size": 742043 + }, + "143": { + "releaseTime": "2012-06-19T21:35:44", + "sha1": "55aae8a09af8275044e83731e160490e3f96e4f0", + "sha256": "16a65c0fc67a7b52df3bc09924ab9bd860f716d5134e3ec843779d2e2c833441", + "size": 742047 + }, + "144": { + "releaseTime": "2012-06-20T02:27:20", + "sha1": "7af758710c159b940e1a1acce61752b769b9c8c0", + "sha256": "e49b93b985344c3eb5fc0fdd84a3a410c271c713188a969585b2c30f8b1632b2", + "size": 828804 + }, + "145": { + "releaseTime": "2012-06-21T04:10:00", + "sha1": "4574a57cd18f729f3783569dda3414af955a5a7c", + "sha256": "ee338a711e8fdd938813ef85aac9018e510dcfda142e01af2c4d48f66de266f2", + "size": 833053 + }, + "146": { + "releaseTime": "2012-06-21T05:12:52", + "sha1": "a9434adf87ddbaaa0ee766a681796ec2c6baaa3c", + "sha256": "922fb4f5ea0d6c143a2fd7d0ec5b0e816239ada14330553d874bb82832608497", + "size": 833072 + }, + "147": { + "releaseTime": "2012-06-21T06:14:56", + "sha1": "e34ab34210f9ba2ef911a9d8261bee46e58d1181", + "sha256": "cd90d2fb96fafaebbd8832b82996718b2ce6687867c98b9b8b10131e5da0e6e1", + "size": 833263 + }, + "148": { + "releaseTime": "2012-06-21T15:33:06", + "sha1": "269b4dcf1895eb1c861a45596fbdf03a7d952b03", + "sha256": "e8553aebad4aba8f4a3501b7c66ca9ba9e1a72bcce1653943da2b5fdc02be2d1", + "size": 833383 + }, + "15": { + "releaseTime": "2012-02-21T00:08:16", + "sha1": "0c288624b936ae51e74849185db9456b0f6eaecf", + "sha256": "839d7cd8f71501ee7bd2f8bcbd05f9be15f1d28223ea92a7715e59e38f30ef37", + "size": 461232 + }, + "150": { + "releaseTime": "2012-06-22T17:50:02", + "sha1": "69992524b6dad50b7a1f134084d6723941600178", + "sha256": "b377f8001a182855709ef08f002d6426d3d1704b04a3abce7162f688628411bc", + "size": 834008 + }, + "151": { + "releaseTime": "2012-06-22T18:53:06", + "sha1": "390e254050b5d437c52fd3372a9bf5e7af82d190", + "sha256": "8ebc2bf8dd8afd0d17607df892276827cee6accfefe02ddbcdcc0d1fa622cc37", + "size": 834136 + }, + "152": { + "releaseTime": "2012-06-24T14:51:06", + "sha1": "3457f99c4572e65c0c453825131cafce62a403a3", + "sha256": "606e7e860725a3beac211c8814377be05fce2f0d4d31e6591a08a56124883e68", + "size": 834135 + }, + "153": { + "releaseTime": "2012-06-26T12:14:12", + "sha1": "a02b59b5eba868c9ef653e6372dabacff0d7c185", + "sha256": "f71fa6baf922ed05cf02d47dd55eed16e9d351b7aa9cd75be92623d278c2c6e2", + "size": 835486 + }, + "154": { + "releaseTime": "2012-06-27T14:38:54", + "sha1": "1aab062c85fea0f607b34a9aae213de23d557219", + "sha256": "aa20ffa2bc0395657185a58c32e51d23c6485fe9a11e49a6488d5db7c52474a6", + "size": 836032 + }, + "155": { + "releaseTime": "2012-06-27T17:24:36", + "sha1": "072165b010760b236cd60d9270e0ca691a0a1eb4", + "sha256": "e77a492dfd41732cd31ed066419247a12bbdad81a5035f082cbe559c3ee3904e", + "size": 835994 + }, + "156": { + "releaseTime": "2012-06-28T12:47:50", + "sha1": "e65ddb0a00327cc3042977dfb4b3cf7d2c3f9141", + "sha256": "69cffff633cf417d15def003152b1219deeac932905331e1e355a579de8d6610", + "size": 835993 + }, + "157": { + "releaseTime": "2012-06-29T14:06:30", + "sha1": "875565aa589b1c56332f3732f1830b5ada72f353", + "sha256": "b93a825687291259d9ecee57f861a92f876b85c974ef596498b25f27e2f82209", + "size": 835994 + }, + "158": { + "releaseTime": "2012-07-01T06:58:20", + "sha1": "a6d07ec81f663969efdefdb0da0a01c3bd7e61a1", + "sha256": "af68569fcabc2f46331e296e7ce6f4a38d664245dee702827c6f301f00f767b9", + "size": 835995 + }, + "159": { + "releaseTime": "2012-07-02T20:30:34", + "sha1": "1902fd2cee020fb0cc37323df70123c9f1ef521f", + "sha256": "8e95e919e287c486745da1abb4f4f514790dfa4e03a7cd667ff6dcad3b7ea950", + "size": 835994 + }, + "16": { + "releaseTime": "2012-02-21T01:08:40", + "sha1": "e122dd4424507cb886cfaf17d74d32f0b5c27976", + "sha256": "73913abfd6fc33e5fda8d42ed3877e1d6c7ebf693add23727450411ac48aeee8", + "size": 461230 + }, + "160": { + "releaseTime": "2012-07-03T22:13:38", + "sha1": "ffce964d80f804b44f41f9445720cca889df82e3", + "sha256": "428e96518a844bab63f7b7baaddd47fc83596a161827d0776ab95a3cf5e87c97", + "size": 840432 + }, + "161": { + "releaseTime": "2012-07-09T13:47:08", + "sha1": "9b577c7c90c075345c9edbbbf1e9e1b04d526a5e", + "sha256": "159f2f456214b343e12aebfd5f4c6a2aa25534f2de04ef1518c058d736a6dbcf", + "size": 840533 + }, + "162": { + "releaseTime": "2012-07-09T16:06:48", + "sha1": "0c2899851e84610ff9f68178d8982feb2994e30e", + "sha256": "addc741a97b22b20521f1155437215b04318e6a66bd5a65c8c132283b66efd1b", + "size": 841554 + }, + "163": { + "releaseTime": "2012-07-09T21:41:18", + "sha1": "75d6ec38c6ab0667583a5a7253004c739b8e628d", + "sha256": "1a5acd0213bd0e915b83b995ecdd99c0de9d1ecb1c1e732eb044fb79363a1059", + "size": 841544 + }, + "164": { + "releaseTime": "2012-07-10T17:05:40", + "sha1": "93be0a3149c333402a7696a23a45f4ffdb901ae4", + "sha256": "00e8168f96459964e97a37bcfe6c6f83f46d0825f00fbf96b8fec6d2439292eb", + "size": 841547 + }, + "168": { + "releaseTime": "2012-08-01T02:52:16", + "sha1": "1297549223eb2fcf39228b2ef9f572d8fb843dbe", + "sha256": "fed79cb7f26711043db245577f0b826b948cc2184219380b37277782604049f9", + "size": 841565 + }, + "170": { + "releaseTime": "2012-08-01T03:06:10", + "sha1": "b5076149dc1890bdf7df986d77b2a9f78b3873db", + "sha256": "ee62fb09ceebd3a73642a6ba9218f2323fb6f450246355d3a7dfd74b62e0d0b8", + "size": 841564 + }, + "171": { + "releaseTime": "2012-08-03T16:59:00", + "sha1": "65fe624282d24b03e2a35212f9ab6c5e3e10a5e0", + "sha256": "dd6f66865bf04b89fd80a5041c6f9e81e0caefd266097447c73d7e924f67875a", + "size": 841570 + }, + "172": { + "releaseTime": "2012-08-11T02:06:04", + "sha1": "c965a2b9ec9b32ca0570248c99bc1536cf264be9", + "sha256": "16b6cc8b3479318b8a4f438536622852fd553c191fe4a327f0db5d6568c1d48d", + "size": 1056844 + }, + "173": { + "releaseTime": "2012-08-11T04:15:12", + "sha1": "27de803e547a20deb519d1f4a46bda7b639ac0d3", + "sha256": "0e66efa38a4da2e2455701a6107116269c3c5a8110609c05ca54b95035480a52", + "size": 1062629 + }, + "176": { + "releaseTime": "2012-08-11T16:25:50", + "sha1": "c7dc3e0b343c0be64fe7158b05d48ded492c1c90", + "sha256": "dab06042d5fa6737c106d573c3f7ae7392674c1b955d9bf65964fa362692ddb7", + "size": 1068704 + }, + "177": { + "releaseTime": "2012-08-11T17:20:10", + "sha1": "32cfe2f9b93ee0d4cd02089f573a12dcbeb37fa4", + "sha256": "627cd1d8fcf661457cb55f96b83221051159d0ecd7423baacb7432c1893ba7f2", + "size": 1068703 + }, + "178": { + "releaseTime": "2012-08-12T06:19:28", + "sha1": "eb19f25f008fd60e23db74eb5fbae1fbcca48dbf", + "sha256": "bc4b85d4d1f1a828dbce1ad9a46e0dc4a258f32ae463007328802a4d9f959c7a", + "size": 1071601 + }, + "179": { + "releaseTime": "2012-08-12T15:37:14", + "sha1": "aee8717d6781530b2e311b89a0a71fcca58b71fb", + "sha256": "6ee6271971e179158f232104c7a6c804661d71b09633a58229bfa6e4ac733da2", + "size": 1071601 + }, + "18": { + "releaseTime": "2012-02-21T17:14:26", + "sha1": "e348ff6d988c61d98b8a560d7cddc965e2d81482", + "sha256": "a639c9d4f68aefc3c6fe8ed32081e41c67fb6a489a87bcf6a42030c24a1bd136", + "size": 461226 + }, + "180": { + "releaseTime": "2012-08-12T21:46:22", + "sha1": "10dcdc2ea96ba2b86836e67f5569f0f1b895cb9a", + "sha256": "2a48a0d307111333f0030f1799f7e6a79c0efdb30b214060b3bf290d26e77f4b", + "size": 1072919 + }, + "181": { + "releaseTime": "2012-08-12T23:01:26", + "sha1": "f42f43f5562789b2da8eda6598b3d5cfd63720af", + "sha256": "f930595914b8ec50f5e8d9a6bd2842455017fa0802e0a7e09a03a1464b4fefe6", + "size": 1073492 + }, + "182": { + "releaseTime": "2012-08-13T14:20:16", + "sha1": "649fb921f3209dee50991bb8785b245d33e878a7", + "sha256": "f488e3d262d9445b853c8560035d303b03099fe562c0401313e403a913eb628a", + "size": 1073493 + }, + "183": { + "releaseTime": "2012-08-13T23:33:08", + "sha1": "6b278b91c68e8b013ae58c5796c4e2cb9cec7c37", + "sha256": "abccf353a3626161ccb6efd34c93fa1bb3d388ef28662524fbe2841f531b7ff4", + "size": 1106697 + }, + "184": { + "releaseTime": "2012-08-14T00:09:52", + "sha1": "6ce09190d2660c7ca25f60bba02a3ea70072cc60", + "sha256": "d1786b21227630227fa0db5dcc451b690e8e4522dc8f5b108d30dd13728bfd77", + "size": 1106701 + }, + "185": { + "releaseTime": "2012-08-14T04:44:38", + "sha1": "5e2cba3e9e81c1ab11b10c2c47b5b010a06e921d", + "sha256": "324d235979e59bfcaf1a2573b921231357d00940c83c1346b926fbde9e90c19c", + "size": 1106693 + }, + "186": { + "releaseTime": "2012-08-14T06:41:56", + "sha1": "89b4118b59459c9643b3de32373303d04a27e5df", + "sha256": "e0f4a04188d3950e3de4131a394b354d551b657d1fadfd0297b16d708a8156e2", + "size": 1106707 + }, + "187": { + "releaseTime": "2012-08-14T16:07:58", + "sha1": "a9afc5ba72b8224a91cdedc4f10f47ae5eecbe3e", + "sha256": "cc52a1c5cdf0539e86fb83535e30ac21d14d2bd2083c3667edd177101cbec94e", + "size": 1106910 + }, + "188": { + "releaseTime": "2012-08-15T01:04:26", + "sha1": "a8526b0b84ba5d853cacdb25a568a926e90f5674", + "sha256": "6f378334e5aff66e48d727e640db7c49067c932cccac018b333a8061870b1409", + "size": 1108814 + }, + "189": { + "releaseTime": "2012-08-15T02:00:36", + "sha1": "4ee137f2a60010981a021cd39705b773a86a342c", + "sha256": "999c0cda3d1f98cf1cb1ac3eea80ef2029d44d0ab7f200971453415c26383a6f", + "size": 1108815 + }, + "19": { + "releaseTime": "2012-02-22T12:45:24", + "sha1": "a543b0d8607847ab739ad0b4bc109d8b5eb9e36d", + "sha256": "9863223a74fb8b09a6de07818708c52113b951852b8354de2139fe24689a900e", + "size": 457000 + }, + "190": { + "releaseTime": "2012-08-15T03:59:52", + "sha1": "7c8e296dd20d0a099d4ffc0ed6aa2f528844c098", + "sha256": "32b390a19cafc75c66292c547fde2349326a93e0df4db261a26ce34745a77c00", + "size": 1114702 + }, + "191": { + "releaseTime": "2012-08-15T04:20:00", + "sha1": "35c3abea886ffc85f00234638953b24c52feabc8", + "sha256": "9c93b994cf3627833efc96d0b659aa11e4d65389f5cb03966a3c564a336799e0", + "size": 1114733 + }, + "192": { + "releaseTime": "2012-08-15T05:32:22", + "sha1": "3bfce4ff38d083e21ac7565435e11de73a1355b3", + "sha256": "6ee2d016c435d16d5025f50cf2fb37a6ef849627f8cf88d9df498a2591ffd15b", + "size": 1114783 + }, + "193": { + "releaseTime": "2012-08-15T05:41:58", + "sha1": "6f9560278fbf8ba6448aae4e9e314bfdd95f66d0", + "sha256": "437689a1bdd935a29ba5dcbc9883e1c0c014a8686fa40672115a4699dd3c7c3c", + "size": 1114790 + }, + "194": { + "releaseTime": "2012-08-15T17:07:10", + "sha1": "15506c8f8035238775e48c7f2b1c9604a7237567", + "sha256": "30cbe1c1aa0ae1c694765f044801cd9e041078f4e47938c26a8d4e4f5d174e68", + "size": 1116652 + }, + "195": { + "releaseTime": "2012-08-16T04:18:30", + "sha1": "8591aea55c6452626abdfef9a710f2912b071496", + "sha256": "078ddbbad79ea0a9c8fd4d83560a24b27fd14dbc0253b15811c6db3954517d21", + "size": 1117510 + }, + "196": { + "releaseTime": "2012-08-16T04:26:12", + "sha1": "4dc7d314e1d7e815745298d9849f16326d98a4cc", + "sha256": "82a2747bea9aa044ddd384e40229f4380e66544a27c77ff8611f0796571db3d2", + "size": 1117510 + }, + "197": { + "releaseTime": "2012-08-16T04:39:20", + "sha1": "06d558e96e443cd20f28890f60bd846b24a89345", + "sha256": "3bf063bffccc8203c8bb9b16410e38b73d7d061516fabe0d55d8ebec9b3d8341", + "size": 1117510 + }, + "198": { + "releaseTime": "2012-08-16T04:45:46", + "sha1": "ad7c3988568eba9b0a6fb28008fcc2ae7d492baf", + "sha256": "9a06b85b20fe04ce9dee8ddcdcb2984631f97dc277158cdd7dc00a7399d8fdf2", + "size": 1117510 + }, + "199": { + "releaseTime": "2012-08-16T06:51:58", + "sha1": "a43116a04d2653b21cf1482ab3127f5f2e1350df", + "sha256": "cd3f5e0c8052b1323f02f6fe95caecc0001faa1e4b7197e47d7938870c23697a", + "size": 1117518 + }, + "2": { + "releaseTime": "2012-02-07T03:25:24", + "sha1": "17729ac3f56a9c6b19884b0b9f6176c01b6577c9", + "sha256": "ac32701e81a26d81bde327648a11238bb252852fe47ebf5f1f1ba7d2e89732bd", + "size": 410393 + }, + "20": { + "releaseTime": "2012-02-22T16:59:28", + "sha1": "825fce2c50b8982ff8dc55c1726f809b355dbac0", + "sha256": "8435098217c1525f78fd0d496e7297925a3f19a0e3a5b1cdcac228ac4287f3c7", + "size": 460010 + }, + "200": { + "releaseTime": "2012-08-16T14:50:56", + "sha1": "13cd134bd2c71e8559485cf1f3ffb1bd6fe8db36", + "sha256": "7623739f26a54d6921459194e09019e5f0a1697aa84f6a73360dfd81f89aa179", + "size": 1118509 + }, + "204": { + "releaseTime": "2012-08-17T08:15:06", + "sha1": "44a706ddf785343411c042e1117b2514e6bb81a0", + "sha256": "02be25f1ffdcef9d1df61f4a5b7c72a2801c485b092f218be0fe534bd5f34df6", + "size": 1118645 + }, + "205": { + "releaseTime": "2012-08-17T14:36:38", + "sha1": "2dcd664c9f3d49e775139059def2fd34f473b500", + "sha256": "cc7341808da6852fe8f911faae63eb3fc15f29a0041be3054d719cdf0fd94c49", + "size": 1121958 + }, + "206": { + "releaseTime": "2012-08-17T15:11:38", + "sha1": "9dd3cd02e41d6ebdd4f4e6a27b8c623f1669f15a", + "sha256": "ac6522e7e98fbd1b3434d8cf017b6c99b410d2d9e9cebcaa21eccd22f41014c1", + "size": 1122529 + }, + "207": { + "releaseTime": "2012-08-18T00:54:36", + "sha1": "cabf2158a95d36514ac42877df9b324ff82cc692", + "sha256": "54554e8040ac82a63177c3c3f06b037076a1c4a74acf9dae8fbe143d5ab36726", + "size": 1122552 + }, + "208": { + "releaseTime": "2012-08-18T03:20:28", + "sha1": "6bc793175417d57ee6d8fe2953e80b622e51e30a", + "sha256": "0d4c2c845f26f03d05465ecc9d4dfe89e645d7915ae09d380724b8aefd4ad73e", + "size": 1127644 + }, + "209": { + "releaseTime": "2012-08-18T18:31:40", + "sha1": "1e2a7d448a81df1b87b92df5d7654c3b773ce3cb", + "sha256": "0a60f96c58726818a01b3e12d34ee2e64eaa52ab891be28b27319bffa3b25f24", + "size": 1128219 + }, + "21": { + "releaseTime": "2012-02-24T02:44:08", + "sha1": "a26524032331f99cc199c949845d9c21f7ca6220", + "sha256": "a763eaed63cc63795e147ed7fc0e718d50ae884daa0fe6344e2eadae04532716", + "size": 461387 + }, + "210": { + "releaseTime": "2012-08-18T19:06:16", + "sha1": "fb8a39877182075057ab635988a716779ce3c1df", + "sha256": "6e960c40d5ae23921b57dbfde8c90b3b3837219baf046aa110e35041f0922d0b", + "size": 1128955 + }, + "211": { + "releaseTime": "2012-08-18T22:11:36", + "sha1": "8bac076be4e2b1ca18bbc4a5a6dbf428ffe8a000", + "sha256": "de42413d21d609322a5601d5d461f9814bbf04142035a38035af614eede96bcb", + "size": 1128948 + }, + "212": { + "releaseTime": "2012-08-19T00:24:18", + "sha1": "660b131b8c7b5847928325495107d2bf18fc6252", + "sha256": "f4cc8b5a713a14e5712f5e981e9cdcebe1aa79b2f83719a67851d088a19dd176", + "size": 1131604 + }, + "213": { + "releaseTime": "2012-08-19T09:40:06", + "sha1": "a343280c7a069b665ad4892f1fc3efc0204ba273", + "sha256": "3068b0a7e105b7a3bcc40b04836735295c4932bf4e3f41671b00876523111fc6", + "size": 1144787 + }, + "214": { + "releaseTime": "2012-08-19T18:45:34", + "sha1": "9c7461c292717660c860c9dde3a998f80c9db3f9", + "sha256": "df7e911eca3b02cdb53f20bc25e91ff64df2b74e6485703a00834c4ac87949c8", + "size": 1144823 + }, + "215": { + "releaseTime": "2012-08-19T19:03:28", + "sha1": "772542b3aa274c40494aec474a9801e86e832bf3", + "sha256": "4ce688bcebd13c5b3ab37ed9a4ff3f8a8c315f2ddf3495e226e3f1edb9e757f7", + "size": 1144429 + }, + "216": { + "releaseTime": "2012-08-19T21:48:20", + "sha1": "34b05962c8aa58a60420d3276598a3e236ff5faf", + "sha256": "b01354ffa8e7b6f09ba4b8d6b37e2ede984e8bea64af23dbf44ab0905083e710", + "size": 1144496 + }, + "217": { + "releaseTime": "2012-08-19T22:10:42", + "sha1": "1abb0fac2833326264ca74c84b781e7044d52c26", + "sha256": "98ab579eb3ff4253770b676106619a542b27ddc526111bc956dc48d0bcff2339", + "size": 1144596 + }, + "22": { + "releaseTime": "2012-02-24T10:53:16", + "sha1": "f4f11608f49cbfeb025afbb938081540415fc9fd", + "sha256": "078689fbc3fac7d8f5496a1d8a22176d7637e9df7bd11a330727cd7879fff304", + "size": 461389 + }, + "220": { + "releaseTime": "2012-08-22T11:11:14", + "sha1": "0909743af1123f6fe96e01bbf67e4117dd2bb6a4", + "sha256": "d15f10ef045f95d18b7d3dbdcda06cc92148ddae9b21f5e949fa5666bc7ab7f9", + "size": 1156840 + }, + "221": { + "releaseTime": "2012-08-22T14:47:48", + "sha1": "17d16a72551dafcdb66cd8a2c2f1fd7ce5d9b202", + "sha256": "d84a778ddcfd327d3bb91ea80ad8b06c155659380d840e70dc2e4a4ad145c489", + "size": 1156896 + }, + "222": { + "releaseTime": "2012-08-22T14:51:48", + "sha1": "9134a4885e0dbd08d7a9c1b12f5900d1f3f5f7fd", + "sha256": "5b293663cfd379dee0941000331095230b77268bd0a930aee2ea91afacd309cd", + "size": 1156900 + }, + "223": { + "releaseTime": "2012-08-22T16:18:02", + "sha1": "dd89de55a4a0eadddd93a16a67eeab8d2c8e9d00", + "sha256": "8c838d0962c35b7b21dba8ba153241b7dabd30b6202a428f8763eb9951b3e991", + "size": 1160119 + }, + "224": { + "releaseTime": "2012-08-22T19:08:34", + "sha1": "7cbef6b2618c7b05af1327a0dc9d83205ddb47f2", + "sha256": "62348b5f57a64a386387f229f7ff43fc5ba28f3e3fdc0827d84404e3f680a19e", + "size": 1160691 + }, + "225": { + "releaseTime": "2012-08-22T19:38:16", + "sha1": "60d5a20dce93496201aabe29eab2cbd6e1ce7697", + "sha256": "9f587e629d1f68a92c2e908999a08f892bf8082e31a68dd3fabd01fbd93a718e", + "size": 1160681 + }, + "226": { + "releaseTime": "2012-08-23T07:24:58", + "sha1": "45c32c24fa82f2fdc58137ea2f0f91859bd99d02", + "sha256": "ace28642c14b394070c3a56069e67e380fe2374faf830953144ff820f34a8a89", + "size": 1167077 + }, + "227": { + "releaseTime": "2012-08-23T11:58:40", + "sha1": "efe8252c1f118e6dab54ddd3f718270dddfc7fab", + "sha256": "67c9b58b826939fd6d77f2f16a83df317dc2625aa43dd896dbd4bfb56ebf933c", + "size": 1170150 + }, + "228": { + "releaseTime": "2012-08-23T12:13:40", + "sha1": "8657c475ea0eaeda5c16af9098d07d26fa5780df", + "sha256": "0338dab67d7e77926d9e7ce407243f9b534798b83d6e57e17c57d25195888ced", + "size": 1170172 + }, + "229": { + "releaseTime": "2012-08-23T17:57:20", + "sha1": "7d706d763865779048b5cb612617f77947089c41", + "sha256": "1b98bf38c67a37797565caa5199921a50d3a516688fd5bc888ba9e4ea3b8363c", + "size": 1172234 + }, + "23": { + "releaseTime": "2012-02-24T12:49:32", + "sha1": "eb953b9fa97348e07e073b9013ac8c077f3af32c", + "sha256": "368ebff3d647b3d815395e1cb2ff6517414cb692bd25fa47d9f52cecbf80b0ec", + "size": 461398 + }, + "230": { + "releaseTime": "2012-08-24T15:09:36", + "sha1": "1d31483af924041f9737f21323152328a8ada6cc", + "sha256": "b41b781d5c9fcf05798790ae20ae593dc33f588975b8db88be13b0ff09d2bebb", + "size": 1172239 + }, + "231": { + "releaseTime": "2012-08-25T01:34:06", + "sha1": "398aa064fac7a8711bb611f34abee9450be7e426", + "sha256": "9f157b203662140d71384be689c3fadbfcc2bdeb8887085f3a0eeeae17c497e0", + "size": 1172327 + }, + "232": { + "releaseTime": "2012-08-25T07:15:30", + "sha1": "ab0fd12b1ce77ffb6ac24b1ebadb883087200e52", + "sha256": "c39d6d53e2ce7608f0c4263d23a0ffa59824ad767a4df0faf34f5ea4af525ecc", + "size": 1172236 + }, + "233": { + "releaseTime": "2012-08-26T11:34:16", + "sha1": "807402e42a377050fdc551e021ddd3130a6a3eff", + "sha256": "00a042267454a09179b30569dd2da4ae715d7d7f695a34afdb6cf34e5ab8b214", + "size": 1176543 + }, + "234": { + "releaseTime": "2012-08-26T20:35:54", + "sha1": "0bc0f8f52db177d403cc6aa7f74ae8ab341bc6c4", + "sha256": "b4e952468b1c690213d95885ee0c71c5c0323d135158fbb1e6ecc54565ceeae7", + "size": 1181438 + }, + "235": { + "releaseTime": "2012-08-27T21:50:54", + "sha1": "9406efb776d6317ab2c99a686d9eb32c724bdf45", + "sha256": "6eda7136f7c8c4c29fab4e0bf91989712f84cd5c5d5bf6512efbff5d2de9027c", + "size": 1181419 + }, + "236": { + "releaseTime": "2012-08-28T00:59:14", + "sha1": "40a2c71e07d6c108f4e70ed2f5e80669c03fb549", + "sha256": "302ec33f3f3e7a7101a8d60558d1cd43e491324056a46bd097b69d5281e7141d", + "size": 1181495 + }, + "237": { + "releaseTime": "2012-08-28T01:10:16", + "sha1": "8a9651513e473b3e70e13e14b44cdc799523a5e0", + "sha256": "8f4a4eaed30fa8b8bb9a9d83954fd33e8914a09f8c01202c38055286c995da88", + "size": 1181512 + }, + "238": { + "releaseTime": "2012-08-28T17:40:02", + "sha1": "3b5931dfa33f19686e14dff03e2851a7f6bfc8bc", + "sha256": "fee9770baa979f27a089d9608cfd60624000725290af9fb24108f8b26b22b756", + "size": 1181524 + }, + "239": { + "releaseTime": "2012-08-28T20:46:12", + "sha1": "e5d8cb507f2beeb472e966e8a117a3f28f38fe91", + "sha256": "4e99138dd45dd037fef09cc7f0116d82c771b3c9b6dad9d0796c0e9dc73f8b29", + "size": 1188988 + }, + "24": { + "releaseTime": "2012-02-24T22:19:12", + "sha1": "a3296fef41cf016dfe4133c5f284d88218897c6c", + "sha256": "f285d1a5c6f500ca137bcd34ab95453798400c65b429354b24efdfe6102fc9c7", + "size": 460666 + }, + "240": { + "releaseTime": "2012-08-29T13:46:12", + "sha1": "e7a49134aaa40d28432616a9ae1c216489403a9a", + "sha256": "230c37e867963112a9b4202d91bd0ce3dee6bc30d4d528e35eca81d9d35b3d72", + "size": 1189119 + }, + "241": { + "releaseTime": "2012-08-30T13:14:40", + "sha1": "cc37f754904050111c21a85d5554ee8032329c9e", + "sha256": "2d04f456b42c2c748f27baf2bda69bda316ed3a750eb501818736545b3057bba", + "size": 1189119 + }, + "242": { + "releaseTime": "2012-08-31T15:29:00", + "sha1": "27dc3883f07f26237a77372388b549efde958fc8", + "sha256": "ce40adcbbada923db4b7df1ee4d3a9145f83159945df97218b418a2dff903975", + "size": 1190637 + }, + "243": { + "releaseTime": "2012-08-31T15:40:00", + "sha1": "2846ba941a4e2cf5fe46f56e2fa465bb8eec7d2c", + "sha256": "93d67db0f8afbcdf9bc2d17e16a912925c578b1ccf52924a76a110e2ee6a290b", + "size": 1190764 + }, + "245": { + "releaseTime": "2012-09-02T11:15:32", + "sha1": "02e1248f238bbfc8e96be69adbd1213ae64cb595", + "sha256": "94d80d34a4f7ba7586c9f5e41cc846d6d9ccc8fa4c04a0abc7fc12ca7995cdb7", + "size": 1191348 + }, + "246": { + "releaseTime": "2012-09-03T20:30:50", + "sha1": "b8beb94f7491aab93a7227567c1a9fbfdf6b20b3", + "sha256": "983bfa9e67de68e8cb1a691075efef777e5c44e738d0e9a46869d4b84bf84f6e", + "size": 1192956 + }, + "247": { + "releaseTime": "2012-09-04T17:29:10", + "sha1": "4512823cb1bacd1e973e17c89e5cba03c1154fa3", + "sha256": "96727df14ddfe9a115490fe6a94c35848c1ca5019fe8929f676af1b6000aab4a", + "size": 1197219 + }, + "248": { + "releaseTime": "2012-09-05T23:25:52", + "sha1": "fba13830753463a40593edd07ca73c3eb1710cdf", + "sha256": "f01717142dbe7d2c09baab684c937b8c665df6f7d7f47c98f0b68eca0e3aeb7d", + "size": 1197218 + }, + "249": { + "releaseTime": "2012-09-06T21:09:10", + "sha1": "9123f06fc28d3d9d1347a012a1f490265384f70d", + "sha256": "fba2dec051596362f8a32bf6ec571b158f3363ad1fc1c10add548e529a2d4f56", + "size": 1203819 + }, + "250": { + "releaseTime": "2012-09-08T19:23:28", + "sha1": "64f1ebb51653de5e8c43851d58d760511076d283", + "sha256": "47442a0d27aca2e560329369e1c3c451868b9b3de6cb7c2a56c0198dc5dd2c37", + "size": 1207099 + }, + "251": { + "releaseTime": "2012-09-08T22:53:32", + "sha1": "47842089e4e19de881446c452fb7c13a4870756b", + "sha256": "d50d6b69d6124fa9fa75204a8dedcc761bc5331ffa721b59b24e0229974d0ac5", + "size": 1207098 + }, + "252": { + "releaseTime": "2012-09-09T11:39:20", + "sha1": "ad02718c6ca50313953afd8943ba8ccd8b61030d", + "sha256": "6584a2719b4e67ff3dc6b967730d10dff698b7ed50900c6a47331bda1d632a50", + "size": 1207177 + }, + "253": { + "releaseTime": "2012-09-11T13:51:04", + "sha1": "d224df2f61e8492cb8bc4cb6bd7f5b182ca75892", + "sha256": "285422a2b343cc0357b2bba12d6cdf934ac99aaaa2bbe82522598fcd81ce4434", + "size": 1207304 + }, + "254": { + "releaseTime": "2012-09-11T16:30:52", + "sha1": "48c4dc2d0d599bf586ec3631a73194bfcd760cf9", + "sha256": "4f6d04fe16a1bc1ae7fa0b9e5cd85627c72373682e7ae10ac43e8ad835b74c15", + "size": 1220519 + }, + "255": { + "releaseTime": "2012-09-11T16:55:22", + "sha1": "86cc35abd26f0e51e1f75c0cf5df7afe2fa37619", + "sha256": "eae12bb6dee60dc7522046e01d1483fd53cab07cd6b31cdaf12fec31e2204074", + "size": 1220564 + }, + "256": { + "releaseTime": "2012-09-11T17:13:10", + "sha1": "31736f46042ed8d674f4a5b6d07381cdf416f29f", + "sha256": "38f8d4a6132342bb263631bdb6e4e917321ab110d6b9ab14d889205e4c1f1bf5", + "size": 1220577 + }, + "257": { + "releaseTime": "2012-09-11T18:39:00", + "sha1": "c24ca8adb810e4ded4fb3a5a8e96c5dafe36b5a7", + "sha256": "c1d924bd6379b514a78ba1d6e6730d4c40ac4d6c7600acc79f1a1cab1a06fab0", + "size": 1221666 + }, + "258": { + "releaseTime": "2012-09-11T19:33:50", + "sha1": "c3bcb792058b55f7c4fc2d1bf08bc56eefe7a502", + "sha256": "62db5c51dee86894e5695c277773f03a1df4d5f8a228a71122e18ef21cf8a221", + "size": 1222130 + }, + "259": { + "releaseTime": "2012-09-11T20:20:30", + "sha1": "f5f059fa094272cc57a37b29e1f497d7b160723e", + "sha256": "493e697ffdddf636f072d7278c71fad04010a5a30b0aae18190bb27de37b986b", + "size": 1222138 + }, + "26": { + "releaseTime": "2012-02-25T15:44:56", + "sha1": "2f32d8d4fe7ff21a1134cd2336d292e44e3df4b2", + "sha256": "7af8a2d502bea9ad6e5559006a1e92a08401f2dcbdeeb7ddfc10c651c191139e", + "size": 460674 + }, + "260": { + "releaseTime": "2012-09-12T16:02:58", + "sha1": "d94a9fdd3695659255dd56efdf28971526befdbf", + "sha256": "37e34c0b3ad569cc11e9ec9d55b82bdf78e9306df78180379af1f0c03dc32719", + "size": 1305620 + }, + "261": { + "releaseTime": "2012-09-14T23:15:18", + "sha1": "de533442b141f1c250b17b93e111a30d057c02e1", + "sha256": "ea5593702bf95ac0373b9e926208aad24e05c947bc92c6cd7b9e1cc059063f9a", + "size": 1308626 + }, + "262": { + "releaseTime": "2012-09-15T20:51:08", + "sha1": "a28028cfb93f2616090a6dcbbfa16c8b96c140a6", + "sha256": "091a2a3a14353ec147b802052061477e82b96bb493b98499318b2c207aea0b30", + "size": 1313382 + }, + "263": { + "releaseTime": "2012-09-16T21:40:46", + "sha1": "30a7c5124f1d0a4f5f4bfaf6a8777c3247a220ff", + "sha256": "9286c9e90aed43ccc94ea88b61ded3fcbfcd09fd5b27b37cf4aa7ed1a58602de", + "size": 1314342 + }, + "264": { + "releaseTime": "2012-09-17T05:44:06", + "sha1": "6c785d1017bee9dcac4239749f7ac96495885365", + "sha256": "bbc74e6e951e68c94637a3a26a28e7a67883e91e5baecb82f50a0225aeef8f02", + "size": 1314347 + }, + "265": { + "releaseTime": "2012-09-17T05:59:50", + "sha1": "145240e8eef335df7765a42eb7433d7e9fe442f9", + "sha256": "779049bc88685d694db6d63749f34182211741918b0fd2730a91ac5d29467bad", + "size": 1314351 + }, + "266": { + "releaseTime": "2012-09-18T20:27:34", + "sha1": "3f346ded27f95dd013744fe3cd6e0c2d96c10b3c", + "sha256": "ce136d679ff863568703972c10dfe9d1d75160d4f26e01d7e8bcad0604a4fedf", + "size": 1316175 + }, + "267": { + "releaseTime": "2012-09-18T20:51:16", + "sha1": "8d73f34e62b70f7a88613a0308515cfbd77bfb34", + "sha256": "153609a14494ec17e74d914a9ef4a6a94a242fbb9e03b8dccd2bee4387333513", + "size": 1316171 + }, + "268": { + "releaseTime": "2012-09-18T21:03:10", + "sha1": "b9e7741f51d647af6de525c671270a636f8da77a", + "sha256": "4a982c7fc6181a26a846226152ff8db1b7fb3c716cd8523afb3e1e9a01370373", + "size": 1316170 + }, + "269": { + "releaseTime": "2012-09-18T22:35:02", + "sha1": "6025e36e12dfdc67aa5d5679fe43fdbb31b5a992", + "sha256": "6ed3322fdc785f23cbc32cf38a66301629bbd9fc21254ecccd6633cd3ffe5f6c", + "size": 1322458 + }, + "27": { + "releaseTime": "2012-02-28T18:57:58", + "sha1": "2d31fe2db3a0a1d3e4112b8a7593799b0000508b", + "sha256": "91df022c75d4ad218ff54bb397c8202da1b2c55ab0c75675f2e59502e197d0d2", + "size": 464730 + }, + "270": { + "releaseTime": "2012-09-20T19:50:52", + "sha1": "0c405297d5e32d30edc90eae9b1284d4e93758b4", + "sha256": "ce3814fafdc9e8f1d3c9ed2a3d8695c572d3b12c89de75596f4f9cf962ac6b91", + "size": 1343909 + }, + "271": { + "releaseTime": "2012-09-20T20:59:58", + "sha1": "6ccfb512d6f87bd37b6e85199d3789f548c53cba", + "sha256": "84d316aba81569e4fed43dc1831c32eda9d626471d22f1f04374b49ca3a5dec6", + "size": 1359878 + }, + "272": { + "releaseTime": "2012-09-21T06:40:22", + "sha1": "4557fa3fce875085402a53f74bd1b05bc0efad7f", + "sha256": "15d585a5dd3c667e33d18134115f223a5ec2c151fc25b968abf1e7d635ed83ec", + "size": 1359876 + }, + "274": { + "releaseTime": "2012-09-23T17:58:06", + "sha1": "6ec0b6f483df744accc5dd091a80b5948e63b8ff", + "sha256": "194acd06120c5669d440e7276b36bd30c1370d00118e9a389c801b92b800f069", + "size": 1359855 + }, + "275": { + "releaseTime": "2012-09-23T21:14:34", + "sha1": "e1da8d4fbcfb21627ad727e486e5fc176226567e", + "sha256": "797ca0b72c9405424e9cdb9079994ecdc94165b452fa3770ff1b404a607ef7b0", + "size": 1378357 + }, + "276": { + "releaseTime": "2012-09-24T19:17:42", + "sha1": "c8e7be4ed777f9eceac85775df2931a6e3930566", + "sha256": "fb39f7a37af11c00ec79c1c50f9cd0356f49c3886c03a3a85e0d84db5cdde3dc", + "size": 1379400 + }, + "277": { + "releaseTime": "2012-09-24T20:13:30", + "sha1": "14c6ec0bfff30f2a64c4be8c08fa19362e41e791", + "sha256": "31af93738a346fae8a8eb545625d57ef39939987dc04b2f0fa0782abe091d7c9", + "size": 1379499 + }, + "278": { + "releaseTime": "2012-09-24T21:20:46", + "sha1": "cb49775fe4c7e4b3ad8cbd0e545465d4554da3b5", + "sha256": "04c066b977f7abbe0c9a5b615de5c6cfc4bc8a59f701fe37f7b20f980e95b7de", + "size": 1380176 + }, + "279": { + "releaseTime": "2012-09-24T23:38:40", + "sha1": "7d61712d0a659e852ac966948dee1c9096437584", + "sha256": "e269294f5399aba12dd8bc55b0e14dd3397f7024e4c568f9de1389f74d80f14f", + "size": 1382733 + }, + "28": { + "releaseTime": "2012-02-29T02:33:32", + "sha1": "35151035d6694f7e58f2a38b86ad41605ba9eead", + "sha256": "29de2673b5b22b782d8cef432883f651ca295613fed51d1d96ff22a337ed0a66", + "size": 486646 + }, + "280": { + "releaseTime": "2012-09-24T23:52:36", + "sha1": "47743796a00274d650c48426e8a1cd4e7974717e", + "sha256": "5848521978f5967a995d16844ce50e5e260abfbab0311fd6f02f2dd21f1197d5", + "size": 1382958 + }, + "281": { + "releaseTime": "2012-09-25T06:09:10", + "sha1": "1138df5823018374c2805f381007002568812deb", + "sha256": "aa009dc61289bf4cd4616974ba15e2246ed562391952e925fc4e4d3a3290d61b", + "size": 1382960 + }, + "282": { + "releaseTime": "2012-09-25T07:37:12", + "sha1": "b9204db9e55c707c123ef96c34bce982cf6ac6eb", + "sha256": "8560e9cfa84ebd08812e6c81774103074c8db8bfb371f1b8fa7b52a5994a40bf", + "size": 1382961 + }, + "284": { + "releaseTime": "2012-09-25T19:51:46", + "sha1": "d041d3886bcdb568b96852fdc5cedcfcfabfd2ca", + "sha256": "57ef413d7562f44ad3125755ab31b3c9c60d909d0b90a89140ce6dedf6cb4a5b", + "size": 1383332 + }, + "285": { + "releaseTime": "2012-09-25T21:10:46", + "sha1": "1f7ab01768059ce5928fb0b6f1a527aafa4fc8d7", + "sha256": "f251c87ed68ae655567900f9e960eeca02daa1bf3aabe7bbb342093608824c5d", + "size": 1384679 + }, + "286": { + "releaseTime": "2012-09-26T02:49:22", + "sha1": "728b7e377c5f9bd0ef9ec66b382665f9b83340bd", + "sha256": "282808cb91384574aae591926cc778ed3a91eae18923eacfde99f3bb1ea31c48", + "size": 1384692 + }, + "287": { + "releaseTime": "2012-09-26T06:56:34", + "sha1": "fd68f31ce6d9e798d39eda31bc8a6ed3840bf036", + "sha256": "daf830444ab50cb61393843d6f489f7d358e09cb4dca5da72e5faa28bc66d416", + "size": 1385394 + }, + "288": { + "releaseTime": "2012-09-26T13:23:24", + "sha1": "f9943e9a126373b4afa55664f3ef882c8b02e4c3", + "sha256": "fbc87e2b5e473841cc5227856f71fdacfe76ace73fbf69ce003df8de322bae3d", + "size": 1385418 + }, + "289": { + "releaseTime": "2012-09-26T18:59:40", + "sha1": "1b91b9786878ac44121db168bd6163faa005be02", + "sha256": "fd1c33323f1202c5010c586091bd6dc5a4fca7718547b6475bddc17cc7227813", + "size": 1387742 + }, + "29": { + "releaseTime": "2012-03-01T09:43:22", + "sha1": "24afdde48a82edef65f089d7e98844444d6f368d", + "sha256": "deff2dee5718547a537148eb24f6130e6b145a360d3fbe82ab4c52d59d72ad6f", + "size": 486658 + }, + "290": { + "releaseTime": "2012-09-26T22:23:24", + "sha1": "038de0718c800c605deda3cc1ea63f1467cc0d85", + "sha256": "47118979ecc3f2c36d36b9d70bf96a5881837008b05aaa45a63c5206b203c6c2", + "size": 790109 + }, + "291": { + "releaseTime": "2012-09-26T23:17:06", + "sha1": "065b1fe40b67ddd5d8bcf14ae9f1c5596f75713d", + "sha256": "073b76291ab2507af08eafb1b61b4e9faf6d22ad62e3bac396f95b9aed68a216", + "size": 1395063 + }, + "292": { + "releaseTime": "2012-09-27T21:42:56", + "sha1": "a679d1084c73429a77c4ffb50b97ce777b4609b4", + "sha256": "3acd92ea7648db24593c114ce5686a943461febc01201ce5b9d7ee23cdfb524b", + "size": 1396837 + }, + "294": { + "releaseTime": "2012-09-28T01:06:32", + "sha1": "64f6f140b33e9e5f19875173fdd320287797e684", + "sha256": "0cc8414d0a807bfede8f5795b42e45bf841da38a52124335fda658403f75acfb", + "size": 1399300 + }, + "295": { + "releaseTime": "2012-09-28T22:40:30", + "sha1": "93a98657e5bcdfd5649f01f692f58c22da0e47bf", + "sha256": "94fb922756e6d65dc1f33b0ba3d55cc1a7b1164ff288be326459e710f859054d", + "size": 1403212 + }, + "296": { + "releaseTime": "2012-09-30T01:53:04", + "sha1": "fad0d621171c99f9caa0f41e123a58024f0e35ee", + "sha256": "024878d93bc75e2da4ead3658a1d100f613f6c9db5f453b31804b4f9826334cb", + "size": 1403299 + }, + "297": { + "releaseTime": "2012-09-30T02:05:30", + "sha1": "47e7ff030762ffe8e6ed354a119a08123a9173e5", + "sha256": "b11d5af17c75405368034f8e25e0a6f5e8ee8cd51002ceea0d6325b9e40bd880", + "size": 1403379 + }, + "298": { + "releaseTime": "2012-10-01T20:00:02", + "sha1": "4916d49e40f4fa54166886bac140355aef3566c4", + "sha256": "4950ddbed97db5e1c206117360ebcc5476d8766de01ff81a14d8bc721b6b1b2b", + "size": 1403428 + }, + "299": { + "releaseTime": "2012-10-03T01:15:02", + "sha1": "2ccd5e67834ed7398d9ac2640e099b62b5abca9f", + "sha256": "2110109759eecbc0620332d36da3f563928417e110d174f6dad5b7ea7f8ac706", + "size": 1424943 + }, + "3": { + "releaseTime": "2012-02-07T05:17:42", + "sha1": "3fe54181614b768989c3c7bf7511e155e6951b50", + "sha256": "58bece6eacb2ac1f1620cfb933a28091e29a54011b833bf4e237020ae5f7410a", + "size": 410382 + }, + "30": { + "releaseTime": "2012-03-05T13:41:18", + "sha1": "595e36215d90f21453aa9341229e912f24e34270", + "sha256": "7cc4d8665a7e53eebe8b464268aa87279e50fb72018a1a13b390a044d550ccb0", + "size": 491830 + }, + "300": { + "releaseTime": "2012-10-04T17:54:54", + "sha1": "86cd379f205b276f8c0324f68d2f2e8937385e9d", + "sha256": "ef233640f7f1355f1e75ee17028d25c907c0b6ee349e3b9627ca1399eba377f4", + "size": 1425269 + }, + "301": { + "releaseTime": "2012-10-04T18:13:16", + "sha1": "a2be7a5a53937cd1e9ba52d5c96000d65dc5dcd0", + "sha256": "1bab552c7fa6ec7e2b081a1588d4c52644e6af4704ec2e01e53fec4f6135cf23", + "size": 1425270 + }, + "302": { + "releaseTime": "2012-10-06T21:08:56", + "sha1": "f13bf3a018b054802e3a392d06f4fb4119ef9b20", + "sha256": "00292036a9eb6f604047712d63e11ee4b6fd6b3ed78ebea87ce0681c0047faa1", + "size": 1425356 + }, + "303": { + "releaseTime": "2012-10-06T22:33:42", + "sha1": "3889893893cb42d3a6152e776e9f6a180066dcaa", + "sha256": "e4a2b58ed312225e2695454736891bb41827ca554c84827023d33485656f0521", + "size": 1428414 + }, + "305": { + "releaseTime": "2012-10-07T19:21:12", + "sha1": "efd0fbfb3485a70ed9fb2af461a8ee2c5049fb3d", + "sha256": "2999f5efacaffc97feab6ac34d9fc912dd62f485afad14a712e0b88b42f4fcbc", + "size": 1428418 + }, + "306": { + "releaseTime": "2012-10-11T20:37:20", + "sha1": "ba1430d974407ef00969214c4390217b5ec64273", + "sha256": "2cd545363aac02da88b7885cec17523cf8b86daf6137cfbb465ea3c30477fa10", + "size": 1428541 + }, + "307": { + "releaseTime": "2012-10-12T07:06:42", + "sha1": "4abca56246431b36c149cd313e4835763ce8fd18", + "sha256": "a74f4c9a9fbfa40ad32cf1a80ad5440dc69742507746c1186b8c7cb93caedeea", + "size": 1428536 + }, + "31": { + "releaseTime": "2012-03-05T15:11:10", + "sha1": "4bb8573263e2d3e44fa5c6ef43f3e18ab5262562", + "sha256": "f8bdcc0c6024d76ea9e5e0e1344ac7241781afc3a231ce02da00906389880c90", + "size": 491816 + }, + "310": { + "releaseTime": "2012-10-14T13:21:20", + "sha1": "8052486df828c7cc6489d1f8a9ff0616c4d1d4fc", + "sha256": "7e530302923567d8e67dee84dea6495372a9fd583cfeb615410733f851598ce2", + "size": 1428709 + }, + "311": { + "releaseTime": "2012-10-14T21:04:00", + "sha1": "a040f2961a9f80d213dd63fc524a43c97a80ff81", + "sha256": "f85f541a15f45eec0e2d1729f723eec8d4aa4f61be174f7018385625baae58d2", + "size": 1432897 + }, + "312": { + "releaseTime": "2012-10-15T17:26:04", + "sha1": "b0cf805b556bab9117143b4a98a3858627d41e09", + "sha256": "2eac4812f955dfc247f10f2505e5ad571479ff073b8956f34d6f7ef2410ff987", + "size": 1440667 + }, + "313": { + "releaseTime": "2012-10-18T18:03:14", + "sha1": "fef9dcf979edcc958e88b6df81ef3c6389e8b337", + "sha256": "37bd8e7bd982b43b88e1812940e5b5dbd815da6a7ef0e497bd715e2d665512d1", + "size": 1440713 + }, + "314": { + "releaseTime": "2012-10-18T18:23:34", + "sha1": "0e6d656ad19cec0212bde20ab007aebfe307524f", + "sha256": "e2c45046b943ad8a0fddd1459f859c8f11daf55ddae79ee5bc915fab73ad9b71", + "size": 1444706 + }, + "315": { + "releaseTime": "2012-10-18T19:36:54", + "sha1": "d73efe944b56af1dec736a2841bf90b982fdcfda", + "sha256": "6a84beaca35ff12697c463325aac82047122d992ca30945689c735b81357c905", + "size": 1444954 + }, + "316": { + "releaseTime": "2012-10-19T07:33:54", + "sha1": "c6523c32c76347f4e524f2a62ffb818c1be100a0", + "sha256": "50c3dc888d807a521e159506439df28e9d1f607b51f9aa6f5e3351eeec37282d", + "size": 1445006 + }, + "317": { + "releaseTime": "2012-10-19T09:52:58", + "sha1": "953bcb1d58c2936bb09de2865087969a4c477b97", + "sha256": "301624aaf307f788af93c31d9a78a924fcd606c516f8250803594e413ca30794", + "size": 1455076 + }, + "318": { + "releaseTime": "2012-10-19T20:01:02", + "sha1": "a9aca7b4697197542b6d5af11a4f54aa4b052cb7", + "sha256": "5209fa33513733ea5466166354db2004c9b5373da59d45ecfa390f8870341b39", + "size": 1455002 + }, + "32": { + "releaseTime": "2012-03-05T20:08:08", + "sha1": "22acfcd17c076eb0d421c4dd3b954aeaaa9ac541", + "sha256": "ebe9955b45a3b57b9729ddb39cffefc84fac133df5b4faf5a16e8772e7643ac7", + "size": 491816 + }, + "320": { + "releaseTime": "2012-10-21T19:03:58", + "sha1": "2458eed5baf11e6cad3dd20cd1597eb21e6619da", + "sha256": "bfe7f3d609aabb8ef140ad7e440f3a5889d651a970076acfe3b418dd60ef544d", + "size": 1494316 + }, + "321": { + "releaseTime": "2012-10-21T19:10:42", + "sha1": "3cfbfacdb3187808752b41fc05281c10479d1d49", + "sha256": "ef596b1ad38833c2fa296f4f6ea0bc48e0ba477c1f7486daa8540674a6e98c41", + "size": 1494344 + }, + "322": { + "releaseTime": "2012-10-21T19:25:06", + "sha1": "7267e92a88bdc02609fe505498ef04ebab34e1b9", + "sha256": "73ad5c2751b5d582bb450b2803e3e3410bb71503b3a89e548f1f66995eff7789", + "size": 1494344 + }, + "323": { + "releaseTime": "2012-10-21T21:13:26", + "sha1": "609edfe719164418a648702d0d4886cfecae0af9", + "sha256": "62321c8a8ba3c75592929cb9b6f85093a53140066c77c44c1dfb3099a797f63c", + "size": 1494585 + }, + "324": { + "releaseTime": "2012-10-22T00:06:58", + "sha1": "1bc48563a4863659b9f4a7db7556bc34fbd759f6", + "sha256": "d4ba7ee24d4c96459f9ddac17f9ccc6f2b1cf1fa3f9db2ff35b2305664693f0f", + "size": 1494640 + }, + "325": { + "releaseTime": "2012-10-22T01:33:04", + "sha1": "c4fdc58df5f7fef44f1fc56c8e21b4c7eeed2e36", + "sha256": "42cb64e70fe45866f53fd1042a9ae547cc1b93f6ccc7c2f4ab7d2d0756514723", + "size": 1495067 + }, + "326": { + "releaseTime": "2012-10-23T07:33:54", + "sha1": "951d5d3be6a187f7d8083ab272490b611b83178d", + "sha256": "a3eb35d9315cb30dce07064eeddcdb501db6714248ee1275e1952f1705364fee", + "size": 1495169 + }, + "327": { + "releaseTime": "2012-10-23T17:11:18", + "sha1": "206f653b01decb7ed59856d8e5918aa2e29d7de7", + "sha256": "9b3b2f418c36341abb1772c58c2fb469b9791ec17d633f15f05299df360982a5", + "size": 1496510 + }, + "328": { + "releaseTime": "2012-10-23T19:58:42", + "sha1": "1f0adeb2906c5b36ea2e9aa38ffae6249fcc4fc4", + "sha256": "4117b0c4a84004bbd00707726541c554daaa7ae47d5c64756c4c2566a3d8f4f4", + "size": 1496526 + }, + "329": { + "releaseTime": "2012-10-24T04:58:42", + "sha1": "fdf61e473c34f7273962370da9a40dfac2554d28", + "sha256": "c10ffa5d4bd63737808d8273097678c256d961bf556f6f5f8bc2c283e95ab230", + "size": 1496508 + }, + "33": { + "releaseTime": "2012-03-06T00:33:56", + "sha1": "e0c02879e9986488810f4f54d4b7c3d71700daba", + "sha256": "6d28858969c5aa5b1151c73708d9996e154c0dbda3d7f526c503df5c7cd40f7a", + "size": 493289 + }, + "330": { + "releaseTime": "2012-10-24T15:06:52", + "sha1": "7b7c77d36bef706f655acac4507a1a731282c342", + "sha256": "b6215a0814bc50465b47d00497bf29a0d87e7b296470f532238208af5b5d00b1", + "size": 1503248 + }, + "331": { + "releaseTime": "2012-10-24T16:22:08", + "sha1": "6e943173b9889fb97d86a0dd27f2a4e85777aa92", + "sha256": "e34fe78f021948511a9ebf4fdaeab63e1095278ba61c3cb9d7e1d9f43591a191", + "size": 1498731 + }, + "332": { + "releaseTime": "2012-10-24T20:19:58", + "sha1": "65355d7e60accf48e78e9fa011bdbd9c90a57f9c", + "sha256": "0bb6f6d7b832fb02010711638be3c94ef9b7c305e720127353f7df9c0927f801", + "size": 1502361 + }, + "336": { + "releaseTime": "2012-10-25T12:50:48", + "sha1": "770038a5a35f4d615fa8329f2ce86e2244555295", + "sha256": "504a206d83df78ca2e0c1d4d2ac73a352bdbb95e10f23d85f6e1ab6cc67cda46", + "size": 1510583 + }, + "337": { + "releaseTime": "2012-10-25T14:06:30", + "sha1": "8ef4b1ee1783e504c963850e0388d7841a07d9f5", + "sha256": "1e384bd63602ae7c72e508869874d48479b4b84dde060eb0d421110a4ed29607", + "size": 1510581 + }, + "338": { + "releaseTime": "2012-10-26T22:14:56", + "sha1": "66639c2142007e828ace0e073e8bb6cee331b9a5", + "sha256": "03cf9db17993d4f7f65ca35f8417af1fc9009d89e915312c77c6770c9d9c823d", + "size": 1510621 + }, + "339": { + "releaseTime": "2012-10-26T23:42:06", + "sha1": "2b7c222c546aa1fb4970158cb73a3c7ee1a8752f", + "sha256": "066bb3a7e85f79956b1d63a05669f5341cd3bed037c82b51979e00097ef2eb4f", + "size": 1511938 + }, + "34": { + "releaseTime": "2012-03-06T12:16:10", + "sha1": "026c986f32243ea3717ef5588078cb24e205dc3f", + "sha256": "fa01b7da584bb1bd82ff172b7a0c20f0cc331cdedc8147ca73f4242650ba92d6", + "size": 493315 + }, + "341": { + "releaseTime": "2012-10-27T17:16:34", + "sha1": "e4803f22cd8658dad3d9fcfb0e1000d64a6d23bf", + "sha256": "1ec9689844eb2f0622b4b2202eda95be209d46e52b2974c0d209710a3d123fa6", + "size": 1512068 + }, + "342": { + "releaseTime": "2012-10-28T05:21:52", + "sha1": "5ed309d34f886909d155c2a9ce4ecf0c5773dd2d", + "sha256": "f619ad665ff333142023ad40f711aa1fecaa90be3fc441fbe26c88db60453f15", + "size": 1513794 + }, + "343": { + "releaseTime": "2012-10-28T05:56:26", + "sha1": "7e75505b38d43d8ddba72ca54a80a05d3f8421e0", + "sha256": "a05a4d0b1630434f8101b7e719e4234064bac07c051c69fc54c86649dfc427c7", + "size": 1514653 + }, + "345": { + "releaseTime": "2012-10-28T16:40:54", + "sha1": "3ea15e52020b3e2293ef51c0e94a6f9e7a5126f3", + "sha256": "1064de17fc5d2f395020da84cb14e590abf35874dfed266bcd270e44f24fb400", + "size": 1525523 + }, + "347": { + "releaseTime": "2012-10-28T20:10:44", + "sha1": "0b1205eaf6f091a06f340259f6f249ee76787e6e", + "sha256": "783555feb06393b22fa6639e40018ae647a50baec7bce2aa4aacd0827626e312", + "size": 1525525 + }, + "348": { + "releaseTime": "2012-10-28T22:58:56", + "sha1": "bc79e870e11fef61ddfba2c82eb4268af049a44a", + "sha256": "12d3bc2efd574c691c5cd1304be113605dc585157c2f9dc9759a36a5605d38ba", + "size": 1525392 + }, + "349": { + "releaseTime": "2012-10-28T23:11:02", + "sha1": "1cfb5f54ce72ddb174031b64d04c158f98892a51", + "sha256": "e47f59822872eca8e85a9fc5f5a3eed512109afc595201b245987b5ec4f32806", + "size": 1551747 + }, + "35": { + "releaseTime": "2012-03-06T14:22:22", + "sha1": "ba295b9285cc6be48d3dfa7fd37ea86213c45578", + "sha256": "28a1f00312db22a4cf21e8a2f44738816a86ae4f20ddfa722399539834436155", + "size": 495444 + }, + "350": { + "releaseTime": "2012-10-29T00:46:24", + "sha1": "5d9a4661d55b93221d6363a58dd5376474351c01", + "sha256": "6ef74924226dc59a37a3d718caeb152490de0f32caf06b832a5717b324fa57af", + "size": 1551798 + }, + "351": { + "releaseTime": "2012-10-30T07:34:28", + "sha1": "116fbdbc70e3dd7905bc5c591cf6a4969c126da1", + "sha256": "93d3daf31960dc9ed863037f02d078c2f52f3ebbc22ab16f91b3691834722a0a", + "size": 1556458 + }, + "353": { + "releaseTime": "2012-10-30T20:14:42", + "sha1": "dae9da6a5f388913fafb99f9c99fcf4b60e22f80", + "sha256": "565d5b12e452affca7965d1d0b6b7208bfe06522a1bd82002f416278d0f90cff", + "size": 1556757 + }, + "354": { + "releaseTime": "2012-10-31T11:20:58", + "sha1": "629cbcecc84e21703fee50093402da51573b073e", + "sha256": "75407b1dfe61f9a0722377f80eef7734c2567750c43b2950fcabf86995c7a77f", + "size": 1556800 + }, + "355": { + "releaseTime": "2012-11-02T12:52:28", + "sha1": "f7885f3ae3436d452a8bef4d9668f95298f7da7b", + "sha256": "b35d3cbe3a4e6a967fd97791be9e03014531aba1b2df6e365981436cc2dfbc6c", + "size": 1558322 + }, + "356": { + "releaseTime": "2012-11-02T23:37:06", + "sha1": "3f617c12e53ba1e3bb572e80d1b7665bae78baa3", + "sha256": "086d80575e3d80afd7f2eea8ec16f16b9f8c13ab3da7193c0c9f2f28792bcdce", + "size": 1568644 + }, + "357": { + "releaseTime": "2012-11-04T16:48:28", + "sha1": "eb0ae9e2504070958b6189483986e9104496b851", + "sha256": "befbd54a2a2d330d3023b43f680de88048d4ed9619ab271e5a94cb170ddc2aeb", + "size": 1568710 + }, + "358": { + "releaseTime": "2012-11-05T17:19:40", + "sha1": "04031bf441d7a634a85cc42013944a9210f38417", + "sha256": "7ed938631edfb68e4154b210246eaee2152d692e4dfc19aab14a241dbda26a9b", + "size": 1571298 + }, + "36": { + "releaseTime": "2012-03-06T15:09:00", + "sha1": "8ea8e6acd46548bd44e4065fcd298c6c8fe45bfa", + "sha256": "065e78e6c66fcc12ee0739ade8bc6c4de458d6146b2aa0268a27726846a27822", + "size": 495443 + }, + "360": { + "releaseTime": "2012-11-08T21:48:34", + "sha1": "39be64e9c2150f4fabc0b935f89d7eb4e98e768d", + "sha256": "93df1c8f6ef9df7a8a720498fc1d99c13a1d8d782425b4e1763e5465216c8a1d", + "size": 1570985 + }, + "361": { + "releaseTime": "2012-11-09T17:25:36", + "sha1": "f398db2d8385a3fd219bfe6c9497592e4d4c2e22", + "sha256": "cfd5bacca0ac58763208f506afd5a99ed729c73675adca26f9e5854bed620840", + "size": 1570879 + }, + "362": { + "releaseTime": "2012-11-09T19:04:06", + "sha1": "e87fbfea41cb8c1d45ed826d38ff7b956bacf080", + "sha256": "01b69b8250676214c6d6d4ec8750569cece3393925482b2cfe349b6e5781c17f", + "size": 1570970 + }, + "363": { + "releaseTime": "2012-11-09T20:56:32", + "sha1": "1771762757ed9d42f0037edb3676e77739a7a771", + "sha256": "4c05f84231bf150ba275f086857278b39bead1ace381553cb18bac4ccb61b93d", + "size": 1571054 + }, + "364": { + "releaseTime": "2012-11-10T19:33:58", + "sha1": "94e582f9b55f032a6acedcec16c78adf8dc5d491", + "sha256": "cbc34b9f02573e14a910d8a6dde8c99a7099da75a4be2ab096e6c5d5d81576e9", + "size": 1578038 + }, + "365": { + "releaseTime": "2012-11-12T18:44:30", + "sha1": "8777440f4e187005c0897b0210c927b9657334e7", + "sha256": "5ee66f082387f88eb932d1bdfce8d6d2c9fff7d062f28f76c3da9c08285c3254", + "size": 1559401 + }, + "366": { + "releaseTime": "2012-11-12T18:53:48", + "sha1": "ab553f5143e540886bef8f84d34fbc7fefd48db5", + "sha256": "a5ec60b85c40f16c282aa0c4148f2da10f404e27903be7a5f81418988e549a3c", + "size": 1559399 + }, + "367": { + "releaseTime": "2012-11-12T19:47:18", + "sha1": "496ebd0e668fe2d8d6407c3a451dc85822a5c542", + "sha256": "c91589bd1bde3969a2aac31aae08b9f66e1955c454eaadc204ff1094f8a02024", + "size": 1559438 + }, + "368": { + "releaseTime": "2012-11-13T05:16:32", + "sha1": "4a6ce155d69a0e77172bd33e8542843ba2fb5557", + "sha256": "936ea8b61d2569e41e18e9f1cf6e3f6bf62e96f3458f01bbde7035694b27b69b", + "size": 1572991 + }, + "369": { + "releaseTime": "2012-11-13T12:34:36", + "sha1": "ba531896a52058369d867a96ad471c33b196fbc8", + "sha256": "2465f0cc6bfc3a6ce1f1e7c4792ea3378d095c80feb7022dc7f34789e7b1ffd7", + "size": 1560273 + }, + "37": { + "releaseTime": "2012-03-06T19:04:38", + "sha1": "0fe737b9df40cab28f02c37590e424f67df083c4", + "sha256": "7262bf12856ad4843ba79af6b87893890da228afad5ef864ee8caad45d4f7630", + "size": 495444 + }, + "370": { + "releaseTime": "2012-11-13T13:09:52", + "sha1": "b2076adfc54efc8ae825730a64ed01279d44c211", + "sha256": "0c1744dbc69b89a48751270fb564eb6f4309da6bde626e1372d2d50e25e5f98a", + "size": 1560358 + }, + "371": { + "releaseTime": "2012-11-13T14:07:42", + "sha1": "b183e618cb2e48527f7a29b708fff9d58295f1e6", + "sha256": "13e8021d23a2d2fcb5ca9fc3df96b3455818069266587fb341843600467b1b8f", + "size": 1560418 + }, + "372": { + "releaseTime": "2012-11-13T19:58:58", + "sha1": "027d47d7976d01ccc3599e041dfcded3ec15eb2a", + "sha256": "1b844c29cec43e00e82b65e258f71f61c1cce5ca0d2b8356f50b47d9d6ef7932", + "size": 1561761 + }, + "373": { + "releaseTime": "2012-11-14T19:27:58", + "sha1": "fda4fbf2916207d55e98ec27ea61549c1826da54", + "sha256": "a0c437ddd2cc6c7be270fc6b88d6539829679b79bd01aff7f90e79a3bbfc148e", + "size": 1562217 + }, + "374": { + "releaseTime": "2012-11-15T04:49:52", + "sha1": "9de2d89f0531bcb1adc8267ee0a8baa008f33e85", + "sha256": "fa82a63bbd85cb7ae31956b637e735a8cc2febd981ee68b400a999691e1b0a7a", + "size": 1562900 + }, + "375": { + "releaseTime": "2012-11-15T15:28:26", + "sha1": "0d8966170b6962601e5a91b19b2d50e341712823", + "sha256": "4d13ace48459183ce6787de75d60b878a2af9953b62a613a54f3bfc46a65cb3c", + "size": 1563025 + }, + "376": { + "releaseTime": "2012-11-15T19:51:02", + "sha1": "e1b8b7bace6918a37d4d514cfc7fda2d52ed8026", + "sha256": "c9747e1904f643348284bd0a84f69fc39466f8cf294eb7e8bbb8dfa38fff3da0", + "size": 1563055 + }, + "377": { + "releaseTime": "2012-11-15T20:06:00", + "sha1": "780c95faaa1ba67abad4f3337400608c447cc58b", + "sha256": "6933de9c37497ddddbe75c097dec6bfb6cc2952a0b1f677395484b90246b3205", + "size": 1563101 + }, + "378": { + "releaseTime": "2012-11-15T23:33:32", + "sha1": "dce5007bd59c08b094a83f1f35b64e25f1996f78", + "sha256": "8530d8205c99537ed71b7252ed34f05326e88e901ac8950d34da36142619a9a5", + "size": 1566485 + }, + "379": { + "releaseTime": "2012-11-16T15:47:20", + "sha1": "b201f6af733fbfb0bd2c11c68774b31588257217", + "sha256": "0f4714124c33ee1d7531a385da2ca59bea742c668e8420eafba85cd1481cbe5c", + "size": 1566514 + }, + "38": { + "releaseTime": "2012-03-06T22:49:30", + "sha1": "d254fec60aafefafcb399790a28f27f69e67d56c", + "sha256": "f946b0050a736e47a115da5cc5a23a4cf80a8a54cf1adeb16afb21da332bbf37", + "size": 495443 + }, + "380": { + "releaseTime": "2012-11-16T17:12:00", + "sha1": "2307ad742e748fd12a8565bd5da3cb751a6432a9", + "sha256": "c3521e6ec808aae8d459ad0851d5888e3146aa934920ce2b7c3c9877a14f2689", + "size": 1569305 + }, + "381": { + "releaseTime": "2012-11-16T21:14:30", + "sha1": "4dda566adf78076414db2c141940e6aaaa41dbd5", + "sha256": "701a668032d4d621221caeb0a24d4f244394afa128e7f392679f9737e21acfb6", + "size": 1566513 + }, + "382": { + "releaseTime": "2012-11-17T18:56:40", + "sha1": "1f944700b9a13ac67691968da20f2535e3d77bca", + "sha256": "0bf4fbad7b07e72fba6f858fc115ebb8d0c9622f13b110f2d750a2aab70aae69", + "size": 1566687 + }, + "383": { + "releaseTime": "2012-11-17T22:21:40", + "sha1": "65e67841ce18c66bc1cde1ba97df287983a83bf8", + "sha256": "b6ba49202676310a9510ce41181edc018cfa373ee83d033692d4b00d53c4bcac", + "size": 1566646 + }, + "384": { + "releaseTime": "2012-11-18T00:03:10", + "sha1": "3c6adeef6acfc9b7abb0f199b395b98f711cb93d", + "sha256": "647d75ae381c37af8c025ef68f08da0722995785dde35df5f3f3da2a6b7818ed", + "size": 1566769 + }, + "385": { + "releaseTime": "2012-11-18T02:42:22", + "sha1": "a15a6f757d97b8f0eb8ad8d4ac7d3124c0321746", + "sha256": "c177bc64a849afcf08f47a1b840ac8374a97c282f5a36e5901beec293ad02b4a", + "size": 1566949 + }, + "386": { + "releaseTime": "2012-11-18T09:16:58", + "sha1": "99e1ab64ce488b7232c73208b16eb04f470fd9f5", + "sha256": "c9cd3f00e1f80eed295e5630a0be0074813f9d17f1113c1cc78bad733c43e556", + "size": 1567017 + }, + "387": { + "releaseTime": "2012-11-18T17:32:38", + "sha1": "2d91b92f77c2decd351b13e5d50019c2bc4af3e5", + "sha256": "68b80e96f6f9a346c1b15ee4fe169a5b2fcc2fae413b897dca8a5073b3f9a6ac", + "size": 1568405 + }, + "388": { + "releaseTime": "2012-11-18T19:26:58", + "sha1": "876479361328ed724181a07a30a1a103b600fb2c", + "sha256": "762580a61284d0c3740e577e1b76038fcb7866170f03eafd268a8b62f8d00a37", + "size": 1568457 + }, + "39": { + "releaseTime": "2012-03-07T09:49:42", + "sha1": "dde19ec058b2f6628763f1bc72648844155a67b8", + "sha256": "a321c4314b2cca490d977c37ef1fdb183e3a5371abc68aa01a3587e6ccdadd42", + "size": 495506 + }, + "390": { + "releaseTime": "2012-11-19T17:07:02", + "sha1": "c71d7e28ae162d29eb8806040f6f7fbf21708d14", + "sha256": "542cf72c16c210875f6eb55097165e7af472b306817506f8d5ab3778ff06f6cb", + "size": 1568504 + }, + "393": { + "releaseTime": "2012-11-19T22:03:40", + "sha1": "fed5072a6499574348eb2e1726fbb4599bd0a3ee", + "sha256": "21060ed45ea15c48c35c4977b9cf08b76a69ba26846b087df29a693f7378d090", + "size": 1568255 + }, + "394": { + "releaseTime": "2012-11-20T07:12:44", + "sha1": "66e56c512a992b0bb903a75ae84d06de354b5c28", + "sha256": "da4530a3d6587165c1a40f8fdbd2507d65b26d7c3793c3725abd1ea1aa331a34", + "size": 1565762 + }, + "395": { + "releaseTime": "2012-11-21T17:10:54", + "sha1": "5be9167d38845adbaf24e58e9171d582b1e9d612", + "sha256": "a29de2d2303298967ef3c3eeb0b0abe5d35c543cb4b885c77e82997e52288b35", + "size": 1565838 + }, + "396": { + "releaseTime": "2012-11-24T12:17:28", + "sha1": "3efd96ec4115072fc8ad5b5a202d27cf8ad56ac3", + "sha256": "571f1ead1b918d6326844c34e1f529007d890c30ad4831aab092b1d7b1c6007c", + "size": 1564970 + }, + "397": { + "releaseTime": "2012-11-26T22:28:56", + "sha1": "2f1a2fd2a5f9bbb7a39490bb4c029b39db80ce48", + "sha256": "7378bc6b9d96c22d277fe99c6f4ba0e9b8b72ee3c7ddb84e5f27ec640904b243", + "size": 1564930 + }, + "398": { + "releaseTime": "2012-11-27T00:49:16", + "sha1": "f5bc769ba675895c657804c7aa1574e993cedb39", + "sha256": "74141455ecb4964d04c19ac4c59b0fa4d3064121968d5249a3a914f1f1c3a9c3", + "size": 1570364 + }, + "399": { + "releaseTime": "2012-11-27T01:31:16", + "sha1": "3f81754b6649761afcc5f9ce17ac92a078ebc713", + "sha256": "563a12fb5c7a82974aeb427928fd3f2a4a77d58421d62519ee5640a3de57110f", + "size": 1570525 + }, + "4": { + "releaseTime": "2012-02-10T03:10:24", + "sha1": "0e36def24134f9ea0262d650d757a37375eb03a3", + "sha256": "e6cb1ccf475de90bc7455bfe7d3b22c48474d8f2f779ce15869b5f12aa97991a", + "size": 417875 + }, + "400": { + "releaseTime": "2012-11-27T03:09:46", + "sha1": "ffce011510bac3b35a704cba8bddad4ff77ac8b0", + "sha256": "234d9950ff347a9636f93a7e2ca5c13100a25c944fcb0e3d3575fccec207f8d9", + "size": 1571980 + }, + "401": { + "releaseTime": "2012-11-27T03:18:54", + "sha1": "d20d4215257451427feac211b007881c57e1259c", + "sha256": "6a849378fe84c62d2623b363a30686f16bfcf3cfccbe3ed0b0a35b02525a1b23", + "size": 1572151 + }, + "402": { + "releaseTime": "2012-11-27T13:28:34", + "sha1": "25889ddffbade3e9c467ffb0c5fab27f36078dd2", + "sha256": "66ef433a2c80bd59a874e9a3850247358a7b4dd2eca082eee86e721841d7ee87", + "size": 1572142 + }, + "403": { + "releaseTime": "2012-11-27T15:56:04", + "sha1": "3836f55df5e5b0ef820273d7eaef7392126fcb3a", + "sha256": "f25db24661de5f1bab385bba2552fdb6cb6ab000d43d27bc12524580d2c181f1", + "size": 1572392 + }, + "404": { + "releaseTime": "2012-11-27T16:06:34", + "sha1": "e958182912c91fe4c77fbab7fdb60148ff4efae8", + "sha256": "d9f855ef98c546e7213c1ed863909131a12ed20ffca479949009b7faaea6272a", + "size": 1572624 + }, + "405": { + "releaseTime": "2012-11-27T17:21:26", + "sha1": "78e964e525fdae2339787d5063c14668e4de18a7", + "sha256": "f8032efd8fbcd2c25a657b567934358e98557d92895e1d0094c5fb638ce68230", + "size": 1572753 + }, + "406": { + "releaseTime": "2012-11-27T17:55:00", + "sha1": "191d3a0768b892f4af6aa256639f0267cc4177b3", + "sha256": "88f276290ad3b4505e1c6a3486c6ce69a96db9416498e13d21886d948d05b60a", + "size": 1572983 + }, + "407": { + "releaseTime": "2012-11-27T23:46:16", + "sha1": "7b50df5d5782bf5568074836ee87342273d2c9d6", + "sha256": "5f11b6194292fecebea4ee1679c3ff8733d6111175f12a8abfe6b86b8dda55fc", + "size": 1573097 + }, + "408": { + "releaseTime": "2012-11-29T05:08:18", + "sha1": "3559c418690e0634bf2ef375d4356304f227620e", + "sha256": "be355580f79b976008c60abc11a1aedfe34b5409d852b6ab92e87f3c677a4e9a", + "size": 1573136 + }, + "409": { + "releaseTime": "2012-11-30T21:26:38", + "sha1": "632e8c6c84fcc6abe47cebff567a772c55ef6ab8", + "sha256": "4f52fef86901c8f1df14cdd1c388f0466f86c010fddae94f3b1f1b4bf5ba217e", + "size": 1573285 + }, + "41": { + "releaseTime": "2012-03-08T22:37:54", + "sha1": "464bda507ea2b70a27a168dceb26511fab3e97d3", + "sha256": "46df091f2436c079a881de6a7cfb8dafe8e79872bcedc21e4a6fe88ede672141", + "size": 499564 + }, + "410": { + "releaseTime": "2012-12-01T23:01:20", + "sha1": "a771d3f3823f2698477fcf09e695bfe2b85dab43", + "sha256": "243382beb46dc0092604dfba1ed518e0beeaca26d36287524646360428e596da", + "size": 1574333 + }, + "411": { + "releaseTime": "2012-12-02T20:10:38", + "sha1": "a07de9f69faf2403a0020cf02434b73ff661e19c", + "sha256": "d80d56f8a6c1d2064763fc9c073f07471e3c8d168784fa75f324b0aea8b979cd", + "size": 1574484 + }, + "413": { + "releaseTime": "2012-12-05T03:55:42", + "sha1": "b8c267d5e9490a08fa4200180a89f2dd6c0da65c", + "sha256": "a0dc646aafc7230d7257dfe5340c26d6dd960155b01a7663800d35fdd1c40808", + "size": 1574140 + }, + "414": { + "releaseTime": "2012-12-05T20:15:24", + "sha1": "6716fb10e4c917036f213b566031097b54c2a73c", + "sha256": "922da5ea5571d02c55d26e438ad8cb06642bc55c668e2bfc4929e8dead7a0066", + "size": 1573934 + }, + "416": { + "releaseTime": "2012-12-05T21:06:12", + "sha1": "4294dd76051274853c92390277f0ee6a449d4ee3", + "sha256": "9786265a6ffd025fa31dfc87d3f9d3d5f3740c670426bea6542b9170c41379c6", + "size": 1574377 + }, + "424": { + "releaseTime": "2012-12-06T07:18:32", + "sha1": "3086e9a8484bad60e86dc0493efaf578b6a56dd0", + "sha256": "fb709c1dc458ecfb06870da123c0ec1d59dca5578ad215d3a9dff4ec14fc3a8b", + "size": 1576166 + }, + "425": { + "releaseTime": "2012-12-06T14:19:06", + "sha1": "4fccda18239a1876f3d62f5c965d60b82dc91468", + "sha256": "7bb5e4b9c1aed20331b78635f15a2e801865490a1e5fa6f6a8f537349e39d700", + "size": 1576317 + }, + "426": { + "releaseTime": "2012-12-07T12:29:54", + "sha1": "8026a34475e6872234ac979b6a2c8099d423b7ea", + "sha256": "2938e6d0aa31b4e681815592f90ea49b433617be15cb4e50a4087c94c55e0dfe", + "size": 1576395 + }, + "428": { + "releaseTime": "2012-12-07T14:25:52", + "sha1": "4c352824ffec9ed14461d582f7329132a1c8df14", + "sha256": "e82d4cc3bb08a8dbe2d88bb4a9edf71350065861de4a19c72f74be949fab3c71", + "size": 1576422 + }, + "430": { + "releaseTime": "2012-12-07T14:46:08", + "sha1": "cf80d6a0ee80b8906c495eeea1def139a40a4987", + "sha256": "b86373c66c61b79b7f9e87be9ad1da33eef18dff6726f496d815e37adbb237bf", + "size": 1576422 + }, + "432": { + "releaseTime": "2012-12-09T15:13:24", + "sha1": "70b8b82c7ed7ec46c98db96762949e2671ba920e", + "sha256": "6d6539b0c4cdb5b342b4cbd68da0a3e6059fcac7ee6d3199efbfb307fb54a284", + "size": 1576278 + }, + "433": { + "releaseTime": "2012-12-09T15:19:16", + "sha1": "27f1997fc815e04b0f56f0015b078bf2c84fa7ec", + "sha256": "59271f90f8a6071fac3b934493c08524ecab56c8679b666ca242644482fd6fe4", + "size": 1576330 + }, + "434": { + "releaseTime": "2012-12-09T19:48:28", + "sha1": "8748888abd3d3c2adcf4d4313414c6295ec3e706", + "sha256": "0395f5aca0707016c9ec6a4e237ccdb5346b73c72f9e653934c29e6ad2f893fa", + "size": 1576349 + }, + "435": { + "releaseTime": "2012-12-09T20:01:56", + "sha1": "a1b84b450226f355d8dec28a3e8c1103cd9b37af", + "sha256": "bbb10267af0fcfadb9c5d7e1fe843394c4fe301eef0ef41068d31ead86dfb9a5", + "size": 1576377 + }, + "436": { + "releaseTime": "2012-12-10T16:59:08", + "sha1": "8c4b90d40e9793c3252c3f88c730422fb64669a9", + "sha256": "2073d3ab32a6aaa868b96d3980157c23952f78c8b6ec593e44dc57cf34660a8d", + "size": 1590738 + }, + "437": { + "releaseTime": "2012-12-11T22:46:36", + "sha1": "832c44b5e1c6e85d35ed566e4f123ed67e4b9778", + "sha256": "6cceba7d45ad61c1bc5c9bfbcdae0d24f2c268c2417724ccc701c5c7c8167a42", + "size": 1590956 + }, + "438": { + "releaseTime": "2012-12-12T03:55:14", + "sha1": "24c3852556e4a2172bd37de1cad18d4243a0b308", + "sha256": "f7a3057bdee5d5e48d1dd4231e53fb94e7fc6d679cbd6912b908e5a92baacd28", + "size": 1592071 + }, + "439": { + "releaseTime": "2012-12-12T15:35:04", + "sha1": "380e5ed60de266795ef3dee3c936621141cf0186", + "sha256": "e4ecef94ad2362bbbf3698603eb8a8326e6593b37561c68af568c5019eb57006", + "size": 1592612 + }, + "44": { + "releaseTime": "2012-03-09T14:31:00", + "sha1": "b52292f98704566d55ed5fbd4dc0405d8edb6e0b", + "sha256": "4d87f84695eec54608719f0eaaadb9cab0d552d73df6d3feab69a7ef3bfa512e", + "size": 499566 + }, + "441": { + "releaseTime": "2012-12-12T18:22:44", + "sha1": "bae8c4e99b9e2c0617550db52ad8eecc06ba2f6d", + "sha256": "6f6410d465f289369450fdcf3742f1f0c905272cdac58b6fee8f079dc54a41f6", + "size": 1593778 + }, + "442": { + "releaseTime": "2012-12-12T19:17:38", + "sha1": "a542808264f7a5f0d915c33e2cc3f2142f1fcc0b", + "sha256": "b2439f523dfcb813856fc862a4a3a1e6f8f6d803694b80f2a1da395982f0650c", + "size": 1660053 + }, + "443": { + "releaseTime": "2012-12-12T19:38:34", + "sha1": "ac0e17501a2925505c2e1ffa44a0f8eee0b9b845", + "sha256": "ccbc7994ab79325e5b591911f747e7ec58083f01794f3c865aee60e9d51ae2da", + "size": 1660189 + }, + "444": { + "releaseTime": "2012-12-13T00:54:08", + "sha1": "a1451b128695094b6b5cca335449e1d620de06fb", + "sha256": "ad3040529aa031dd3bc1fa6cbfe7d8f315205ba9c5df8a06bb6a3bbdd474c26e", + "size": 1669622 + }, + "445": { + "releaseTime": "2012-12-13T01:37:06", + "sha1": "b034cbad3f93b4dc7da0d1afbbe8541d53ab98a5", + "sha256": "c4ae11bc38717108e01dca4ca64f8649c64dbf471016c89859baa126421f1e21", + "size": 1669620 + }, + "446": { + "releaseTime": "2012-12-16T19:08:40", + "sha1": "21b69f42306a5a27cadfe6d80c334e0733ab52ac", + "sha256": "efcd28ce76ec40846e291476a3e9155cad3edbd838a40ff4a4f3074deb2d7ea8", + "size": 1669607 + }, + "447": { + "releaseTime": "2012-12-16T21:13:04", + "sha1": "8ea8676eff9c3c27cc98c1a713ef58e65744e765", + "sha256": "7e08e0f7b54d67f6f26c35336a629f724455856822441507649224689d28ec98", + "size": 1670780 + }, + "448": { + "releaseTime": "2012-12-17T09:01:44", + "sha1": "13a9f80d41adf293179a39e5b6a484871d14ac44", + "sha256": "0189e4a7f4a9c41924f2a52fffad0e40657b5442743ee4e4f43098d72adf25e8", + "size": 1670806 + }, + "45": { + "releaseTime": "2012-03-09T17:26:54", + "sha1": "801c29b3682f1af358166a262ff882085709e050", + "sha256": "025d932795079e1f305cdbcad4e2144334ccc91f1d028b619d71ef844e29373a", + "size": 499542 + }, + "451": { + "releaseTime": "2012-12-18T01:35:54", + "sha1": "421993ef8f69c3a9409eb4d5ed7fc2c425066c9b", + "sha256": "c9e195b010bd0e1c721e58270e7d3cb6beb5ceb18e95be60a5a04fccc19eb3f4", + "size": 1726000 + }, + "452": { + "releaseTime": "2012-12-18T06:33:42", + "sha1": "2a2c3d7656179a3576c68ef05593241cab30dc89", + "sha256": "894c384a989e22d644708a18dd4b2873c2d8d1a344a46fa268efb8453d6907a2", + "size": 1726210 + }, + "453": { + "releaseTime": "2012-12-18T07:25:04", + "sha1": "4efb68e5ba7e83f30e69e4e6417d937140a37843", + "sha256": "36c23bb5e8c524e4633b17feac709f499c7d4d44178f4fcfcf1e75a9f7034792", + "size": 1726167 + }, + "454": { + "releaseTime": "2012-12-18T07:59:58", + "sha1": "6a37494bc27f2a931ad7a55071d799b0c14d322e", + "sha256": "f52e50343683b49c102f25a595cb9298bf38d6bbb431d66b2d25edbb68f41875", + "size": 1726248 + }, + "455": { + "releaseTime": "2012-12-18T09:05:42", + "sha1": "a6769078d9dbeda08be78d1ff98e8398948db030", + "sha256": "fba9f76b198b90acff4b1e73ff313d13c6b7282aa40baf9b782bad7d65f8380e", + "size": 1726503 + }, + "456": { + "releaseTime": "2012-12-18T11:37:00", + "sha1": "0a04ca649837a9254daa96691d51011bb25da139", + "sha256": "b68b9b26db586479608c0b76054e345832d4e697933662664b7d26edfb9183a9", + "size": 1726508 + }, + "457": { + "releaseTime": "2012-12-18T12:23:28", + "sha1": "32815602e585fa49d469911f7afbc9477af3dd14", + "sha256": "f8ddcaacf7b1eec6d564608fd3a127e71ad50430fe00a9a689aea25ba9798d44", + "size": 1727433 + }, + "458": { + "releaseTime": "2012-12-18T15:13:42", + "sha1": "41ad6776ef46795e9d3fb219f0cc70deacc322fd", + "sha256": "47964bd168713ec45d60d0909ac004970d01acabb5f117d93bb67e2c36970064", + "size": 1727457 + }, + "459": { + "releaseTime": "2012-12-18T16:06:36", + "sha1": "a75f08410a16f34504503464fac3585d1cef9dad", + "sha256": "f05ca5f2e4e507cf1e9d117dfaf7f06a0c96cbb2ced0de2ad99b16421dae945b", + "size": 1727472 + }, + "46": { + "releaseTime": "2012-03-09T19:00:00", + "sha1": "249650d67d67be25f72835ab5ef7524f488f1804", + "sha256": "7c1b57a1e1297aa0766bd3a52dbe18f5d38d17e013622af681a11e3e8958014a", + "size": 499542 + }, + "460": { + "releaseTime": "2012-12-18T16:45:26", + "sha1": "82d3f2945980277af4e5562283b46d5c99c33192", + "sha256": "01c47f5cc5326ba08b1372abde90598e8fc47b557fe737f04db021f0607a5972", + "size": 1727478 + }, + "461": { + "releaseTime": "2012-12-18T20:15:42", + "sha1": "736ea6a5de8a8631f179958c727af63cde2534c3", + "sha256": "e772575ec613c557ed7e83e1fb55c855d9cc0cc3396636287e1609c63a78977f", + "size": 1733216 + }, + "462": { + "releaseTime": "2012-12-18T20:22:02", + "sha1": "c5870d3b28063d0e2c2e1320d47d1cd883953d27", + "sha256": "29b5e43ac1ebf8572cf8a426c51fc8eac132ebe62937b8297bb6a0bebe6495ed", + "size": 1733220 + }, + "463": { + "releaseTime": "2012-12-19T14:47:42", + "sha1": "8964d7dbdf6db684371b79f31f2708daf26a3d65", + "sha256": "61d212a885d5d9903fa3653246e492ad243afb191353c74fc5cf3e4ae02649cb", + "size": 1733227 + }, + "464": { + "releaseTime": "2012-12-20T06:29:08", + "sha1": "8f3649a5743184c0b1b09653749cff1aa2a817d3", + "sha256": "14206ed1f73ba0b305637a0870ef70ac7ad52d3b44961effca54ec36dc065753", + "size": 1733293 + }, + "465": { + "releaseTime": "2012-12-20T06:55:52", + "sha1": "2f8b54e20bd0968be3e54e2d6a160f325acd6b11", + "sha256": "e26f8e433197a05ec0e7e8d663bd0ed8ffba274c9c462af727275ea03f5e067f", + "size": 1733394 + }, + "466": { + "releaseTime": "2012-12-20T08:55:54", + "sha1": "a3aadc9017870b125e86aa174151f2f8e6c4bad0", + "sha256": "29ccb3022faad84e868df4d7106699c4ec04cc2aa042dc7e77a105e632d5ba6d", + "size": 1733369 + }, + "467": { + "releaseTime": "2012-12-20T16:07:14", + "sha1": "ebfb8b5a38998ac3d15a49ac421270399a35e9e6", + "sha256": "a8a1ea57487d9074247eacf61cf12ea62ff1de07e6bbe10a87492a54da4495a5", + "size": 1733972 + }, + "468": { + "releaseTime": "2012-12-20T19:45:14", + "sha1": "872cad36bf9fbd8b570c8839786665476d3d37e8", + "sha256": "4f1a56fc643c96fed83187c4c9caebd7c7ecd1e1abeae8eb2c4f20e04f341c39", + "size": 1734950 + }, + "469": { + "releaseTime": "2012-12-20T23:53:48", + "sha1": "7426aac26d35e178b3d2663b4d506a82d00a3f85", + "sha256": "7bfc916af6e0754c2cb8fa7775e22883af8766d1586d1214b9f88f0c47c5d237", + "size": 1734950 + }, + "47": { + "releaseTime": "2012-03-10T17:12:54", + "sha1": "658451d143a3e9acbfdb405bbb7e6a9d0cfd6bea", + "sha256": "201c8e614888d675355a780ba7e14ee630bc199b6ad5a7d0e4dae18f85236e01", + "size": 499538 + }, + "470": { + "releaseTime": "2012-12-21T01:20:06", + "sha1": "9df25c7d137cac8bb6f01fa947fa6f7cb1ed5730", + "sha256": "dc7585b24d6c54025f373908af901f63b2d460832c036ad4ee68f410b4c5cb6a", + "size": 1735047 + }, + "471": { + "releaseTime": "2012-12-21T07:29:44", + "sha1": "4efb1b18519a23f5c00f9067f2391b6d08d3a5f0", + "sha256": "090c3a55b08e8ad91b9b77cb85a53234687c9a94259557dbb723966cccb8cdb4", + "size": 1734974 + }, + "472": { + "releaseTime": "2012-12-21T13:51:46", + "sha1": "e6e08713a05d0848b69de728aee4657f3a3c5efe", + "sha256": "11d7bd50322b63c8dadb6b6b0b3b57c0e077fd1a62d08f18c4141466598e49ff", + "size": 1737294 + }, + "473": { + "releaseTime": "2012-12-22T05:13:46", + "sha1": "5c729491f944ae248bbbbfa4c3538ab55d8e3ad3", + "sha256": "45f164a5433be75743a271aa7ddd2489d2c2acaa11b39edd687c2c319ee22969", + "size": 1744124 + }, + "474": { + "releaseTime": "2012-12-23T13:37:12", + "sha1": "999bbcd15fa79c272a733b0cf66cbb894a1b3f68", + "sha256": "953721125acc90d1ba8e1092508b9dc844956a412d47c4448ce5150a5aca8c7d", + "size": 1744238 + }, + "475": { + "releaseTime": "2012-12-23T22:54:44", + "sha1": "3a1f3803a43b2e7c506a344b88c7832c808462ab", + "sha256": "3c18c13011d4274e56353e4ba04c1295e7a0d41f4f5dd2bb779df8ddea566862", + "size": 1741653 + }, + "476": { + "releaseTime": "2012-12-24T00:34:20", + "sha1": "2daa310149da3edcbb7d08faa58760a21c26a8c5", + "sha256": "9e7e4d1cbdc912c31c114e129217ddf97346e0be91fbf82c3ea5cc5832a800d8", + "size": 1741664 + }, + "477": { + "releaseTime": "2012-12-24T00:40:32", + "sha1": "bba7b620d135e62ff4158ab41252bcf9174b4110", + "sha256": "34f421c1a173ae1afe7cad37eb326560919c176e3b67031b698546e9707c40f8", + "size": 1744371 + }, + "478": { + "releaseTime": "2012-12-24T02:33:06", + "sha1": "e9a4f006c0bb89e12c6653d336441746e10ec0e1", + "sha256": "7ae27b002491dea6ce4563582a52da6c559a17896af281ad2a87e9dd6b87e72b", + "size": 1744491 + }, + "479": { + "releaseTime": "2012-12-24T02:42:26", + "sha1": "48678d934b09e484b66cdedd5ea02e8a34891418", + "sha256": "5ccd19915392c33809f26334f2bbc8c0c40dfcd221abea01f56efaaa00f83df1", + "size": 1744492 + }, + "48": { + "releaseTime": "2012-03-12T12:23:28", + "sha1": "9c64c3b621f2d2d3e0b9a45aeeb0c81e6994508f", + "sha256": "3cebc5d52ea6595868522a3643cb1b75067e86b6831ba69056aa0dae6ab202b1", + "size": 499538 + }, + "480": { + "releaseTime": "2012-12-24T02:58:50", + "sha1": "3d760ec785b329dc04fa59342b381dd357336811", + "sha256": "d06834960396f393714a92afcdad10a53ae774d086d6b03139e057905d28124f", + "size": 1744429 + }, + "481": { + "releaseTime": "2012-12-24T10:18:58", + "sha1": "1ff2196efd74a559216860a70b85f09e3e63de9d", + "sha256": "73dcf5b3f1744c61a43c0f9c676b3092dc1167687f3870ec8e49ed8e4c2692b4", + "size": 1745086 + }, + "482": { + "releaseTime": "2012-12-25T17:20:24", + "sha1": "699a44e90e186283858c06c26ae61591c0930ccf", + "sha256": "477e063f1ad9bd5bb82e373bd592d834d4379283f58e3c3add051c5381adcea5", + "size": 1745156 + }, + "483": { + "releaseTime": "2012-12-25T20:16:10", + "sha1": "3058f414ed26f7a17716dbfc714059634814af7a", + "sha256": "63ed21d141b96509b487741a9ee8b8eb91c5ae107737f813bc56037cd8a51920", + "size": 1745409 + }, + "484": { + "releaseTime": "2012-12-25T23:08:44", + "sha1": "22917af8817870ec59c31b47f444e3f3775f8dcf", + "sha256": "36be7238426914c4d6146d58c1961070d49cf69fb6ca5077fdd0f094e56dd36e", + "size": 1745586 + }, + "486": { + "releaseTime": "2012-12-25T23:32:22", + "sha1": "da305a3cea5057bf8ba153fd066631c11b05addc", + "sha256": "483741ff2cac45c6e4a18784b3940420af399598c4efd467dc73b9235dc891d3", + "size": 1745580 + }, + "487": { + "releaseTime": "2012-12-27T14:56:32", + "sha1": "610de83860eec1991f86c9965a76f87b89b08d12", + "sha256": "ff4b78cb32de1a57e7beb6fe6134033cce0defa90272dbc449745f224ad821a8", + "size": 1745542 + }, + "488": { + "releaseTime": "2012-12-27T21:24:56", + "sha1": "473485ee42c5a18ab47994bceff362da0a1bea55", + "sha256": "01f13df19856643460dc7cf95c57769ff34f1413187c6f88b858f43be28bb55e", + "size": 1745935 + }, + "489": { + "releaseTime": "2012-12-27T23:17:08", + "sha1": "ad4b1579edf9053d7c213fadcb7d10538c88a1ac", + "sha256": "241c88f0eec5b75d49a6a9561ef8af6dbe1caa3dac7977141fdc60fade59e758", + "size": 1745975 + }, + "490": { + "releaseTime": "2012-12-28T10:15:24", + "sha1": "12af97cacd54e55593e5879d5c214abe6ddd898c", + "sha256": "07ae2b7d06ef4c80c7d19e7bddf3ea610257f8989cd87016f6fc5135b49c9a57", + "size": 1745974 + }, + "491": { + "releaseTime": "2012-12-28T22:36:56", + "sha1": "5ab9a4f78adfb6b345bbca0cf8c92effee616f67", + "sha256": "17ddd3251dad9359d624fa5cd2e198561cafaa341ceb37c37a57f83f3ffbd66c", + "size": 1746029 + }, + "492": { + "releaseTime": "2012-12-30T21:03:42", + "sha1": "24dc432e3d6a7c1ff28900cfab9c7168c6e51530", + "sha256": "585981eac33151616981789662507f1019072c9891da48880e5ed48300d62e5f", + "size": 1746383 + }, + "493": { + "releaseTime": "2012-12-30T21:30:20", + "sha1": "01cf4d59115b3bf2b8cbe2e54d6703200016d2ec", + "sha256": "faef915c0307bfafb20f21db5e606a155470381e98c53f8de0f3748c859ab150", + "size": 1746349 + }, + "494": { + "releaseTime": "2012-12-30T22:09:10", + "sha1": "06b2c1905ca8de001b823b0f397d21b4b8c45dfd", + "sha256": "91d5fe316e253992c5c6b7be88e8f353bce4cbe8958a314a4c6242c6e5581828", + "size": 1747746 + }, + "495": { + "releaseTime": "2012-12-31T09:26:20", + "sha1": "90b567013a6cd3abd28f6acef8da13be80139309", + "sha256": "367de6a4bc90ad1cbf1fa4503cef59da1b00f46e9ae98c54dbca50d9a6a3039a", + "size": 1747783 + }, + "496": { + "releaseTime": "2013-01-01T22:02:56", + "sha1": "ec5da86e1eb98345401f289a677e22d9ff39b677", + "sha256": "036cfa78ffdced3f8d1e9d07a9a4cad8bfe6106ee6a2f323e0f46f7bb75cdb59", + "size": 1747767 + }, + "497": { + "releaseTime": "2013-01-01T23:23:56", + "sha1": "6734cd7a2de6fec77c0745a4fd054f56547f1b45", + "sha256": "b46dee407c06cf73bacd12a7d2ae3be48b6745f2b160c5d3853fe0c9d94914cb", + "size": 1750532 + }, + "499": { + "releaseTime": "2013-01-12T21:48:34", + "sha1": "3853b9b6c90063764d9cbcb7ff95c2bfbc2e40d3", + "sha256": "4afccd945b9536a3432136086b32e2383505bfe595a5a1e446eae032bdd98f8d", + "size": 1750887 + }, + "5": { + "releaseTime": "2012-02-10T04:05:56", + "sha1": "14c5933f019a36c72ac21447223922d225d8ca12", + "sha256": "65d74f1abb6bb748cc42f8e959974e768bcf4acc828122abf37b2c2cf8f3922b", + "size": 418025 + }, + "50": { + "releaseTime": "2012-03-12T17:00:18", + "sha1": "493cacd2e0fd442d22bf602ee630f662a94a09e9", + "sha256": "1e0b71714d6b755bb8b88833774ccf512119e4011f176921343bed43772bf0e2", + "size": 499533 + }, + "501": { + "releaseTime": "2013-01-20T09:04:36", + "sha1": "71e3564d1dd45c032f863f91ced3c5e0b31adb97", + "sha256": "f1152a34c0cfd6197a51e2ab11e0e9d792335d44334c7d4fd76b895d6d9bd5c4", + "size": 1751447 + }, + "502": { + "releaseTime": "2013-01-20T09:47:06", + "sha1": "9b5f5d1bde50cf315c59ac505b344598d31503ae", + "sha256": "f2fbe43bf2931d1c9ad60e44186c9246d3d62ed83b571faafb2662a4b5ad3ca3", + "size": 1751313 + }, + "503": { + "releaseTime": "2013-01-20T13:28:28", + "sha1": "2862ddfb1247e3fa63feaf75bb6eb89619641555", + "sha256": "4c7f9472f6ed96859baaa602f5d93a033066e6e584245bae85d44b884cd1c016", + "size": 1753210 + }, + "504": { + "releaseTime": "2013-01-20T16:53:24", + "sha1": "207a042ae365d8c57c8edca3116ade1b04ed558b", + "sha256": "eb99b88ceaf65b6090c5d1d2d8ebbacd17f363988ebef764639e038f5cde1f03", + "size": 1755376 + }, + "505": { + "releaseTime": "2013-01-21T20:03:18", + "sha1": "039029b9d3c5bca4459a2133d48488763b435391", + "sha256": "f2e15042fa418e6ac9380399a755739a4f9f8145e9f6d616516d5c0e6a594e87", + "size": 1755366 + }, + "506": { + "releaseTime": "2013-01-22T08:14:22", + "sha1": "5f3d3cba6c563334f585a0d3f2d1c1d3bfb673f5", + "sha256": "e36aa8cf1dd69e504ed58caabf140b804a172288b58b4dc343551f5d8d20af01", + "size": 1757249 + }, + "507": { + "releaseTime": "2013-01-22T11:59:02", + "sha1": "df4a34e476f7ee94a435ef8f26513b926afa770d", + "sha256": "3a2c6b8904c605c028465e4e64e71e0cb24121c705a7f271909b56b254af2de7", + "size": 1757663 + }, + "509": { + "releaseTime": "2013-01-23T21:44:32", + "sha1": "e7d8ea9367667e29a6fe3e0b56b888e34a7c6c2b", + "sha256": "6351f2bebfa1f5255f8310c06c274bcdc42ede5e262674bf7df7ef00c1a5b3ae", + "size": 1757812 + }, + "51": { + "releaseTime": "2012-03-14T11:57:34", + "sha1": "19428f0e666c4050a5f0d6ba066471fdd10a4e95", + "sha256": "b09b008c025b1a8ea35821c653fbb16aeb74a2b68a0113d5d46012c8fcd0d169", + "size": 499534 + }, + "510": { + "releaseTime": "2013-01-25T19:25:36", + "sha1": "bdbb8003de83e6c136e1ce523c12de6109726e54", + "sha256": "0b20a127a2d61edeec71ee1baba52aa92a35d82880e6c660c47cf750d0d83b32", + "size": 1758064 + }, + "511": { + "releaseTime": "2013-01-26T08:29:26", + "sha1": "37e54676fe4db1dc8cfb2b56f3d5344024aca44d", + "sha256": "06a0d1ebdb10344a1949d03cac65f73e88e59f364b4de7728dedf5e8e749221e", + "size": 1758076 + }, + "515": { + "releaseTime": "2013-01-26T12:16:40", + "sha1": "d09d5267e419bc6f35e065789eb87780bc69c767", + "sha256": "15a1c1b749c840e55ca27a2bef419f710d334351284b20526c3caab6730bfde4", + "size": 1758042 + }, + "516": { + "releaseTime": "2013-01-27T08:49:18", + "sha1": "c02c0f5e08e7c975b9b7685fb43ee41f992386c7", + "sha256": "6a7c899130ba3be06f421df8b5874f5347d28944ac2304ac321f8553345797a9", + "size": 1758848 + }, + "517": { + "releaseTime": "2013-01-28T19:23:52", + "sha1": "85730f2eab50431f06074f56fd45ac52f35e7888", + "sha256": "bdba524fdafb87e57b8c8e1beff2ae2d577a16518092198c49f4201fb8851539", + "size": 1761462 + }, + "518": { + "releaseTime": "2013-01-29T04:17:02", + "sha1": "2cd88ccf1af60465380efec07e0a3cef13f4c922", + "sha256": "05736dd9d54e6a92298a1e945da8319d88e0949bb4088b23c0575e87c0a5fa4f", + "size": 1761405 + }, + "52": { + "releaseTime": "2012-03-14T16:56:06", + "sha1": "a7a92d24b575d901506285511817bce22302bedf", + "sha256": "58dcce37e0a45cbbc79ce0efa5f19fb1f0cce4fed70fa1e34061c37c949bb32f", + "size": 500306 + }, + "521": { + "releaseTime": "2013-02-04T09:25:46", + "sha1": "087bdb006cd96f6ba343901cb49b62f10c3c1bcf", + "sha256": "648a9d61659d83d49e0f054913bd945b0d78493e5b3f939c71725e48fbd2b435", + "size": 1769480 + }, + "522": { + "releaseTime": "2013-02-04T12:03:06", + "sha1": "386872fe1744a35dec7e0311335977d9595bf2a7", + "sha256": "6550ed6b0828e93525b3186f7de2e90cf865c37fb308d9e48bad7d96ef91dcc6", + "size": 1769519 + }, + "523": { + "releaseTime": "2013-02-04T15:58:18", + "sha1": "cfe19e7ac7c15b6be821d5af5fd75beac7f1914f", + "sha256": "c8426060eb8bee5020afb0fbf029a4a2f45d2db8a6293d93d8e82cf73f144d8d", + "size": 1769094 + }, + "524": { + "releaseTime": "2013-02-06T18:36:06", + "sha1": "d86aded1f0e1cf6e6fac264be9ac3d26c1b0700f", + "sha256": "92a1c6faa1770fb2c785619834832e3a5825177206afa91d4c55a1b01d6a9622", + "size": 1769480 + }, + "527": { + "releaseTime": "2013-02-15T06:39:20", + "sha1": "6fbf800c40a7ae21cafd5355a7b8b4d8b46bf95f", + "sha256": "5dff0742023186542bdabd8019bbe58b8741328c9f88399fc4d808663781ae41", + "size": 1770314 + }, + "528": { + "releaseTime": "2013-02-22T16:12:28", + "sha1": "c81b6fbba954448137846b9b920203c7260a070c", + "sha256": "48e4bee76f2106ff36adc225c699f28d4ab7c72f420f3c3f97be5fbbb98dd38c", + "size": 1770590 + }, + "529": { + "releaseTime": "2013-02-23T12:27:12", + "sha1": "275c135f5f0617b6f5ace20d7a00f0668697d770", + "sha256": "216cce520e834f6e6239fbd0f3d5eb06344870d575115b680cbd1433814fda45", + "size": 1770653 + }, + "530": { + "releaseTime": "2013-02-23T13:23:34", + "sha1": "04a7307ba922860718b4700ca6c7858d24148f98", + "sha256": "675b7e15378c3b69483208065edace129ed313a4104c0e9a420241ac8a0e45da", + "size": 1771375 + }, + "531": { + "releaseTime": "2013-02-23T14:11:28", + "sha1": "932b3ced33034df13662f18994afaff9900c385c", + "sha256": "98fb1a46e54611e4829bf3c1434e44f4234949fc059fee564db78bc620e808c0", + "size": 1777234 + }, + "532": { + "releaseTime": "2013-02-23T15:00:26", + "sha1": "bcac19ccf60bfd4b13f6f20dab638c58cc043146", + "sha256": "36c55d2d17ac830fba3de5594b7f38c686a5f54933f0ea08aaeb9f95319c2d36", + "size": 1778535 + }, + "533": { + "releaseTime": "2013-02-23T15:25:20", + "sha1": "c3886f37a70edf593fd643db522afa1d1cbd9137", + "sha256": "3408ff09133b41cb2b3e7a667c9cbc79a4b201f30f98b889fffea8af55ce1f8b", + "size": 1778541 + }, + "534": { + "releaseTime": "2013-02-25T00:00:20", + "sha1": "bd0f40a78c18140265ff042a96d73f01c4f60906", + "sha256": "7ae860d3f7423b97b1fb5343a65fcc6866242fde23e1aa00c113dd9b61fa8187", + "size": 1778669 + }, + "55": { + "releaseTime": "2012-03-17T19:58:18", + "sha1": "4a921565b941fd8883513b79d27767622fd7440b", + "sha256": "d5baa47e296c2f18b2b69f5acf525bb3635bb728ba5c0e278c58fe71057d809b", + "size": 500341 + }, + "559": { + "releaseTime": "2013-03-09T10:59:20", + "sha1": "7cefe2301914b7859cd8282630a9a17f6c27d433", + "sha256": "7d7ab7709fbd637a51250aa2d8ee9a2eb6c6f62843d089bd90aed6b3a7ee71eb", + "size": 1799274 + }, + "56": { + "releaseTime": "2012-03-18T23:43:50", + "sha1": "21181f018ad9aad7bb173126fee729b3fb1bf51c", + "sha256": "7a64787f1c09dddbe48a3f61b283e3b2fa82b832b6a329561f45904a94547102", + "size": 500331 + }, + "560": { + "releaseTime": "2013-03-09T11:16:06", + "sha1": "513348c4938d80fcac62b8fcbfbf802671fb374c", + "sha256": "a0a3967f4371154520b5904630f51cb6eefd489c2df6aa6a5ada21f82df6c7a4", + "size": 1801695 + }, + "561": { + "releaseTime": "2013-03-09T12:20:34", + "sha1": "b64dbb4a6e5721354070ed43cc8e565f004f983c", + "sha256": "9f6a313add3dc0035bca35e227701b10df8bc3de48765c519c0ab8c324bdef6b", + "size": 1801871 + }, + "562": { + "releaseTime": "2013-03-09T13:02:44", + "sha1": "753e3a080941052cccd7375df5f63564a86b7fc3", + "sha256": "a3a65288216568e04c1195dc232fd469d0cf40a1ea65c085f5c4499076d72fc6", + "size": 1801898 + }, + "563": { + "releaseTime": "2013-03-09T13:35:42", + "sha1": "a3ac851d0aa5cd19b4f5015cf9cc1f0ccad1c3ea", + "sha256": "f3434b432994d59c16f3a73a432211a1a8064df619970f765e1d30541c0bf985", + "size": 1801948 + }, + "565": { + "releaseTime": "2013-03-09T16:04:34", + "sha1": "cccb6bf2733a4cda8b05d4a9176ab15deaa29b25", + "sha256": "0c5d591dba0d5a7589a953cb0c6e14b2a2b2f245f110f1afec909ad41bcad81c", + "size": 1802067 + }, + "566": { + "releaseTime": "2013-03-10T10:19:34", + "sha1": "471051946714e5a831d608d40f34ad09a0e81da3", + "sha256": "1c7fee319ec0bf88ad77c7ceb8f6d38095d8af9009bccdade5de1ad07ab9da69", + "size": 1802209 + }, + "567": { + "releaseTime": "2013-03-11T14:42:34", + "sha1": "85d19c0406314b6a1c931b905c8abd991342af53", + "sha256": "ea006ce61b4585283237e27995a3d5486fa26e4b0c221716ae9f320f6e2f6f4c", + "size": 1802207 + }, + "568": { + "releaseTime": "2013-03-11T15:48:22", + "sha1": "d49f2abbf3d4471d8039707e80df85d4f1a858dc", + "sha256": "e3759b326137fc5426dbc4f5606781641ed0f93266671fa653911a11cf7db770", + "size": 1802260 + }, + "569": { + "releaseTime": "2013-03-11T17:33:56", + "sha1": "895318254c2a15f84c31a4066a0c7e1d013f2bd5", + "sha256": "2ace28caa0c6bb929bf1c360699feeaef299d69ec5590d02a387e7fdfa585d81", + "size": 1802373 + }, + "57": { + "releaseTime": "2012-03-19T10:36:28", + "sha1": "3821f7764661d74ab8b84acd41c3145f595c9dd5", + "sha256": "cfb87dbd958a9cd46e1bd312a10df884f813fa738edd1db34a6a340563c50fa2", + "size": 500324 + }, + "571": { + "releaseTime": "2013-03-12T16:27:20", + "sha1": "256a746fdca6952208588476c8c1a67e214fcb5a", + "sha256": "20e49414075e9c980de3e9889eeb760b33d7696cdfff730bca8e4abd2b17fea3", + "size": 1802132 + }, + "572": { + "releaseTime": "2013-03-12T19:11:22", + "sha1": "5421a1e7613ec0c54dfe29fe78747dd4c3ed4ded", + "sha256": "e3e2cfdeb8f92d0b2961caed878ebfe8e3783a64539b03c016596ac9b90e5384", + "size": 1802718 + }, + "573": { + "releaseTime": "2013-03-12T19:22:56", + "sha1": "c4e36dfe96db003635afd8f5d0dd1ee9c9330b23", + "sha256": "dc403bfc35df2bd0ceaf91d3f33bff1f50e0fa51c01758f46a5bf61765ea543f", + "size": 1802799 + }, + "574": { + "releaseTime": "2013-03-12T19:48:20", + "sha1": "970862c9cbd70b7e31b52426ddd0cf948c9a9ce8", + "sha256": "04a7b09abd5a21eb5d75627d892b4b6971bf12f8dd1267fb902df46c35002bf1", + "size": 1803367 + }, + "575": { + "releaseTime": "2013-03-12T20:50:38", + "sha1": "0e727130e6492c26fcdea9866b91f2af8d0ed9e6", + "sha256": "13a50326c5d78cb3aea9f5fed7f415bc4499e33acb9bd41c7d30fd3e90ea3d17", + "size": 1803644 + }, + "576": { + "releaseTime": "2013-03-13T12:02:16", + "sha1": "88524debaac98b4a7e81713789a33278fe3b1dbb", + "sha256": "09ed456116397421fe20ecda9fd73e252ce953e5c9712f9ba3af5a1b5f7bb662", + "size": 1801710 + }, + "577": { + "releaseTime": "2013-03-13T12:57:32", + "sha1": "ff91a570c54f10922727007f1d89e83f73210d79", + "sha256": "7653623ab8f74478ffdfb422c5d021cc7a18906c96fd356fd90d7b0fef2d5988", + "size": 1801735 + }, + "578": { + "releaseTime": "2013-03-13T13:10:30", + "sha1": "e0cef279c9a067955e9519aaf5c28cb38c9fd45b", + "sha256": "ade4e84a7eaa1f5d5f7f9af945862ce7817f32628b800f9f86973eeb39ef343f", + "size": 1801793 + }, + "579": { + "releaseTime": "2013-03-13T13:22:36", + "sha1": "1249b4843235da3782d98d917c90d309b91bc4ca", + "sha256": "d4d4bb20f765c5c8e16f6ed9d32aa90c35c7f2c0e740b37396568c36a68f6ba6", + "size": 1801812 + }, + "58": { + "releaseTime": "2012-03-19T22:42:46", + "sha1": "9985d536259cebbb8f139f8ce3176b22039270ca", + "sha256": "06e87b5a04c7ff02c481195175d0a198e964285a9aa637e72eda0421c6018a9c", + "size": 501964 + }, + "580": { + "releaseTime": "2013-03-13T13:34:08", + "sha1": "d756a4fa056fb7b2f6768f7d0fe2d912c28b4c8f", + "sha256": "a7dc5fffffa88e4f8d0318ba7a844c63913a127926b9844104085d5450097527", + "size": 1802410 + }, + "581": { + "releaseTime": "2013-03-13T13:45:54", + "sha1": "3b3bed47c3f1779c5d2080310a20cef2474cf7c2", + "sha256": "8d3e539e593ccc4cb25845ef6901e64f309ace1072bfe43676c16afbc5827bf6", + "size": 1802422 + }, + "582": { + "releaseTime": "2013-03-13T14:20:52", + "sha1": "d38d55e839820418b8597a4c20a27926094da29a", + "sha256": "bcad9e4bb77021662a9934d03055a90d373c48e995f6a37ef09f74c984553015", + "size": 1802412 + }, + "583": { + "releaseTime": "2013-03-14T14:06:14", + "sha1": "2cbe8b97154514dbdda74c96118672356596c59c", + "sha256": "e59ec936b65388d4c757dddbe918410ef3628b406993e407d348e31ff1619b57", + "size": 1802447 + }, + "584": { + "releaseTime": "2013-03-15T21:35:12", + "sha1": "cc83161006e3001a0b6abbff6d5866c5997f122e", + "sha256": "cf35a38f6eb00d0b5939ffb6eb749f0bd0bc7efd7a5da129cca94b5bd052964b", + "size": 1802450 + }, + "585": { + "releaseTime": "2013-03-15T22:28:24", + "sha1": "67851281cd6d7300cfa4f6ed40d36ec91b3a93cb", + "sha256": "fe2ee5a25849e6772c37dab140a3025733145872bfc44048d0fa85bbe671d75f", + "size": 1802442 + }, + "586": { + "releaseTime": "2013-03-15T22:42:18", + "sha1": "28a200368e5e57b42b81515c665d547714e75feb", + "sha256": "c94fde4b5256d311b51f9a2b5df88e0f637baf7b600664f9303d43304dfdec8f", + "size": 1802483 + }, + "587": { + "releaseTime": "2013-03-16T11:52:38", + "sha1": "2cf449d932668dc49da5ceec7fd12b0bd0588670", + "sha256": "426c3326e475e5603311db05cf785809b6ea99597cf5fba9edbd718cdeaacb0b", + "size": 1802487 + }, + "588": { + "releaseTime": "2013-03-16T12:35:28", + "sha1": "9fbe0dbdf36173a5c2d873790148c533957af2c1", + "sha256": "c5d033bd0d05fef758c23a6374f1f628fba6c0102d88d0d2dcd2a313c81ec685", + "size": 1802499 + }, + "589": { + "releaseTime": "2013-03-16T13:59:58", + "sha1": "07cb240272a941a01b1314a99e3ea5dcf093a8df", + "sha256": "f23fb37f45c28e246c461fcedd135ce473d0aa3da62141408a759ce164a7c475", + "size": 1802541 + }, + "59": { + "releaseTime": "2012-03-20T06:50:10", + "sha1": "c22cb4824886aa26a95700f38768083cc84a0b70", + "sha256": "b00bdbdae11e16016759850278a79da857b7c19e91762b15b5cef2022834f532", + "size": 503801 + }, + "590": { + "releaseTime": "2013-03-16T23:21:04", + "sha1": "3c5c525447f98d3abeeceab5b68e3318273c25a8", + "sha256": "1f1e552ee329f4fbc9bec71060406dc52375aeaf0f4d25b8b585aa7268670e6e", + "size": 1806206 + }, + "591": { + "releaseTime": "2013-03-17T00:16:14", + "sha1": "75817e473b6f290c881e5de9ff7084c3807247d3", + "sha256": "3e9f5ddaebb29ee4c43f0b54b1859054b43dea5a9c4cc487f0f1706525e33e56", + "size": 1806210 + }, + "592": { + "releaseTime": "2013-03-17T13:11:16", + "sha1": "b6b44424f0c57a36d0b4d2fe38b3ddc837e0bc24", + "sha256": "978578203b4490875b4781511b0ce70f987a5c370c61b597c33aeb8168135f2a", + "size": 1806617 + }, + "593": { + "releaseTime": "2013-03-17T21:15:24", + "sha1": "868f3bd54310b460d99aa4fc948d814904834b6c", + "sha256": "3c05e042f959aa93de758811ba5c4fd6fcf2b1f8f88d014e3e4679f04bec7a33", + "size": 1808804 + }, + "594": { + "releaseTime": "2013-03-18T06:19:08", + "sha1": "05dcca538da1ba41ac5e59e74eb862121cb5be88", + "sha256": "6c6d1fbcdf7d7afd8ba6bdd085517b06c17f19122ed471505c9e87b2e27a7857", + "size": 1810025 + }, + "595": { + "releaseTime": "2013-03-18T15:37:20", + "sha1": "10fe3da7c4f5c5897e7dc1bea826529e9c6cd240", + "sha256": "9f3eee1df41b9de671fbd5ea43537d303be4c86366678b1fc2423ae1072fcb97", + "size": 1810024 + }, + "598": { + "releaseTime": "2013-03-20T19:59:44", + "sha1": "51fa60cdafaa9497465e792d3ec884c2fb411bd1", + "sha256": "ee98f47baa521a317f361ad44d3f62677343a8aa46605a949d8eac2c5a297f3f", + "size": 1810101 + }, + "6": { + "releaseTime": "2012-02-10T07:00:32", + "sha1": "469c7532e6e92ce5be68e850643a2b03b305c9df", + "sha256": "a1c33cb061da2fe86fdb7d46c8744f52b9661832de7422f22e64228eef4b323c", + "size": 421298 + }, + "60": { + "releaseTime": "2012-03-20T22:13:54", + "sha1": "3fb0ca0321285a9b7ec52bfe173ce905c45f6ef5", + "sha256": "c1bec94a7d15a2d761ca132b3191836a9cbc57df1757ac89778494699f45f63b", + "size": 502757 + }, + "600": { + "releaseTime": "2013-03-21T05:58:52", + "sha1": "f100c13093c7cbcc647d01db0e06b033857ecc44", + "sha256": "3490da99bf1a9d02ab3723b806ea4b2544df3ef760f4d3f3716e28d125f617d8", + "size": 1812847 + }, + "601": { + "releaseTime": "2013-03-22T00:00:40", + "sha1": "65b86fdcaf4f0d3ae39f4ef6060df038c0246a4d", + "sha256": "6b828b19a733beb784689c651f31576d49a4828a4bd1ab6d326028f8c75db4e0", + "size": 1812890 + }, + "602": { + "releaseTime": "2013-03-22T07:38:02", + "sha1": "02c4747b8f443a6baabd42808641901c7316d10c", + "sha256": "e992506a04eea308de41e0440acfcc2c5862aa815192864de874511213772ce2", + "size": 1812888 + }, + "603": { + "releaseTime": "2013-03-22T10:43:46", + "sha1": "035a390467f9f8fee7109ed68261b97ba4d3b4df", + "sha256": "87fa43b1060b04aedc0c51896605cb5218abe9286ec8213312e860da86abf782", + "size": 1817618 + }, + "604": { + "releaseTime": "2013-03-22T12:14:54", + "sha1": "d08a3ffc03ebe236906205dad90a172f6170eabe", + "sha256": "b88c74203121c64ec61db3b5c80ba684ce72ed9b81dbe30fe4c965c3a6bde6ca", + "size": 1823680 + }, + "605": { + "releaseTime": "2013-03-22T15:03:40", + "sha1": "4f500cf41d5c988df867232ca366f329b1bd59e7", + "sha256": "1ae4763067a05b6774ae49929f2f003ab239fdd8e8e63bbcb0d7eae2b25af426", + "size": 1823687 + }, + "608": { + "releaseTime": "2013-03-23T21:30:56", + "sha1": "decac58077e666780177384985f01079c4e2bab6", + "sha256": "01db87c37d61ea353d92edf8f97fba8b1cc8100f59e79208b2fd7ed7a57ba01f", + "size": 1841717 + }, + "609": { + "releaseTime": "2013-03-26T12:14:08", + "sha1": "487e2e3d063d55b585d0358822b7b62bd3f457de", + "sha256": "190a33807674e2d0f4d9ba40ecdc11efb99fd42582283d0c5b5ed0598757c57f", + "size": 1841499 + }, + "61": { + "releaseTime": "2012-03-22T20:01:10", + "sha1": "d0ba974da976e9348c3b8497a606d888839034ac", + "sha256": "0074d9e139b79f4f1bddcef86fef87b79c28cfc1fd7caa421a76fd66d8ed6ca9", + "size": 503013 + }, + "610": { + "releaseTime": "2013-03-26T12:32:10", + "sha1": "f19d03346de350b600a1485e3736ea722feec731", + "sha256": "8474514cfc245e9c9c7429552cf09ba80b5ed4a8b4eb04d37c76f9a86fa25d98", + "size": 1841597 + }, + "611": { + "releaseTime": "2013-03-26T21:59:42", + "sha1": "2b5c9e928b14eba5985fdf99141e0b4f36f4919b", + "sha256": "a10a3303eb45fb206fc86dca357cc6414b5de313882f34f5a9d7446e85b5bcd4", + "size": 1841630 + }, + "614": { + "releaseTime": "2013-03-27T17:34:36", + "sha1": "ad15e8ff0469a674421d8b91447543ad5ddae4e5", + "sha256": "f6fdf613e51cee90807544e96acf2b0ee71160fd11e4fb6cce43506254ed4229", + "size": 1842016 + }, + "615": { + "releaseTime": "2013-03-28T06:16:30", + "sha1": "2f846dac453503c38e94a2ec4b1912c4107ad6ea", + "sha256": "46fe09a4b47cfea1314406db10ec52446187bf9d4ee82d891fe445f06057e95a", + "size": 1841842 + }, + "616": { + "releaseTime": "2013-03-28T06:32:18", + "sha1": "e924ed455c1352274bf758b61290c5cddfccf16f", + "sha256": "905002cc9488c0e553b24f602280e672911de6a7d3e8c5d102b9d64c1ebab3bf", + "size": 1841905 + }, + "617": { + "releaseTime": "2013-03-28T15:50:34", + "sha1": "9293a9a74adb8991c6057b3cdfc985276ead3a71", + "sha256": "21ae46fb70a81ca1140a4e499b8971c66d8dfba5d2b37fd47ff4e209fc67d927", + "size": 1841930 + }, + "618": { + "releaseTime": "2013-03-29T10:54:14", + "sha1": "eacfb8930e7426c7aad65db03f1c4d47f9a629b4", + "sha256": "bb60011ad40b9967458f7f94dd38b169487f273f3063b29e6387ec9a101ec913", + "size": 1841693 + }, + "62": { + "releaseTime": "2012-03-25T23:38:34", + "sha1": "4764871665c79041b233e06b62951b6500693007", + "sha256": "0ab4b860362867ca3eb3f18db522a74876f1cbe8d9e9fb50892f8003a21691ca", + "size": 503894 + }, + "620": { + "releaseTime": "2013-03-29T14:30:48", + "sha1": "fba2fc79ab6adbf37543ba7c832ff69dd9e4bca8", + "sha256": "d64106428e99e04b2a8200f8bb1f7a5dd415c5e16e1c244a976eb8ca53bb5a64", + "size": 1842046 + }, + "621": { + "releaseTime": "2013-03-29T19:53:46", + "sha1": "2fd638d07a63d3d266dd1f355a0037d8a121a75f", + "sha256": "89eab9898290cf4361784c3f81ed6be8445483935fee900e5a19f1266ec71095", + "size": 1842165 + }, + "622": { + "releaseTime": "2013-03-30T10:26:26", + "sha1": "aa86d940795a19314a97225bfcfa58ad5f466384", + "sha256": "1716af38d742c935515879897795b4ae6b91066ab2dcafe9db1de1847b3baa44", + "size": 1842514 + }, + "623": { + "releaseTime": "2013-03-31T07:59:12", + "sha1": "8958c9643b16640342f0b63396c6f2cf2072099b", + "sha256": "5c9e09c1c5524db1a5eddb09ff57ff7078cebce970ac266bbc83f5732a73ce43", + "size": 1841475 + }, + "624": { + "releaseTime": "2013-03-31T08:34:44", + "sha1": "20aedfa6e7d255f99adfadf9f345c3ab9aa5a521", + "sha256": "756c0869814858979a866381e09f53565461e7964a86d97ed26602ff4b2a225b", + "size": 1841511 + }, + "625": { + "releaseTime": "2013-04-03T01:01:26", + "sha1": "985c86a6b349d03952897f0b516b4970782ccd97", + "sha256": "feb6b97edd2501de5825624311c90a5a05b23b67a85331d00b04132f7362f5e1", + "size": 1845610 + }, + "627": { + "releaseTime": "2013-04-03T03:17:22", + "sha1": "887556c1ee0c9cec4447ed38a4abf09858266aaa", + "sha256": "a1cfb5ed61fffd2291407da332876db576c5008eb3319c75e35773c50bedbe4c", + "size": 1845607 + }, + "628": { + "releaseTime": "2013-04-03T03:37:02", + "sha1": "686799aaadad7814253190bdb0a1fc7560451178", + "sha256": "3eaac663cc980ac9a4563e239dcbc134f2047cb700230424a5c558e996d9acf9", + "size": 1845673 + }, + "629": { + "releaseTime": "2013-04-03T05:16:26", + "sha1": "d3aa64bfdacbda1048ccaa9f5238f1f541528ad4", + "sha256": "1e356867221fa36ae1e60e4be61eade98675eecb1f92c82b30fe41fd27de7ecc", + "size": 1845744 + }, + "63": { + "releaseTime": "2012-03-26T02:56:50", + "sha1": "4fe8f595c76a6ac45d2243e610222b05f5d5696e", + "sha256": "fc55e2ba6f78afe8ca60dc6d2388e8510ba8262160c6acf11b1ff7b64bea6042", + "size": 503843 + }, + "630": { + "releaseTime": "2013-04-04T17:17:08", + "sha1": "67a728e15c95d5bf0c79c4bd2eb5a6cfe9ede6c0", + "sha256": "c3acf9e87f951770d71e4d4f082424f2c10523e2987d7201adfddfd047bf19d5", + "size": 1846619 + }, + "631": { + "releaseTime": "2013-04-04T18:39:42", + "sha1": "6444644de15fb9780b66a51008124dcc78bf36bb", + "sha256": "737d1307d2585a5ce50384476fc36b8f74e81db48af542737764a16c5c3f1c4c", + "size": 1847007 + }, + "632": { + "releaseTime": "2013-04-04T19:04:58", + "sha1": "315204071999b6f5b71ddc7e146a00462e68f2af", + "sha256": "8961e9275dfde5b55f4503b0ca12fa50dd79295ad7f6eb7edf6deeccfef7c25b", + "size": 1852106 + }, + "633": { + "releaseTime": "2013-04-04T19:22:44", + "sha1": "d52c199a6699a8a5c5192e2024d5f0b08c987a5c", + "sha256": "329ee4d1b752025c123df1511f120a36c76e58d9604558d7420ff9c58f10c2b4", + "size": 1853907 + }, + "634": { + "releaseTime": "2013-04-04T19:45:34", + "sha1": "19d4a565a3a3fa307d1a7691a18f15b7053ec9c3", + "sha256": "ea4473393f4fd4b05d136f09bede7f163cfb3ed349b90385cd9aee308de75a53", + "size": 1862442 + }, + "635": { + "releaseTime": "2013-04-04T20:03:00", + "sha1": "51b985a55285d32017de00f585b9f36142de6fce", + "sha256": "0013a81965e4a557753088da180a9117ccd15a399ca9f289be4ebeeccfa49300", + "size": 1864201 + }, + "636": { + "releaseTime": "2013-04-04T20:19:58", + "sha1": "ce0ff3cc72c656a36d574fcaa13c5e948d0e96ed", + "sha256": "6d5858ee8a582757b9d9e90466b741c360aadb19e7c9db0d7e03cf471ae8906a", + "size": 1864670 + }, + "637": { + "releaseTime": "2013-04-05T00:44:22", + "sha1": "63e4e9126f9db7d938d5172d9cd892f9e8570b71", + "sha256": "0e88cdfdc1bfc123ec1f3c171721d16b7ddcfef16710762b2ff3e549caf4535f", + "size": 1864839 + }, + "638": { + "releaseTime": "2013-04-05T11:40:16", + "sha1": "6b837529e509ce80bf67a708be7d9160d58a3b77", + "sha256": "6fb257167c1752f8d35ce73f3212b0648ed105c86bd60ce1d2f460b80c7ba55b", + "size": 1864944 + }, + "639": { + "releaseTime": "2013-04-05T16:21:02", + "sha1": "d49ebade7765363fa5d227cbef125969f0848407", + "sha256": "d6d5c05f335e67031e78637be76ada17eabca3f7de020f512104ce0301bd9ef9", + "size": 1864957 + }, + "64": { + "releaseTime": "2012-03-26T04:37:02", + "sha1": "e590a6e7f9cd6d0b683010abca34c69080893c28", + "sha256": "fff2343e68c5815b9aa664770d493543a4f016af5a0160556c9fb5a6b098e429", + "size": 503843 + }, + "640": { + "releaseTime": "2013-04-07T22:55:46", + "sha1": "e7c2fe9a95126c6c1a048df07f6a055aefad290d", + "sha256": "9b92c7b583c86186fe0e60515412389f5885c1f1962b3d8691f177051681f6e7", + "size": 1867592 + }, + "642": { + "releaseTime": "2013-04-09T19:28:00", + "sha1": "d5ba1d70d59d8a8b7840ce4dab9ae70c5a63de31", + "sha256": "496a0cb967490a83f15d439896809dd498da25a210b5ab34de9ada2fdde0adff", + "size": 1871955 + }, + "643": { + "releaseTime": "2013-04-09T22:12:00", + "sha1": "eb9b08f9fb309260302a7b3be845dd9e8168ebff", + "sha256": "e1d1e43d8592d4cd237a0b2528111a7f48f616554454ce8049a0d46e8b1121d2", + "size": 1874769 + }, + "644": { + "releaseTime": "2013-04-10T07:06:26", + "sha1": "efd54911c2ca6f4c300451f94b2840e93f5316b1", + "sha256": "d02b73facccf65d96b33c13e1d98965491e19117bc445b1f29279f844e713b0b", + "size": 1874656 + }, + "645": { + "releaseTime": "2013-04-10T12:14:10", + "sha1": "db855176a6c2d4e869a875cb51dcf0c244726fa9", + "sha256": "fc18fef4c1ee6f7eacde0f4ff6ce582123aeec6092407e9b4a5d23b47470f33e", + "size": 1874885 + }, + "646": { + "releaseTime": "2013-04-10T16:46:34", + "sha1": "0a4310d327dba9c1d1939a8da17a46015cfce441", + "sha256": "c70b0203184883682daafc854c0575fcc9291fe348858aa481d32c062692be8d", + "size": 1889074 + }, + "647": { + "releaseTime": "2013-04-10T17:01:26", + "sha1": "563345cc96844f8005374f64dae2dc78d989e43a", + "sha256": "0e4f5c0fc1c681eed6c84fc715d0e1aaa9ddaa46726837ddc3046a4c8c70810f", + "size": 1889074 + }, + "648": { + "releaseTime": "2013-04-10T17:42:02", + "sha1": "dd37e5b9ad13c7b07983f872818f86f42896c437", + "sha256": "b83d160c0d210f99fd32a510dbd39af972ad65d4813a7efb0f6b6fe32f1c26b6", + "size": 1889326 + }, + "649": { + "releaseTime": "2013-04-10T18:05:30", + "sha1": "fc44d88885a297f2fcaae01262beb460d9044840", + "sha256": "1141912de80faedc8ded1128cb6c73428dbf4223b525f050e26b94def2551ce2", + "size": 1893066 + }, + "65": { + "releaseTime": "2012-03-27T00:44:54", + "sha1": "fdf2e7bdc7ca3cd179b82c4b690e208f9a62bcaa", + "sha256": "d70dabe8ee2f6440b0f612fe61be8e6e990dd97eed60c7dbb98b7820eab16a7a", + "size": 503852 + }, + "650": { + "releaseTime": "2013-04-10T18:33:56", + "sha1": "f862748c96233f922bf2983198251c0d4466cfa1", + "sha256": "78b95b183f8387f6f031f81ebe2556765931302c4b74a0e4d1098e2c1f198e08", + "size": 1893143 + }, + "651": { + "releaseTime": "2013-04-11T12:49:12", + "sha1": "076eeff722342a367058fe5ab60ce355335fe676", + "sha256": "4a30217b29fc967fed7065c5c00bf045e9512eccc68324db44e0b480d12bbf93", + "size": 1900288 + }, + "652": { + "releaseTime": "2013-04-12T15:23:20", + "sha1": "680fc079a7ed7a92cc30db07a50d7318febdfbcf", + "sha256": "7cd5153a145b8d5affda63beeba6dfda738ccda225277c21e0550caac073acd7", + "size": 1898972 + }, + "653": { + "releaseTime": "2013-04-14T22:50:24", + "sha1": "02297c606a18a47ef0159b743f107ce8c4c796b1", + "sha256": "d3cb69d82969dbc8a62858d2fbf54d30d7d088a7d8fea79b194f6e5b0465f584", + "size": 1901921 + }, + "654": { + "releaseTime": "2013-04-15T11:24:44", + "sha1": "79952eda8d6f6350f8d9dbfb775b9f3c9f7a6b45", + "sha256": "1cc0106a37883f7eeefc73e81c4078056f603d99a6c66c6c9f1fdad5d7ca1410", + "size": 1901953 + }, + "655": { + "releaseTime": "2013-04-15T17:11:20", + "sha1": "f070ee134a478cf2c04457e38523ecfce8b6c46f", + "sha256": "b2af5209824736919c5fe6dc2a77a19ebd3c1c80c127db6ea08058219fceacc9", + "size": 1902601 + }, + "656": { + "releaseTime": "2013-04-16T12:03:34", + "sha1": "a893fec9952765389312a7af9a71180774258051", + "sha256": "e3ea6746adca859367fa05aad6257a81e6b10052a34a116fa92bfd99eefab6d3", + "size": 1903303 + }, + "657": { + "releaseTime": "2013-04-17T15:09:52", + "sha1": "70dce35b96dc4d8de33cce93219caa0b3eae98ab", + "sha256": "87fd6f594e94d8ca6a806911f1da5897a9feaede5daf63f899868254adcdd084", + "size": 1903009 + }, + "659": { + "releaseTime": "2013-04-17T20:27:52", + "sha1": "0318a86dafe9b34f17d469f4db59254370e53d16", + "sha256": "8b55ceba1e73e9e10c45da5368554c1996102907de265a58110c258eff8dc853", + "size": 1903124 + }, + "66": { + "releaseTime": "2012-03-27T01:04:54", + "sha1": "ff7197ad0ee80015b31109a7b042d57627ec1248", + "sha256": "0b0fd015dbe8d2ca139ca4b95800cd8e61499ed55bce18b94333811b6109042f", + "size": 503851 + }, + "660": { + "releaseTime": "2013-04-18T15:28:58", + "sha1": "ff188d20471985d2f2e5fd73859271ad0ed6d519", + "sha256": "a17d872ef84e533b369a4b8d4b83d5564d397c29054c16c021af80357e1f0eea", + "size": 1903328 + }, + "661": { + "releaseTime": "2013-04-19T11:59:40", + "sha1": "29d1a1aec78fe793d96e41cec7d3d7caecfa7787", + "sha256": "73a6e3aa3a9346491299761ab0558cbcedf056256ff97ac1b8680ecd3aada47a", + "size": 1903438 + }, + "662": { + "releaseTime": "2013-04-19T23:14:02", + "sha1": "f77e0c8e14c80c07b42161218b59be8fde0bb341", + "sha256": "ceaaae977aac1edb3c518f77efbccecf459ab93b3c77ff2ba002302044f8113b", + "size": 1903425 + }, + "663": { + "releaseTime": "2013-04-20T12:31:26", + "sha1": "61399f70ca08255d09b3ff09b30083d2e9de471c", + "sha256": "3ae90dce0661a86b10a85c80ab487272f97dffc2c65fbf84ae5c1fa0cc91524d", + "size": 1905710 + }, + "664": { + "releaseTime": "2013-04-21T01:20:58", + "sha1": "5c9759fb7183a96d86faf8a5b715afebe2254306", + "sha256": "23ff1c9d97b9fff49223a08207137a9d70081d94b52f8827932029dc06963b5c", + "size": 1905898 + }, + "665": { + "releaseTime": "2013-04-21T11:47:24", + "sha1": "d55b620f5550af53bb7f6a8b9289c87240ce2519", + "sha256": "e4b9bf245caf46efd9643bac2e035c2b422bf445ba599b451d3f4bc24a49deb8", + "size": 1921258 + }, + "666": { + "releaseTime": "2013-04-21T15:01:28", + "sha1": "b09a58b89476fd18e461dec1bedb9a60889ee192", + "sha256": "db41ae60dce1e47363d3b046b68d7ab15b5fe1b42c84c153246b3a23e83d19ec", + "size": 1922439 + }, + "667": { + "releaseTime": "2013-04-22T19:21:50", + "sha1": "7556b581a57f140413b3467dcc6d9139b3f15bdc", + "sha256": "d491dd5c2026bdbcd7b545ebb830db0d1a23caeac03351b2ce299be5f34935a4", + "size": 1922690 + }, + "67": { + "releaseTime": "2012-03-27T07:32:36", + "sha1": "9558cb918a1766d2e11ebba352eff9fcc5a23437", + "sha256": "a979d8479974c422973970d1c27c1b57fe9b3721a1b082f42e327c69c36486d9", + "size": 503826 + }, + "672": { + "releaseTime": "2013-04-23T20:56:40", + "sha1": "1738bc1cf39d465cf78d24b8f31784cb3568ea13", + "sha256": "259a465b177aad0724da4815619f046635881367ca93b525ed305001a4134bd0", + "size": 1923182 + }, + "673": { + "releaseTime": "2013-04-23T21:42:26", + "sha1": "d3f2eb1683bf8ab158aabcff2f2eb3daa0deb31d", + "sha256": "4131973e4eb330e64a135ca7687efe66eb6d49ddc958b3b90ddbb7af511fa61e", + "size": 1923226 + }, + "674": { + "releaseTime": "2013-04-24T11:58:00", + "sha1": "a8aba7c84b23427100b9d60d7337165430abd034", + "sha256": "af174f6c991ea67c3d85bb122f13ae5e7764abfe745783af0ae719356d5ff9aa", + "size": 1973350 + }, + "675": { + "releaseTime": "2013-04-25T19:51:18", + "sha1": "fd98cd49077ce57749235316d7a428545ba4d2b4", + "sha256": "7e112989d08179b444f7aba1f6b1441654121d92c2e9eaf661dcef3f04203edc", + "size": 1973642 + }, + "676": { + "releaseTime": "2013-04-26T14:15:34", + "sha1": "4a80718c75542fed023bb178c11695373539d329", + "sha256": "cada7dad8f5966da437187416413ac8e72cbf2824bbb99314b3bf9e1df5bfe4f", + "size": 1973741 + }, + "678": { + "releaseTime": "2013-04-28T15:27:56", + "sha1": "01bc4839acb7b32a5214906d5f7c1612da1fd5f4", + "sha256": "df6647bd1e408ebc55a9779c1d5b660a24855c2189ca0d04bc0bf4cbd62b37b7", + "size": 1973777 + }, + "679": { + "releaseTime": "2013-04-28T16:41:22", + "sha1": "94fbbdbe7dea9ec402fb821cf1a1472507b67a18", + "sha256": "6b54ce0df3f2f97d02233c0ce13e6dbd40b9c2402888fc1e107488ba9bf88042", + "size": 1973698 + }, + "68": { + "releaseTime": "2012-04-02T02:32:02", + "sha1": "472933267af1bd5693f2aa4e89aaad48cfe2d629", + "sha256": "9c9c26dabe099bca7ec29eed9ce8b90f4d55b91b39693170b171084a7b53ed8d", + "size": 504946 + }, + "682": { + "releaseTime": "2013-04-30T21:26:14", + "sha1": "2832ae601b5aac519f82ef4f784d6029b4e6b806", + "sha256": "201cc3b2af2175ef7ee6bc347bbfdcc9cff6e2cfa27ab30eef53aaf62de8e339", + "size": 1973847 + }, + "684": { + "releaseTime": "2013-05-02T10:24:50", + "sha1": "90c15460f12138f90d0ebe23cc32aaf589b3cf1f", + "sha256": "3383e9062ad778d867405eb04eaf7a3ac9b0bcccd3b7b47ce96cdc535725f415", + "size": 1975130 + }, + "685": { + "releaseTime": "2013-05-03T15:46:32", + "sha1": "50b4d98c368340f96e1d85c6a1c98f8158b39f66", + "sha256": "0ceab9100977dc466efe00ce5e65db2261530a7f2fae9a4376abd674478cd45a", + "size": 1975158 + }, + "686": { + "releaseTime": "2013-05-04T18:49:10", + "sha1": "8a176209473781a6870b9c600c33891807a51d23", + "sha256": "9f28c0dd3737df5911d53442b821768ac373e0db618211e60baf31823ff92df3", + "size": 1981647 + }, + "687": { + "releaseTime": "2013-05-06T20:16:46", + "sha1": "015aef26f6a8eb2ae95485c65e8cfa814715e647", + "sha256": "acc3869918a12f3d97506f9eaab9d9029a2d573cf736ffc67b9e9de2825ba8d2", + "size": 1981935 + }, + "688": { + "releaseTime": "2013-05-06T20:32:26", + "sha1": "3226d1cce1245b1c1e78da9fcbccf9918a8325fd", + "sha256": "8c2ac223476f8e37fa58fb93e0966704aee0a3a9bfafff7207a27fa1fbb0dd0d", + "size": 1982018 + }, + "689": { + "releaseTime": "2013-05-08T17:40:56", + "sha1": "710184c7c19b2be41ae111a930ad878089e1f851", + "sha256": "94bbce5bc8cfbd311cd031391e618dd6aa940bd83735f4a574c890360f706eb8", + "size": 1996416 + }, + "69": { + "releaseTime": "2012-04-07T04:32:06", + "sha1": "75f13154c3196f749bd0db90d9cfeb08273882c0", + "sha256": "5346560a1c8feb740834a06d3e621bbb952aeef734a661a4f937b694770e02be", + "size": 503459 + }, + "690": { + "releaseTime": "2013-05-08T18:19:54", + "sha1": "d4d81fa3ee06a0376f1ea988d4d5ce01bdb87d38", + "sha256": "8aa17bfad0efd2b681c24cb2c361e5b42b645121ea856b650f3d66e9765f4783", + "size": 1996762 + }, + "691": { + "releaseTime": "2013-05-09T02:10:34", + "sha1": "d26816531b8a602b1017fc12c5751b3f0c898f91", + "sha256": "164b63443db99450ffb21e210e2c4cff5b6ac1811274ca22b099048a53b13316", + "size": 1996885 + }, + "692": { + "releaseTime": "2013-05-11T02:12:34", + "sha1": "a6db5508997a1c7da4967be62566a8a9ecbd76a8", + "sha256": "04baab4a61ac567b19a16ccabc2d24621246ec5a8ead0de6964311640bcecbfa", + "size": 1996907 + }, + "693": { + "releaseTime": "2013-05-11T11:05:56", + "sha1": "929858c287ebf13a0dbdbae880cee535031593a8", + "sha256": "bbf24f529798daaf1853bf30b5f716b9d223be7aaa9e75a21d681fb704971593", + "size": 1996968 + }, + "694": { + "releaseTime": "2013-05-11T11:21:40", + "sha1": "d0aaf895840de87de21ac2e39b402b2462108365", + "sha256": "8cc42ebd28541937c1ab671f88d536f2904fc0dba8706761703266076009d897", + "size": 1997048 + }, + "695": { + "releaseTime": "2013-05-11T12:05:32", + "sha1": "df03ea2882aba13d16a806a25c487b0b63d80e12", + "sha256": "2fd71dbf432d2602f884e457f981285725fab90d6461d15b663afdc776b30ef6", + "size": 1998522 + }, + "696": { + "releaseTime": "2013-05-11T13:23:26", + "sha1": "63ca0f99d1cbfa1aef0cb3464d72f1bdb675fe8f", + "sha256": "8675a75da788e107451398ebabba25b8e6b8ed74ab5b75f47c4447019ff4d180", + "size": 1998669 + }, + "697": { + "releaseTime": "2013-05-13T21:40:24", + "sha1": "a67ec8dab25c86822284b73b9be0d895548191bb", + "sha256": "be9e0180ccb4481193d2a99e1327c21c6e3b0248a30c90003f7383a4d6cd20e1", + "size": 2001775 + }, + "698": { + "releaseTime": "2013-05-13T22:11:38", + "sha1": "23476d809fea3460ef2cd61e6198806ec826c2d8", + "sha256": "7232431f16d42899b6a2a56dbe049e23d30489fb66f98406da1893ce0d7b4cc9", + "size": 2001837 + }, + "699": { + "releaseTime": "2013-05-13T22:27:50", + "sha1": "b1c584f190dd2a3802fac3323ac2f939ccf1539e", + "sha256": "ee6e58c5d956d61ebcdaf76ae5693bc2ccb56fa11da67db7c149392aa589058f", + "size": 2001888 + }, + "7": { + "releaseTime": "2012-02-10T07:13:14", + "sha1": "9f74f177ac12b2b99d5418133a48d829c7065163", + "sha256": "5bf54ac1cccba02d30c2f1bf39b06c18f1e7fbdccfb80a60bae2dcbed2e6d111", + "size": 421307 + }, + "70": { + "releaseTime": "2012-04-07T08:10:50", + "sha1": "76b6d4414355a4451f568223f8ed8a0707ab5c0c", + "sha256": "15e2fc339c8bd32383cefa4b3964af35decfc94872f65b039327a0c491753ea0", + "size": 503473 + }, + "700": { + "releaseTime": "2013-05-13T22:44:34", + "sha1": "ce3831b7f357872c476221e28facfa430e9f84f9", + "sha256": "d3c2e269d14b40bfc330f0d532d5c117201b409bae9dfb344ab5373cd2b9001d", + "size": 2002002 + }, + "701": { + "releaseTime": "2013-05-15T18:36:52", + "sha1": "5f7141eefcb4ed3fcb87e638cd7d2eefa0457e2a", + "sha256": "5ac8b8c591cce7ad7623aa62bf569ced84dca30574bc268f8e2de6f80e3ca54e", + "size": 2004225 + }, + "702": { + "releaseTime": "2013-05-15T18:58:42", + "sha1": "8c1422010f057f81d3ea0fbc73bc8e04e04ecb45", + "sha256": "ce2852ad64cf8f6315aff0a294091b586a313da6fa5dcefe956766247c56cd51", + "size": 2004573 + }, + "703": { + "releaseTime": "2013-05-16T08:19:28", + "sha1": "39bb7c0c79e942046675d85e3b60ece4dc7b4a58", + "sha256": "4581ed106a8f9819fde5b7c76a575ab3428b3970bb767c2acd73a906bb90bcfd", + "size": 2004639 + }, + "704": { + "releaseTime": "2013-05-19T14:37:58", + "sha1": "c3948bab0718823ff488bbd7c15e5f3fd79fdfa2", + "sha256": "5be44a78b162876127971f551f6306460a20b9e87fc5b87a7872d590c35f3aa4", + "size": 2004691 + }, + "705": { + "releaseTime": "2013-05-19T14:55:40", + "sha1": "fb0fb76a907588402ac8416d3d37725da8ac7e8d", + "sha256": "249c828331f213d92e4d4484eaf4d0fb6dda8db572551a6b7c3727907124c715", + "size": 2004808 + }, + "706": { + "releaseTime": "2013-05-20T19:58:56", + "sha1": "3c12441da278d3cd993afd3822585797a5d788cc", + "sha256": "74a22bca0f957f7328b158d14e991adc7f26a2bd7cc95c8f23e2dc4a0fb2cf82", + "size": 2008262 + }, + "707": { + "releaseTime": "2013-05-20T20:31:34", + "sha1": "b079436f13cc59cdce6f54e0409d99c0222130f3", + "sha256": "f4b435c84e3a8a44802dc8ba476027c5d7b379852713677b403a38dcc411b115", + "size": 2008384 + }, + "708": { + "releaseTime": "2013-05-21T09:10:24", + "sha1": "ed6c6e9bb5b8b3ab7d6281717ef67359d687c326", + "sha256": "fbdc9297bb1ba5760928d1ef77f610d295a49ba15f1d937e4db87ea76a03e552", + "size": 2008476 + }, + "71": { + "releaseTime": "2012-04-07T21:15:22", + "sha1": "43034ab1176c672ff81b658d8071cd7955a50fcd", + "sha256": "4c7d2eaf146ad1d492434b03a4b7f46c7e91469edda17e3f1cfac270bd4a95e7", + "size": 503475 + }, + "710": { + "releaseTime": "2013-05-21T21:20:08", + "sha1": "0b8d1daccad003be2e930b9391fa87aec2c9d8bf", + "sha256": "d0eef0327f00aadf59c7215d834f9ea7230bbce84e303cea0cbb9ec32eed3440", + "size": 2012979 + }, + "711": { + "releaseTime": "2013-05-23T23:14:24", + "sha1": "c78c3775b880b2b45e8b6b14769da6d2b4748037", + "sha256": "c247dd77fbff8c16a8834fce812f618d34ed4663ead3c7f3f3b1f4a88b446be1", + "size": 2014309 + }, + "712": { + "releaseTime": "2013-05-23T23:31:14", + "sha1": "228c0999c5a224d8290e29823c4dd31b5679866b", + "sha256": "b52b2f0cf5b2dedc06185c500c215ab9e7426f7342d8a4f2fe4f2dd0d7f6fadd", + "size": 2014600 + }, + "713": { + "releaseTime": "2013-05-27T09:17:32", + "sha1": "51f931ead831c564033b17cc835e3c2edab1e24b", + "sha256": "cd79d0b0c55ce044664177c201fc8036a0f18431b67b7e97570ac1b991f0bff6", + "size": 2017084 + }, + "715": { + "releaseTime": "2013-05-27T17:19:28", + "sha1": "00700cefeb2effc71737f65a6cbb204effd5f300", + "sha256": "b3fad160a0d59a27a73b8ebedc40fce8c9885d7ef20fb291e820a4642eb97982", + "size": 2017367 + }, + "716": { + "releaseTime": "2013-05-28T21:44:14", + "sha1": "6118150c8c0e15a6926c62e8525f9014d14dc34e", + "sha256": "71987c72116cd81bd0e7e55ca01755946d4a0a42cc93e264b977daf6abe91f78", + "size": 2021922 + }, + "719": { + "releaseTime": "2013-06-02T17:33:16", + "sha1": "6b90d931a20413bb13c31e08e543f39dd7155d59", + "sha256": "e8dea27918aa6b5573571c8f3f008a576aa11b777d7aa292bf20b7dba0c4d4b6", + "size": 1969868 + }, + "72": { + "releaseTime": "2012-04-08T04:34:02", + "sha1": "8d3179e614985a5d8604b5e28008d36edd8795c9", + "sha256": "81c65151bdae9e7effde9df1bb281b6eda6a409340a45c5f721186f5dccc9d25", + "size": 503474 + }, + "720": { + "releaseTime": "2013-06-02T22:35:34", + "sha1": "56f9d5a36821e3deb3e8d8e5c7c12d26b007f744", + "sha256": "cc4df5646f71a005f0696d4de9ebeb558bd553cd746524e06262f40ab423dbb8", + "size": 1970132 + }, + "721": { + "releaseTime": "2013-06-02T22:56:08", + "sha1": "02323336f7d1e8e68a3feab3123ad1aaf935e756", + "sha256": "d0f1422ceaf76e44b7dfb11fa651689f43a3367863b799610a947191ec540690", + "size": 1970162 + }, + "722": { + "releaseTime": "2013-06-03T13:30:32", + "sha1": "573149c42a161efbe95627850629c801c9107e83", + "sha256": "8b8e6a0dfcf085e4687548b68fa600d8126b84066033f3ddf266c1761fbf71df", + "size": 1970177 + }, + "723": { + "releaseTime": "2013-06-04T18:24:30", + "sha1": "9d0686ede1e00c46b6540cdf9d9354d701fc1fe9", + "sha256": "399da9a77a7a90792b761a007f4fdd8ddfbb15729b0a701edfb46ec02d23fe35", + "size": 1970645 + }, + "725": { + "releaseTime": "2013-06-06T10:24:40", + "sha1": "23126c578162a9675aa80160c5f45ed602b6a546", + "sha256": "cbdd44edc72118d851521d3f65c8c3d93c7eafa88b0c22420cd726962641f803", + "size": 1970914 + }, + "726": { + "releaseTime": "2013-06-08T13:28:12", + "sha1": "68a5d447ad321f5f993a5bedd820fe4349fc4fe4", + "sha256": "9b12289096fb79acefb402d21306f0211e6d8a1ad23d4286c7491b1d11c909b3", + "size": 1970976 + }, + "727": { + "releaseTime": "2013-06-08T15:09:38", + "sha1": "50e7d54fd520da847acf2841915fbfc3aba180bc", + "sha256": "62b5ef66f76390cf5f8267a899de64bc6ab201059af5bf36d7926fb18ee35af3", + "size": 1971222 + }, + "728": { + "releaseTime": "2013-06-08T19:45:40", + "sha1": "dccd0e8722a5dd394fe8c8b3d03f631bd92aea00", + "sha256": "8c95ff2b90b1d20cfc1dbdb36b562c6de95a9bc0b73b17132a4aba39002ba3a1", + "size": 1971257 + }, + "729": { + "releaseTime": "2013-06-08T20:43:38", + "sha1": "94f3f2912a8b02cf96102c6e6d113a7892a745eb", + "sha256": "837f3081f2b570b4fd46f6c9454a3cdb3fe6221e98a1c10528b5849ed9a1ee78", + "size": 1971301 + }, + "73": { + "releaseTime": "2012-04-09T23:01:20", + "sha1": "73c54a203bda1ac2e2b99e5209a122938db118bd", + "sha256": "aaae6d2eb7d882f0bf4496687a7fd4ba9a286006b73ec2b7f896d616f5755848", + "size": 505435 + }, + "730": { + "releaseTime": "2013-06-10T02:45:26", + "sha1": "f75107ac5491862f90d446d955d064350b9ec2e3", + "sha256": "00b98fda45ca4dc97de7ec581cf3abb73b59b5f1230e30aab86f5783a4df9127", + "size": 1971321 + }, + "731": { + "releaseTime": "2013-06-10T03:14:12", + "sha1": "58c8ca5c9f80db437c5d1b6a7617616a869ff86a", + "sha256": "704ebecb955f25eb6bcce50c5fb5e8992b394f27bee610b923cb541914827604", + "size": 1971325 + }, + "732": { + "releaseTime": "2013-06-10T03:35:28", + "sha1": "4794e92c949150dcd742232dc54b340361121e65", + "sha256": "7edbd0b24a16c9fc82c3c213f7deecb18f74560218bf3231638a3d13849f1dd1", + "size": 2027315 + }, + "733": { + "releaseTime": "2013-06-10T15:06:34", + "sha1": "b15e7357fc4cd580df113b31b01d2ab096322eb2", + "sha256": "01a36247c9eca10edc6dbc833e88571063ced5ce8a327e1e3fc3a3ffe0bbc2b1", + "size": 2030486 + }, + "734": { + "releaseTime": "2013-06-11T13:06:00", + "sha1": "6c928588eb71df046994d90f1d080fdf0ddc7aa9", + "sha256": "1cd22d0160ea0e0ba73570b89d506e6bc51234e6fd819b425e527492df4d443c", + "size": 2030872 + }, + "735": { + "releaseTime": "2013-06-14T12:39:28", + "sha1": "82a1dabe45e2261606da04994cf4a68d9ba06f94", + "sha256": "7bebf6b5d546062f47b7427fcced5b3fb55618de6697ba2803fb082433816953", + "size": 2031022 + }, + "736": { + "releaseTime": "2013-06-14T13:17:30", + "sha1": "bc07940c37813839c8137ff07ef616515d75e3c6", + "sha256": "db5a8de955581d386254240cdf71191e59be2b1a17d66ecaad61f404ba792ef7", + "size": 2032700 + }, + "737": { + "releaseTime": "2013-06-15T01:26:46", + "sha1": "7b36d45f87a89071c6252f4cd50e632e7d285ecd", + "sha256": "988072f14ba1f70392e7d2305f6193f7c96399ed004896f5f489c3e04b5c6260", + "size": 2032810 + }, + "738": { + "releaseTime": "2013-06-17T09:35:38", + "sha1": "76223709288287a6a8d22ab16b43a6ab2a284a0d", + "sha256": "5758f6b77d3192cf5fe6d718a522c66fb2a4ddbc375d4b66f4b0019190d07f98", + "size": 2033732 + }, + "74": { + "releaseTime": "2012-04-10T00:47:32", + "sha1": "26e3a344b4aa38f8201109a7d965ac914c3d166c", + "sha256": "5566dea1974860dbf2d74e24ff93eeffef32c9a110e69840e40ef2a4bc339387", + "size": 509139 + }, + "75": { + "releaseTime": "2012-04-10T01:06:54", + "sha1": "8cbf482dcb0722632fd89543f623cf148c53e641", + "sha256": "c3de9491468598a5e69ace5eec1dd99489a88ee188f7cefcd0fa5f053665f466", + "size": 509659 + }, + "77": { + "releaseTime": "2012-04-12T00:51:04", + "sha1": "677b006d34ea06e3cf5aa636717142ebb2e0f8bd", + "sha256": "5a055de2522561542a0ab8aea8cf7d153787222ff81d6cd642a67cc356de8f3f", + "size": 509761 + }, + "78": { + "releaseTime": "2012-04-12T21:50:42", + "sha1": "e78981327efff67efad73471fd22218c9f98d29c", + "sha256": "a5a6efec545b7f068ac989f0ecc73de0b769f319d5b3796b09d6c8666c0a67b8", + "size": 509780 + }, + "79": { + "releaseTime": "2012-04-12T23:40:58", + "sha1": "4261e979e992ad6bfb5d76bbf6aae773774895c5", + "sha256": "603b5cd9226564b5b9217e2f45ae43fbb8636b43a62af249679ddcf42d05f196", + "size": 509886 + }, + "8": { + "releaseTime": "2012-02-13T04:20:56", + "sha1": "82de2ba21c06a352b571ea1374e428e63a91239b", + "sha256": "eacdb5ff32dc902f38e1c5fbde3e29a2a401722378f47f2a76396f13462a572c", + "size": 435800 + }, + "80": { + "releaseTime": "2012-04-13T09:56:58", + "sha1": "24e00e4620341bcceb50cd68f4f24aec2c2f8435", + "sha256": "f0bf7269da20eaff1f7c4a6d967685c65c8a70fe3cd4afc9900f2784355e3efa", + "size": 509886 + }, + "81": { + "releaseTime": "2012-04-13T10:35:16", + "sha1": "185629be371faedee1259e749921fe134c24c82c", + "sha256": "f2b22173dd2d683a05cc212db097388756adba1256eef6410901fe68e01eadd0", + "size": 509833 + }, + "82": { + "releaseTime": "2012-04-14T13:10:58", + "sha1": "f83a1d16d6b0a6f126e6da1084b53d45718e0f7a", + "sha256": "5aa92446463dd6873a71d0477e3933eae094f900e0b26b483d4304d838f351ae", + "size": 509874 + }, + "83": { + "releaseTime": "2012-04-15T07:40:04", + "sha1": "3b16bd8a6cb0c576e0c9d2c32bb063beda71fc1e", + "sha256": "3787eb348373d6cf60cd63dcd8182998e68d3c5fc71f36600546643d60c8e803", + "size": 510336 + }, + "84": { + "releaseTime": "2012-04-15T08:38:52", + "sha1": "c1320821760b73bdb195dd47cddc57f11bde9bc2", + "sha256": "e493a1d690b0b84e8088ab6047391221efec056e98d360d4a03dd9ef2ff11429", + "size": 510337 + }, + "85": { + "releaseTime": "2012-04-16T15:21:44", + "sha1": "24ad84c2b8a29a4cac503bfb40337c2246baec08", + "sha256": "5a006be9b3d6f6ad96697229a2ca413d7675c3bc9da904dc98a26edc46063bce", + "size": 510341 + }, + "86": { + "releaseTime": "2012-04-17T08:50:44", + "sha1": "9226f1ea2b7528b14b46a1550df63a941d02d4a7", + "sha256": "78202fecf9aa24e66c8c24fb5edd3fe85806135db85596ac9e36dee7454c0de4", + "size": 510362 + }, + "87": { + "releaseTime": "2012-04-17T10:30:58", + "sha1": "0822f3f25056be30419e187cdc3e4545bc837c06", + "sha256": "4b5b66c3c26a706a6c2b61b919e5f1bc418a3cca19fb6630d1bc1ed4f90729db", + "size": 510360 + }, + "88": { + "releaseTime": "2012-04-17T11:49:12", + "sha1": "cbf82171afecf4be0f0277ff0bef6646466e8900", + "sha256": "5c501a2f00233812bd746b737e4f3936044555f421f1b82a623a54ee711f3f5e", + "size": 517391 + }, + "89": { + "releaseTime": "2012-04-18T19:46:12", + "sha1": "ba77728f246cc494e84e1754f0f3ce03acb51a9c", + "sha256": "934dc21dfcdd5362554a83239669654a2e964d8621cc8165133099ff6691751e", + "size": 520417 + }, + "9": { + "releaseTime": "2012-02-14T10:43:10", + "sha1": "da9c0bad1054c5c8da8a22bf9394e14f3f70f8f2", + "sha256": "41c3ed9c7caf5d08e9d47dab1a36ce07d3c7ab1219da79fed0f486be61b38ee2", + "size": 446478 + }, + "90": { + "releaseTime": "2012-04-18T21:22:14", + "sha1": "d57947d579fe7441b65c6c1e0df7d3f8c62bed0a", + "sha256": "1ce05a2727edca09e7abca9ffe067feba6ece29de1bdd8473f7a5de4ecb4f9be", + "size": 522552 + }, + "91": { + "releaseTime": "2012-04-19T10:29:24", + "sha1": "513bf2fd928db15bde37aa31783bf243cc1e66b5", + "sha256": "c0843a2ecae1614bb18893633a47539c5ebabdd6c6e421d3de91723f850196bf", + "size": 522849 + }, + "92": { + "releaseTime": "2012-04-19T15:46:52", + "sha1": "3726362c75145a17bfd4d86bbdbc5d2770fc548d", + "sha256": "78065abadccafc87468f50013f7db8f021b00dae0a1640b222f7f3ec68a81b33", + "size": 523485 + }, + "93": { + "releaseTime": "2012-04-19T22:15:26", + "sha1": "246407ad677b342757ed635e0ff27574eed187ae", + "sha256": "2fcfadc16a4c171730e205fee1e7cd169037ac2ddcdc618f37775d1cda75d8ea", + "size": 525255 + }, + "94": { + "releaseTime": "2012-04-20T12:13:26", + "sha1": "17d961b3b62d2a050b3dfcc3598c7ea3fa200680", + "sha256": "4963274a498620988b13a142c02f6092a2b55681a0aa58309bbe0e034657bf44", + "size": 525307 + }, + "95": { + "releaseTime": "2012-04-22T19:56:48", + "sha1": "ce95bd720b3b40360dc0e8c3d1c139b22ff41819", + "sha256": "db66f23cda2d3b2a7490bde96c6105fe5ec184a89d95bab9d7a9451d1c861017", + "size": 534102 + }, + "96": { + "releaseTime": "2012-04-23T10:22:12", + "sha1": "7eb8bbd96e3dffba57cbf54b7945f1a971582496", + "sha256": "7bda8102696ca29c23edfa0889bafe062a66c31a9141e7ac5bc1a60f98545b1f", + "size": 534131 + }, + "97": { + "releaseTime": "2012-04-23T19:21:40", + "sha1": "41b4f307950fdcf862d4cdbda55384cd0af92eed", + "sha256": "fda396ff176e4cf52a9ab308ed0f1cc9883ee1223b8128546e4b49f5a8129e3d", + "size": 534216 + }, + "98": { + "releaseTime": "2012-04-25T01:41:00", + "sha1": "70c6e3b3bf059dffed3d75d1b6b83d2ddd8f4513", + "sha256": "ea6717dd33d9345ed71753278e3bc393adefb69219217f2c456657476a78a6e9", + "size": 535244 + }, + "99": { + "releaseTime": "2012-04-25T01:48:48", + "sha1": "bbeabcea70aa1bd7a24141fd34af67cf259a9270", + "sha256": "62756c8436b22a43ad56096da5e5a406daa416ba106a75ac61f165151cf55b23", + "size": 535241 + } + } +} \ No newline at end of file diff --git a/updateForge.py b/updateForge.py index a2cc8e9a5d..0492339b83 100755 --- a/updateForge.py +++ b/updateForge.py @@ -3,20 +3,42 @@ ''' import copy import hashlib +import json +import os import re import sys import zipfile from contextlib import suppress +from datetime import datetime from pathlib import Path from pprint import pprint import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.forgeutil import * -from meta.metautil import * +from pydantic import ValidationError -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] +from meta.common import upstream_path, ensure_upstream_dir, static_path +from meta.common.forge import JARS_DIR, INSTALLER_INFO_DIR, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, \ + FILE_MANIFEST_DIR, BAD_VERSIONS, STATIC_LEGACYINFO_FILE +from meta.model.forge import ForgeFile, ForgeEntry, ForgeMCVersionInfo, ForgeLegacyInfoList, DerivedForgeIndex, \ + ForgeVersion, ForgeInstallerProfile, ForgeInstallerProfileV2, InstallerInfo, \ + ForgeLegacyInfo +from meta.model.mojang import MojangVersion + +UPSTREAM_DIR = upstream_path() +STATIC_DIR = static_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(INSTALLER_MANIFEST_DIR) +ensure_upstream_dir(VERSION_MANIFEST_DIR) +ensure_upstream_dir(FILE_MANIFEST_DIR) + +LEGACYINFO_PATH = os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE) + +forever_cache = FileCache('caches/http_cache', forever=True) +sess = CacheControl(requests.Session(), forever_cache) def eprint(*args, **kwargs): @@ -31,56 +53,8 @@ def filehash(filename, hashtype, blocksize=65536): return hash.hexdigest() -forever_cache = FileCache('caches/http_cache', forever=True) -sess = CacheControl(requests.Session(), forever_cache) - -# get the remote version list fragments -r = sess.get('https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json') -r.raise_for_status() -main_json = r.json() -assert type(main_json) == dict - -r = sess.get('https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json') -r.raise_for_status() -promotions_json = r.json() -assert type(promotions_json) == dict - -promotedKeyExpression = re.compile("(?P[^-]+)-(?P(latest)|(recommended))(-(?P[a-zA-Z0-9\\.]+))?") - -recommendedSet = set() - -newIndex = DerivedForgeIndex() - -# FIXME: does not fully validate that the file has not changed format -# NOTE: For some insane reason, the format of the versions here is special. It having a branch at the end means it affects that particular branch -# We don't care about Forge having branches. -# Therefore we only use the short version part for later identification and filter out the branch-specific promotions (among other errors). -print("Processing promotions:") -for promoKey, shortversion in promotions_json.get('promos').items(): - match = promotedKeyExpression.match(promoKey) - if not match: - print('Skipping promotion %s, the key did not parse:' % promoKey) - pprint(promoKey) - assert match - if not match.group('mc'): - print('Skipping promotion %s, because it has no Minecraft version.' % promoKey) - continue - if match.group('branch'): - print('Skipping promotion %s, because it on a branch only.' % promoKey) - continue - elif match.group('promotion') == 'recommended': - recommendedSet.add(shortversion) - print('%s added to recommended set' % shortversion) - elif match.group('promotion') == 'latest': - pass - else: - assert False - -versionExpression = re.compile( - "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$") - - -def getSingleForgeFilesManifest(longversion): +def get_single_forge_files_manifest(longversion): + print(f"Getting Forge manifest for {longversion}") pathThing = UPSTREAM_DIR + "/forge/files_manifests/%s.json" % longversion files_manifest_file = Path(pathThing) from_file = False @@ -144,218 +118,243 @@ def getSingleForgeFilesManifest(longversion): return retDict -print("") -print("Making dirs...") -os.makedirs(UPSTREAM_DIR + "/forge/jars/", exist_ok=True) -os.makedirs(UPSTREAM_DIR + "/forge/installer_info/", exist_ok=True) -os.makedirs(UPSTREAM_DIR + "/forge/installer_manifests/", exist_ok=True) -os.makedirs(UPSTREAM_DIR + "/forge/version_manifests/", exist_ok=True) -os.makedirs(UPSTREAM_DIR + "/forge/files_manifests/", exist_ok=True) - -print("") -print("Processing versions:") -for mcversion, value in main_json.items(): - assert type(mcversion) == str - assert type(value) == list - for longversion in value: - assert type(longversion) == str - match = versionExpression.match(longversion) - if not match: - pprint(longversion) - assert match - assert match.group('mc') == mcversion +def main(): + # get the remote version list fragments + r = sess.get('https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json') + r.raise_for_status() + main_json = r.json() + assert type(main_json) == dict - files = getSingleForgeFilesManifest(longversion) + r = sess.get('https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json') + r.raise_for_status() + promotions_json = r.json() + assert type(promotions_json) == dict - build = int(match.group('build')) - version = match.group('ver') - branch = match.group('branch') + promotedKeyExpression = re.compile( + "(?P[^-]+)-(?P(latest)|(recommended))(-(?P[a-zA-Z0-9\\.]+))?") - isRecommended = (version in recommendedSet) + recommendedSet = set() - entry = ForgeEntry( - longversion=longversion, - mcversion=mcversion, - version=version, - build=build, - branch=branch, + newIndex = DerivedForgeIndex() + + # FIXME: does not fully validate that the file has not changed format + # NOTE: For some insane reason, the format of the versions here is special. It having a branch at the end means it affects that particular branch + # We don't care about Forge having branches. + # Therefore we only use the short version part for later identification and filter out the branch-specific promotions (among other errors). + print("Processing promotions:") + for promoKey, shortversion in promotions_json.get('promos').items(): + match = promotedKeyExpression.match(promoKey) + if not match: + print('Skipping promotion %s, the key did not parse:' % promoKey) + pprint(promoKey) + assert match + if not match.group('mc'): + print('Skipping promotion %s, because it has no Minecraft version.' % promoKey) + continue + if match.group('branch'): + print('Skipping promotion %s, because it on a branch only.' % promoKey) + continue + elif match.group('promotion') == 'recommended': + recommendedSet.add(shortversion) + print('%s added to recommended set' % shortversion) + elif match.group('promotion') == 'latest': + pass + else: + assert False + + versionExpression = re.compile( + "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$") + + print("") + print("Processing versions:") + for mcversion, value in main_json.items(): + assert type(mcversion) == str + assert type(value) == list + for longversion in value: + assert type(longversion) == str + match = versionExpression.match(longversion) + if not match: + pprint(longversion) + assert match + assert match.group('mc') == mcversion + + files = get_single_forge_files_manifest(longversion) + + build = int(match.group('build')) + version = match.group('ver') + branch = match.group('branch') + + isRecommended = (version in recommendedSet) + + entry = ForgeEntry( + longversion=longversion, + mcversion=mcversion, + version=version, + build=build, + branch=branch, + # NOTE: we add this later after the fact. The forge promotions file lies about these. + latest=False, + recommended=isRecommended, + files=files + ) + newIndex.versions[longversion] = entry + if not newIndex.by_mcversion: + newIndex.by_mcversion = dict() + if not mcversion in newIndex.by_mcversion: + newIndex.by_mcversion.setdefault(mcversion, ForgeMCVersionInfo()) + newIndex.by_mcversion[mcversion].versions.append(longversion) # NOTE: we add this later after the fact. The forge promotions file lies about these. - latest=False, - recommended=isRecommended, - files=files - ) - newIndex.versions[longversion] = entry - if not newIndex.by_mcversion: - newIndex.by_mcversion = dict() - if not mcversion in newIndex.by_mcversion: - newIndex.by_mcversion.setdefault(mcversion, ForgeMcVersionInfo()) - newIndex.by_mcversion[mcversion].versions.append(longversion) - # NOTE: we add this later after the fact. The forge promotions file lies about these. - # if entry.latest: - # newIndex.by_mcversion[mcversion].latest = longversion - if entry.recommended: - newIndex.by_mcversion[mcversion].recommended = longversion - -print("") -print("Post processing promotions and adding missing 'latest':") -for mcversion, info in newIndex.by_mcversion.items(): - latestVersion = info.versions[-1] - info.latest = latestVersion - newIndex.versions[latestVersion].latest = True - print("Added %s as latest for %s" % (latestVersion, mcversion)) - -print("") -print("Dumping index files...") - -with open(UPSTREAM_DIR + "/forge/maven-metadata.json", 'w', encoding='utf-8') as f: - json.dump(main_json, f, sort_keys=True, indent=4) - -with open(UPSTREAM_DIR + "/forge/promotions_slim.json", 'w', encoding='utf-8') as f: - json.dump(promotions_json, f, sort_keys=True, indent=4) - -with open(UPSTREAM_DIR + "/forge/derived_index.json", 'w', encoding='utf-8') as f: - json.dump(newIndex.to_json(), f, sort_keys=True, indent=4) - -versions = [] -legacyinfolist = ForgeLegacyInfoList() -tsPath = "static/forge-legacyinfo.json" - -fuckedVersions = [] - -print("Grabbing installers and dumping installer profiles...") -# get the installer jars - if needed - and get the installer profiles out of them -for id, entry in newIndex.versions.items(): - eprint("Updating Forge %s" % id) - if entry.mcversion == None: - eprint("Skipping %d with invalid MC version" % entry.build) - continue - - version = ForgeVersion(entry) - if version.url() == None: - eprint("Skipping %d with no valid files" % version.build) - continue - - jarFilepath = UPSTREAM_DIR + "/forge/jars/%s" % version.filename() - - if version.usesInstaller(): - installerInfoFilepath = UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.longVersion - profileFilepath = UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.longVersion - versionJsonFilepath = UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.longVersion - installerRefreshRequired = False - if not os.path.isfile(profileFilepath): - installerRefreshRequired = True - if not os.path.isfile(installerInfoFilepath): - installerRefreshRequired = True - - if installerRefreshRequired: - # grab the installer if it's not there - if not os.path.isfile(jarFilepath): - eprint("Downloading %s" % version.url()) - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - with open(jarFilepath, 'wb') as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) - - eprint("Processing %s" % version.url()) - # harvestables from the installer - if not os.path.isfile(profileFilepath): - print(jarFilepath) - with zipfile.ZipFile(jarFilepath, 'r') as jar: - with suppress(KeyError): - with jar.open('version.json', 'r') as profileZipEntry: - versionJsonData = profileZipEntry.read(); - versionJsonJson = json.loads(versionJsonData) + # if entry.latest: + # newIndex.by_mcversion[mcversion].latest = longversion + if entry.recommended: + newIndex.by_mcversion[mcversion].recommended = longversion + + print("") + print("Post processing promotions and adding missing 'latest':") + for mcversion, info in newIndex.by_mcversion.items(): + latestVersion = info.versions[-1] + info.latest = latestVersion + newIndex.versions[latestVersion].latest = True + print("Added %s as latest for %s" % (latestVersion, mcversion)) + + print("") + print("Dumping index files...") + + with open(UPSTREAM_DIR + "/forge/maven-metadata.json", 'w', encoding='utf-8') as f: + json.dump(main_json, f, sort_keys=True, indent=4) + + with open(UPSTREAM_DIR + "/forge/promotions_slim.json", 'w', encoding='utf-8') as f: + json.dump(promotions_json, f, sort_keys=True, indent=4) + + newIndex.write(UPSTREAM_DIR + "/forge/derived_index.json") + + legacyinfolist = ForgeLegacyInfoList() + + print("Grabbing installers and dumping installer profiles...") + # get the installer jars - if needed - and get the installer profiles out of them + for id, entry in newIndex.versions.items(): + eprint("Updating Forge %s" % id) + if entry.mcversion is None: + eprint("Skipping %d with invalid MC version" % entry.build) + continue + + version = ForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + continue + if version.longVersion in BAD_VERSIONS: + eprint(f"Skipping bad version {version.longVersion}") + continue + + jarFilepath = UPSTREAM_DIR + "/forge/jars/%s" % version.filename() + + if version.uses_installer(): + installerInfoFilepath = UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.longVersion + profileFilepath = UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.longVersion + versionJsonFilepath = UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.longVersion + installerRefreshRequired = False + if not os.path.isfile(profileFilepath): + installerRefreshRequired = True + if not os.path.isfile(installerInfoFilepath): + installerRefreshRequired = True + + if installerRefreshRequired: + # grab the installer if it's not there + if not os.path.isfile(jarFilepath): + eprint("Downloading %s" % version.url()) + rfile = sess.get(version.url(), stream=True) + rfile.raise_for_status() + with open(jarFilepath, 'wb') as f: + for chunk in rfile.iter_content(chunk_size=128): + f.write(chunk) + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profileFilepath): + print(jarFilepath) + with zipfile.ZipFile(jarFilepath, 'r') as jar: + with suppress(KeyError): + with jar.open('version.json', 'r') as profileZipEntry: + versionJsonData = profileZipEntry.read() + profileZipEntry.close() + + # Process: does it parse? + doesItParse = MojangVersion.parse_raw(versionJsonData) + + with open(versionJsonFilepath, 'wb') as versionJsonFile: + versionJsonFile.write(versionJsonData) + versionJsonFile.close() + + with jar.open('install_profile.json', 'r') as profileZipEntry: + installProfileJsonData = profileZipEntry.read() profileZipEntry.close() # Process: does it parse? - doesItParse = MojangVersionFile(versionJsonJson) - - with open(versionJsonFilepath, 'wb') as versionJsonFile: - versionJsonFile.write(versionJsonData) - versionJsonFile.close() - - with jar.open('install_profile.json', 'r') as profileZipEntry: - installProfileJsonData = profileZipEntry.read() - profileZipEntry.close() - - # Process: does it parse? - installProfileJsonJson = json.loads(installProfileJsonData) - atLeastOneFormatWorked = False - exception = None - try: - doesItParseV1 = ForgeInstallerProfile(installProfileJsonJson) - atLeastOneFormatWorked = True - except BaseException as err: - exception = err - try: - doesItParseV2 = ForgeInstallerProfileV2(installProfileJsonJson) - atLeastOneFormatWorked = True - except BaseException as err: - exception = err - - # NOTE: Only here for 1.12.2-14.23.5.2851 - try: - doesItParseV1_5 = ForgeInstallerProfileV1_5(installProfileJsonJson) - atLeastOneFormatWorked = True - except BaseException as err: - exception = err - - if not atLeastOneFormatWorked: - if version.isSupported(): - raise exception - else: - eprint("Version %s is not supported and won't be generated later." % version.longVersion) - - with open(profileFilepath, 'wb') as profileFile: - profileFile.write(installProfileJsonData) - profileFile.close() - - # installer info v1 - if not os.path.isfile(installerInfoFilepath): - installerInfo = InstallerInfo() - eprint("SHA1 %s" % jarFilepath) - installerInfo.sha1hash = filehash(jarFilepath, hashlib.sha1) - eprint("SHA256 %s" % jarFilepath) - installerInfo.sha256hash = filehash(jarFilepath, hashlib.sha256) - eprint("SIZE %s" % jarFilepath) - installerInfo.size = os.path.getsize(jarFilepath) - eprint("DUMP %s" % jarFilepath) - with open(installerInfoFilepath, 'w', encoding='utf-8') as installerInfoFile: - json.dump(installerInfo.to_json(), installerInfoFile, sort_keys=True, indent=4) - installerInfoFile.close() - else: - pass - # ignore the two versions without install manifests and jar mod class files - # TODO: fix those versions? - if version.mcversion_sane == "1.6.1": - continue + atLeastOneFormatWorked = False + exception = None + try: + ForgeInstallerProfile.parse_raw(installProfileJsonData) + atLeastOneFormatWorked = True + except ValidationError as err: + exception = err + try: + ForgeInstallerProfileV2.parse_raw(installProfileJsonData) + atLeastOneFormatWorked = True + except ValidationError as err: + exception = err + + if not atLeastOneFormatWorked: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." % version.longVersion) + + with open(profileFilepath, 'wb') as profileFile: + profileFile.write(installProfileJsonData) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installerInfoFilepath): + installerInfo = InstallerInfo() + installerInfo.sha1hash = filehash(jarFilepath, hashlib.sha1) + installerInfo.sha256hash = filehash(jarFilepath, hashlib.sha256) + installerInfo.size = os.path.getsize(jarFilepath) + installerInfo.write(installerInfoFilepath) + else: + # ignore the two versions without install manifests and jar mod class files + # TODO: fix those versions? + if version.mcversion_sane == "1.6.1": + continue - # only gather legacy info if it's missing - if not os.path.isfile(tsPath): - # grab the jar/zip if it's not there - if not os.path.isfile(jarFilepath): - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - with open(jarFilepath, 'wb') as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) - # find the latest timestamp in the zip file - tstamp = datetime.datetime.fromtimestamp(0) - with zipfile.ZipFile(jarFilepath, 'r') as jar: - allinfo = jar.infolist() - for info in allinfo: - tstampNew = datetime.datetime(*info.date_time) - if tstampNew > tstamp: - tstamp = tstampNew - legacyInfo = ForgeLegacyInfo() - legacyInfo.releaseTime = tstamp - legacyInfo.sha1 = filehash(jarFilepath, hashlib.sha1) - legacyInfo.sha256 = filehash(jarFilepath, hashlib.sha256) - legacyInfo.size = os.path.getsize(jarFilepath) - legacyinfolist.number[id] = legacyInfo - -# only write legacy info if it's missing -if not os.path.isfile(tsPath): - with open(tsPath, 'w') as outfile: - json.dump(legacyinfolist.to_json(), outfile, sort_keys=True, indent=4) + # only gather legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + # grab the jar/zip if it's not there + if not os.path.isfile(jarFilepath): + rfile = sess.get(version.url(), stream=True) + rfile.raise_for_status() + with open(jarFilepath, 'wb') as f: + for chunk in rfile.iter_content(chunk_size=128): + f.write(chunk) + # find the latest timestamp in the zip file + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jarFilepath, 'r') as jar: + allinfo = jar.infolist() + for info in allinfo: + tstampNew = datetime(*info.date_time) + if tstampNew > tstamp: + tstamp = tstampNew + legacyInfo = ForgeLegacyInfo() + legacyInfo.releaseTime = tstamp + legacyInfo.sha1 = filehash(jarFilepath, hashlib.sha1) + legacyInfo.sha256 = filehash(jarFilepath, hashlib.sha256) + legacyInfo.size = os.path.getsize(jarFilepath) + legacyinfolist.number[id] = legacyInfo + + # only write legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + legacyinfolist.write(LEGACYINFO_PATH) + + +if __name__ == '__main__': + main() -- cgit 0.0.5-2-1-g0f52 From 2950b00e1fe322dfc89a566f1fda90c93e07a091 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 15:05:07 +0200 Subject: fix: allow hashing of GradleSpecifier --- meta/model/types.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'meta') diff --git a/meta/model/types.py b/meta/model/types.py index 2fd5435e1e..e06bfd615c 100644 --- a/meta/model/types.py +++ b/meta/model/types.py @@ -58,6 +58,9 @@ class GradleSpecifier: def __gt__(self, other): return str(self) > str(other) + def __hash__(self): + return hash(str(self)) + @classmethod def __get_validators__(cls): yield cls.validate -- cgit 0.0.5-2-1-g0f52 From 6d0b9f34c81a3cee953fc8e74bccddf6ae16a23e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 15:05:18 +0200 Subject: fix: give all timestamps TZ info --- meta/common/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index ce773e4e18..d072287277 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -6,7 +6,7 @@ DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" def serialize_datetime(dt: datetime.datetime): if dt.tzinfo is None: - dt.replace(tzinfo=datetime.timezone.utc).isoformat() + return dt.replace(tzinfo=datetime.timezone.utc).isoformat() return dt.isoformat() -- cgit 0.0.5-2-1-g0f52 From 6777305c000f997183646adef2d38ae10e603ebc Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 15:05:33 +0200 Subject: refactor: move index to pydantic models --- index.py | 63 ++++++++++++++++++++--------------------------------- meta/model/index.py | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 meta/model/index.py (limited to 'meta') diff --git a/index.py b/index.py index b03e665e60..a9678362a5 100755 --- a/index.py +++ b/index.py @@ -1,41 +1,41 @@ import hashlib -from operator import itemgetter +import os +from operator import itemgetter, attrgetter -from meta.metautil import * from meta.common import polymc_path +from meta.model import MetaVersion, MetaPackage +from meta.model.index import MetaPackageIndex, MetaVersionIndex, MetaVersionIndexEntry, MetaPackageIndexEntry PMC_DIR = polymc_path() # take the hash type (like hashlib.md5) and filename, return hex string of hash -def HashFile(hash, fname): - hash_instance = hash() - with open(fname, "rb") as f: +def hash_file(hash_fn, file_name): + hash_instance = hash_fn() + with open(file_name, "rb") as f: for chunk in iter(lambda: f.read(4096), b""): hash_instance.update(chunk) return hash_instance.hexdigest() # ignore these files when indexing versions -ignore = set(["index.json", "package.json", ".git", ".github"]) +ignore = {"index.json", "package.json", ".git", ".github"} # initialize output structures - package list level -packages = PolyMCPackageIndex() +packages = MetaPackageIndex() # walk thorugh all the package folders for package in sorted(os.listdir(PMC_DIR)): if package in ignore: continue - sharedData = readSharedPackageData(package) + sharedData = MetaPackage.parse_file(os.path.join(PMC_DIR, package, "package.json")) recommendedVersions = set() if sharedData.recommended: recommendedVersions = set(sharedData.recommended) # initialize output structures - version list level - versionList = PolyMCVersionIndex() - versionList.uid = package - versionList.name = sharedData.name + versionList = MetaVersionIndex(uid=package, name=sharedData.name) # walk through all the versions of the package for filename in os.listdir(PMC_DIR + "/%s" % (package)): @@ -44,42 +44,27 @@ for package in sorted(os.listdir(PMC_DIR)): # parse and hash the version file filepath = PMC_DIR + "/%s/%s" % (package, filename) - filehash = HashFile(hashlib.sha256, filepath) - versionFile = None - with open(filepath) as json_file: - versionFile = PolyMCVersionFile(json.load(json_file)) - - # pull information from the version file - versionEntry = PolyMCVersionIndexEntry() - if versionFile.version in recommendedVersions: - versionEntry.recommended = True - versionEntry.version = versionFile.version - versionEntry.type = versionFile.type - versionEntry.releaseTime = versionFile.releaseTime - versionEntry.sha256 = filehash - versionEntry.requires = versionFile.requires - versionEntry.conflicts = versionFile.conflicts - versionEntry.volatile = versionFile.volatile + filehash = hash_file(hashlib.sha256, filepath) + versionFile = MetaVersion.parse_file(filepath) + is_recommended = versionFile.version in recommendedVersions + + versionEntry = MetaVersionIndexEntry.from_meta_version(versionFile, is_recommended, filehash) + versionList.versions.append(versionEntry) # sort the versions in descending order by time of release - versionList.versions = sorted(versionList.versions, key=itemgetter('releaseTime'), reverse=True) + versionList.versions = sorted(versionList.versions, key=attrgetter('release_time'), reverse=True) # write the version index for the package outFilePath = PMC_DIR + "/%s/index.json" % (package) - with open(outFilePath, 'w') as outfile: - json.dump(versionList.to_json(), outfile, sort_keys=True, indent=4) + versionList.write(outFilePath) # insert entry into the package index - packageEntry = PolyMCPackageIndexEntry( - { - "uid": package, - "name": sharedData.name, - "sha256": HashFile(hashlib.sha256, outFilePath) - } + packageEntry = MetaPackageIndexEntry( + uid=package, + name=sharedData.name, + sha256=hash_file(hashlib.sha256, outFilePath) ) packages.packages.append(packageEntry) -# write the repository package index -with open(PMC_DIR + "/index.json", 'w') as outfile: - json.dump(packages.to_json(), outfile, sort_keys=True, indent=4) +packages.write(os.path.join(PMC_DIR, "index.json")) diff --git a/meta/model/index.py b/meta/model/index.py new file mode 100644 index 0000000000..f7cdc36e0f --- /dev/null +++ b/meta/model/index.py @@ -0,0 +1,46 @@ +from datetime import datetime +from typing import Optional, List + +from pydantic import Field + +from meta.model import Dependency, MetaBase, Versioned, MetaVersion + + +class MetaVersionIndexEntry(MetaBase): + version: str + type: Optional[str] + release_time: datetime = Field(alias="releaseTime") + requires: Optional[List[Dependency]] + conflicts: Optional[List[Dependency]] + recommended: Optional[bool] + volatile: Optional[bool] + sha256: str + + @classmethod + def from_meta_version(cls, v: MetaVersion, recommended: bool, sha256: str): + return cls( + version=v.version, + type=v.type, + release_time=v.release_time, + requires=v.requires, + conflicts=v.conflicts, + recommended=recommended, + volatile=v.volatile, + sha256=sha256 + ) + + +class MetaVersionIndex(Versioned): + name: str + uid: str + versions: List[MetaVersionIndexEntry] = Field([]) + + +class MetaPackageIndexEntry(MetaBase): + name: str + uid: str + sha256: str + + +class MetaPackageIndex(Versioned): + packages: List[MetaPackageIndexEntry] = Field([]) -- cgit 0.0.5-2-1-g0f52 From 00cbf2073bcae1a9eec60c1440651e5acd74c363 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 15:07:12 +0200 Subject: refactor: remove obsolete model framework --- Dockerfile | 2 +- generateForge.py | 1 - meta/jsonobject/__init__.py | 17 -- meta/jsonobject/api.py | 53 ----- meta/jsonobject/base.py | 394 ------------------------------------- meta/jsonobject/base_properties.py | 320 ------------------------------ meta/jsonobject/containers.py | 252 ------------------------ meta/jsonobject/exceptions.py | 10 - meta/jsonobject/properties.py | 155 --------------- meta/jsonobject/utils.py | 57 ------ meta/metautil.py | 309 ----------------------------- 11 files changed, 1 insertion(+), 1569 deletions(-) delete mode 100644 meta/jsonobject/__init__.py delete mode 100644 meta/jsonobject/api.py delete mode 100644 meta/jsonobject/base.py delete mode 100644 meta/jsonobject/base_properties.py delete mode 100644 meta/jsonobject/containers.py delete mode 100644 meta/jsonobject/exceptions.py delete mode 100644 meta/jsonobject/properties.py delete mode 100644 meta/jsonobject/utils.py delete mode 100644 meta/metautil.py (limited to 'meta') diff --git a/Dockerfile b/Dockerfile index e7a58203ef..4c6848dc93 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM python:3.10.2-bullseye ARG UID=1337 ARG GID=1337 -RUN pip install cachecontrol iso8601 requests lockfile jsonobject six pydantic \ +RUN pip install cachecontrol requests lockfile pydantic \ && apt-get update && apt-get install -y rsync cron # add our cronjob diff --git a/generateForge.py b/generateForge.py index b161b29a3e..6c70d9e531 100755 --- a/generateForge.py +++ b/generateForge.py @@ -1,7 +1,6 @@ import os import re import sys -from datetime import timezone from distutils.version import LooseVersion from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path diff --git a/meta/jsonobject/__init__.py b/meta/jsonobject/__init__.py deleted file mode 100644 index 83f41913c4..0000000000 --- a/meta/jsonobject/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# TODO: maybe move to pydantic in the future? - -from __future__ import absolute_import -from .base import JsonObjectMeta -from .containers import JsonArray -from .properties import * -from .base_properties import * -from .api import JsonObject - -__all__ = [ - 'IntegerProperty', 'FloatProperty', 'DecimalProperty', - 'StringProperty', 'BooleanProperty', - 'DateProperty', 'DateTimeProperty', 'TimeProperty', - 'ObjectProperty', 'ListProperty', 'DictProperty', 'SetProperty', - 'JsonObject', 'JsonArray', 'AbstractDateProperty', 'JsonProperty', - 'DefaultProperty' -] diff --git a/meta/jsonobject/api.py b/meta/jsonobject/api.py deleted file mode 100644 index 8b9c4767c1..0000000000 --- a/meta/jsonobject/api.py +++ /dev/null @@ -1,53 +0,0 @@ -from __future__ import absolute_import -from .base import JsonObjectBase, _LimitedDictInterfaceMixin - -import six -import decimal -import datetime - -from . import properties -import re - -re_date = re.compile(r'^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])$') -re_time = re.compile( - r'^([01]\d|2[0-3])\D?([0-5]\d)\D?([0-5]\d)?\D?(\d{3,6})?$') -re_datetime = re.compile( - r'^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])' - r'(\D?([01]\d|2[0-3])\D?([0-5]\d)\D?([0-5]\d)?\D?(\d{3,6})?' - r'([zZ]|([\+-])([01]\d|2[0-3])\D?([0-5]\d)?)?)?$' -) -re_decimal = re.compile('^(\d+)\.(\d+)$') -if six.PY3: - unicode = str - long = int - - -class JsonObject(JsonObjectBase, _LimitedDictInterfaceMixin): - def __getstate__(self): - return self.to_json() - - def __setstate__(self, dct): - self.__init__(dct) - - class Meta(object): - properties = { - decimal.Decimal: properties.DecimalProperty, - datetime.datetime: properties.DateTimeProperty, - datetime.date: properties.DateProperty, - datetime.time: properties.TimeProperty, - str: properties.StringProperty, - unicode: properties.StringProperty, - bool: properties.BooleanProperty, - int: properties.IntegerProperty, - long: properties.IntegerProperty, - float: properties.FloatProperty, - list: properties.ListProperty, - dict: properties.DictProperty, - set: properties.SetProperty, - } - string_conversions = ( - (re_date, datetime.date), - (re_time, datetime.time), - (re_datetime, datetime.datetime), - (re_decimal, decimal.Decimal), - ) diff --git a/meta/jsonobject/base.py b/meta/jsonobject/base.py deleted file mode 100644 index 90a5f44c6a..0000000000 --- a/meta/jsonobject/base.py +++ /dev/null @@ -1,394 +0,0 @@ -from __future__ import absolute_import -from collections import namedtuple, OrderedDict -import copy -import six -import inspect -from .exceptions import ( - DeleteNotAllowed, - WrappingAttributeError, -) -from .base_properties import JsonProperty, DefaultProperty -from .utils import check_type - -JsonObjectClassSettings = namedtuple('JsonObjectClassSettings', ['type_config']) - -CLASS_SETTINGS_ATTR = '_$_class_settings' - - -def get_settings(cls): - return getattr(cls, CLASS_SETTINGS_ATTR, - JsonObjectClassSettings(type_config=TypeConfig())) - - -def set_settings(cls, settings): - setattr(cls, CLASS_SETTINGS_ATTR, settings) - - -class TypeConfig(object): - """ - This class allows the user to configure dynamic - type handlers and string conversions for their JsonObject. - - properties is a map from python types to JsonProperty subclasses - string_conversions is a list or tuple of (regex, python type)-tuples - - This class is used to store the configuration but is not part of the API. - To configure: - - class Foo(JsonObject): - # property definitions go here - # ... - - class Meta(object): - update_properties = { - datetime.datetime: MySpecialDateTimeProperty - } - # this is already set by default - # but you can override with your own modifications - string_conversions = ((date_re, datetime.date), - (datetime_re, datetime.datetime), - (time_re, datetime.time), - (decimal_re, decimal.Decimal)) - - If you now do - - foo = Foo() - foo.timestamp = datetime.datetime(1988, 7, 7, 11, 8, 0) - - timestamp will be governed by a MySpecialDateTimeProperty - instead of the default. - - """ - - def __init__(self, properties=None, string_conversions=None): - self._properties = properties if properties is not None else {} - - self._string_conversions = ( - OrderedDict(string_conversions) if string_conversions is not None - else OrderedDict() - ) - # cache this - self.string_conversions = self._get_string_conversions() - self.properties = self._properties - - def replace(self, properties=None, string_conversions=None): - return TypeConfig( - properties=(properties if properties is not None - else self._properties), - string_conversions=(string_conversions if string_conversions is not None - else self._string_conversions) - ) - - def updated(self, properties=None, string_conversions=None): - """ - update properties and string_conversions with the paramenters - keeping all non-mentioned items the same as before - returns a new TypeConfig with these changes - (does not modify original) - - """ - _properties = self._properties.copy() - _string_conversions = self.string_conversions[:] - if properties: - _properties.update(properties) - if string_conversions: - _string_conversions.extend(string_conversions) - return TypeConfig( - properties=_properties, - string_conversions=_string_conversions, - ) - - def _get_string_conversions(self): - result = [] - for pattern, conversion in self._string_conversions.items(): - conversion = ( - conversion if conversion not in self._properties - else self._properties[conversion](type_config=self).to_python - ) - result.append((pattern, conversion)) - return result - - -META_ATTRS = ('properties', 'string_conversions', 'update_properties') - - -class JsonObjectMeta(type): - class Meta(object): - pass - - def __new__(mcs, name, bases, dct): - cls = super(JsonObjectMeta, mcs).__new__(mcs, name, bases, dct) - - cls.__configure(**{key: value - for key, value in cls.Meta.__dict__.items() - if key in META_ATTRS}) - cls_settings = get_settings(cls) - - properties = {} - properties_by_name = {} - for key, value in dct.items(): - if isinstance(value, JsonProperty): - properties[key] = value - elif key.startswith('_'): - continue - elif type(value) in cls_settings.type_config.properties: - property_ = cls_settings.type_config.properties[type(value)](default=value) - properties[key] = dct[key] = property_ - setattr(cls, key, property_) - - for key, property_ in properties.items(): - property_.init_property(default_name=key, - type_config=cls_settings.type_config) - assert property_.name is not None, property_ - assert property_.name not in properties_by_name, \ - 'You can only have one property named {0}'.format( - property_.name) - properties_by_name[property_.name] = property_ - - for base in bases: - if getattr(base, '_properties_by_attr', None): - for key, value in base._properties_by_attr.items(): - if key not in properties: - properties[key] = value - properties_by_name[value.name] = value - - cls._properties_by_attr = properties - cls._properties_by_key = properties_by_name - return cls - - def __configure(cls, properties=None, string_conversions=None, - update_properties=None): - super_settings = get_settings(super(cls, cls)) - assert not properties or not update_properties, \ - "{} {}".format(properties, update_properties) - type_config = super_settings.type_config - if update_properties is not None: - type_config = type_config.updated(properties=update_properties) - elif properties is not None: - type_config = type_config.replace(properties=properties) - if string_conversions is not None: - type_config = type_config.replace( - string_conversions=string_conversions) - set_settings(cls, super_settings._replace(type_config=type_config)) - return cls - - -class _JsonObjectPrivateInstanceVariables(object): - - def __init__(self, dynamic_properties=None): - self.dynamic_properties = dynamic_properties or {} - - -@six.add_metaclass(JsonObjectMeta) -class JsonObjectBase(object): - _allow_dynamic_properties = False - _validate_required_lazily = False - - _properties_by_attr = None - _properties_by_key = None - - _string_conversions = () - - def __init__(self, _obj=None, **kwargs): - setattr(self, '_$', _JsonObjectPrivateInstanceVariables()) - - self._obj = check_type(_obj, dict, - 'JsonObject must wrap a dict or None') - self._wrapped = {} - - for key, value in self._obj.items(): - try: - self.set_raw_value(key, value) - except AttributeError: - raise WrappingAttributeError( - "can't set attribute corresponding to {key!r} " - "on a {cls} while wrapping {data!r}".format( - cls=self.__class__, - key=key, - data=_obj, - ) - ) - - for attr, value in kwargs.items(): - try: - setattr(self, attr, value) - except AttributeError: - raise WrappingAttributeError( - "can't set attribute {key!r} " - "on a {cls} while wrapping {data!r}".format( - cls=self.__class__, - key=attr, - data=_obj, - ) - ) - - for key, value in self._properties_by_key.items(): - if key not in self._obj: - try: - d = value.default() - except TypeError: - d = value.default(self) - self[key] = d - - def set_raw_value(self, key, value): - wrapped = self.__wrap(key, value) - if key in self._properties_by_key: - self[key] = wrapped - else: - setattr(self, key, wrapped) - - @classmethod - def properties(cls): - return cls._properties_by_attr.copy() - - @property - def __dynamic_properties(self): - return getattr(self, '_$').dynamic_properties - - @classmethod - def wrap(cls, obj): - self = cls(obj) - return self - - def validate(self, required=True): - for key, value in self._wrapped.items(): - self.__get_property(key).validate(value, required=required) - - def to_json(self): - self.validate() - return copy.deepcopy(self._obj) - - def __get_property(self, key): - try: - return self._properties_by_key[key] - except KeyError: - return DefaultProperty(type_config=get_settings(self).type_config) - - def __wrap(self, key, value): - property_ = self.__get_property(key) - - if value is None: - return None - - return property_.wrap(value) - - def __unwrap(self, key, value): - property_ = self.__get_property(key) - try: - property_.validate( - value, - required=not self._validate_required_lazily, - recursive=False, - ) - except TypeError: - property_.validate( - value, - required=not self._validate_required_lazily, - ) - if value is None: - return None, None - - return property_.unwrap(value) - - def __setitem__(self, key, value): - wrapped, unwrapped = self.__unwrap(key, value) - self._wrapped[key] = wrapped - if self.__get_property(key).exclude(unwrapped): - self._obj.pop(key, None) - else: - self._obj[key] = unwrapped - if key not in self._properties_by_key: - assert key not in self._properties_by_attr - self.__dynamic_properties[key] = wrapped - super(JsonObjectBase, self).__setattr__(key, wrapped) - - def __is_dynamic_property(self, name): - return ( - name not in self._properties_by_attr and - not name.startswith('_') and - not inspect.isdatadescriptor(getattr(self.__class__, name, None)) - ) - - def __setattr__(self, name, value): - if self.__is_dynamic_property(name): - if self._allow_dynamic_properties: - self[name] = value - else: - raise AttributeError( - "{0!r} is not defined in schema " - "(not a valid property)".format(name) - ) - else: - super(JsonObjectBase, self).__setattr__(name, value) - - def __delitem__(self, key): - if key in self._properties_by_key: - raise DeleteNotAllowed(key) - else: - if not self.__is_dynamic_property(key): - raise KeyError(key) - del self._obj[key] - del self._wrapped[key] - del self.__dynamic_properties[key] - super(JsonObjectBase, self).__delattr__(key) - - def __delattr__(self, name): - if name in self._properties_by_attr: - raise DeleteNotAllowed(name) - elif self.__is_dynamic_property(name): - del self[name] - else: - super(JsonObjectBase, self).__delattr__(name) - - def __repr__(self): - name = self.__class__.__name__ - predefined_properties = self._properties_by_attr.keys() - predefined_property_keys = set(self._properties_by_attr[p].name - for p in predefined_properties) - dynamic_properties = (set(self._wrapped.keys()) - - predefined_property_keys) - properties = sorted(predefined_properties) + sorted(dynamic_properties) - return u'{name}({keyword_args})'.format( - name=name, - keyword_args=', '.join('{key}={value!r}'.format( - key=key, - value=getattr(self, key) - ) for key in properties), - ) - - -class _LimitedDictInterfaceMixin(object): - """ - mindlessly farms selected dict methods out to an internal dict - - really only a separate class from JsonObject - to keep this mindlessness separate from the methods - that need to be more carefully understood - - """ - _wrapped = None - - def keys(self): - return self._wrapped.keys() - - def items(self): - return self._wrapped.items() - - def iteritems(self): - return self._wrapped.iteritems() - - def __contains__(self, item): - return item in self._wrapped - - def __getitem__(self, item): - return self._wrapped[item] - - def __iter__(self): - return iter(self._wrapped) - - def __len__(self): - return len(self._wrapped) - - -def get_dynamic_properties(obj): - return getattr(obj, '_$').dynamic_properties.copy() diff --git a/meta/jsonobject/base_properties.py b/meta/jsonobject/base_properties.py deleted file mode 100644 index b43b1d44e2..0000000000 --- a/meta/jsonobject/base_properties.py +++ /dev/null @@ -1,320 +0,0 @@ -from __future__ import absolute_import -import six -import inspect -from .exceptions import BadValueError - -function_name = None -if six.PY3: - def function_name(f): - return f.__name__ -else: - def function_name(f): - return f.func_name - - -class JsonProperty(object): - default = None - type_config = None - - def __init__(self, default=Ellipsis, name=None, choices=None, - required=False, exclude_if_none=False, validators=None, - verbose_name=None, type_config=None): - validators = validators or () - self.name = name - if default is Ellipsis: - default = self.default - if callable(default): - self.default = default - else: - self.default = lambda: default - self.choices = choices - self.choice_keys = [] - if choices: - for choice in choices: - if isinstance(choice, tuple): - choice, _ = choice - self.choice_keys.append(choice) - self.required = required - self.exclude_if_none = exclude_if_none - self._validators = validators - self.verbose_name = verbose_name - if type_config: - self.type_config = type_config - - def init_property(self, default_name, type_config): - self.name = self.name or default_name - self.type_config = self.type_config or type_config - - def wrap(self, obj): - raise NotImplementedError() - - def unwrap(self, obj): - """ - must return tuple of (wrapped, unwrapped) - - If obj is already a fully wrapped object, - it must be returned as the first element. - - For an example where the first element is relevant see ListProperty - - """ - raise NotImplementedError() - - def to_json(self, value): - _, unwrapped = self.unwrap(value) - return unwrapped - - def to_python(self, value): - return self.wrap(value) - - def __get__(self, instance, owner): - if instance: - assert self.name in instance - return instance[self.name] - else: - return self - - def __set__(self, instance, value): - instance[self.name] = value - - def __call__(self, method): - """ - use a property as a decorator to set its default value - - class Document(JsonObject): - @StringProperty() - def doc_type(self): - return self.__class__.__name__ - """ - assert self.default() is None - self.default = method - self.name = self.name or function_name(method) - return self - - def exclude(self, value): - return self.exclude_if_none and value == None - - def empty(self, value): - return value is None - - def validate(self, value, required=True, recursive=True): - if (self.choice_keys and value not in self.choice_keys - and value is not None): - raise BadValueError( - '{0!r} not in choices: {1!r}'.format(value, self.choice_keys) - ) - - if not self.empty(value): - self._custom_validate(value) - elif required and self.required: - raise BadValueError( - 'Property {0} is required.'.format(self.name) - ) - if recursive and hasattr(value, 'validate'): - value.validate(required=required) - - def _custom_validate(self, value): - if self._validators: - if hasattr(self._validators, '__iter__'): - for validator in self._validators: - validator(value) - else: - self._validators(value) - - -class JsonContainerProperty(JsonProperty): - _type = default = None - container_class = None - - def __init__(self, item_type=None, **kwargs): - self._item_type_deferred = item_type - super(JsonContainerProperty, self).__init__(**kwargs) - - def init_property(self, **kwargs): - super(JsonContainerProperty, self).init_property(**kwargs) - if not inspect.isfunction(self._item_type_deferred): - # trigger validation - self.item_type - - def set_item_type(self, item_type): - from meta.jsonobject.base import JsonObjectMeta - if hasattr(item_type, '_type'): - item_type = item_type._type - if isinstance(item_type, tuple): - # this is for the case where item_type = (int, long) - item_type = item_type[0] - allowed_types = set(self.type_config.properties.keys()) - if isinstance(item_type, JsonObjectMeta) \ - or not item_type or item_type in allowed_types: - self._item_type = item_type - else: - raise ValueError("item_type {0!r} not in {1!r}".format( - item_type, - allowed_types, - )) - - @property - def item_type(self): - if hasattr(self, '_item_type_deferred'): - if inspect.isfunction(self._item_type_deferred): - self.set_item_type(self._item_type_deferred()) - else: - self.set_item_type(self._item_type_deferred) - del self._item_type_deferred - return self._item_type - - def empty(self, value): - return not value - - def wrap(self, obj): - wrapper = self.type_to_property(self.item_type) if self.item_type else None - return self.container_class(obj, wrapper=wrapper, - type_config=self.type_config) - - def type_to_property(self, item_type): - map_types_properties = self.type_config.properties - from .properties import ObjectProperty - from .base import JsonObjectBase - if issubclass(item_type, JsonObjectBase): - return ObjectProperty(item_type, type_config=self.type_config) - elif item_type in map_types_properties: - return map_types_properties[item_type](type_config=self.type_config) - else: - for key, value in map_types_properties.items(): - if issubclass(item_type, key): - return value(type_config=self.type_config) - raise TypeError('Type {0} not recognized'.format(item_type)) - - def unwrap(self, obj): - if not isinstance(obj, self._type): - raise BadValueError( - '{0!r} is not an instance of {1!r}'.format( - obj, self._type.__name__) - ) - if isinstance(obj, self.container_class): - return obj, obj._obj - else: - wrapped = self.wrap(self._type()) - self._update(wrapped, obj) - return self.unwrap(wrapped) - - def _update(self, container, extension): - raise NotImplementedError() - - -class DefaultProperty(JsonProperty): - - def wrap(self, obj): - assert self.type_config.string_conversions is not None - value = self.value_to_python(obj) - property_ = self.value_to_property(value) - - if property_: - return property_.wrap(obj) - - def unwrap(self, obj): - property_ = self.value_to_property(obj) - if property_: - return property_.unwrap(obj) - else: - return obj, None - - def value_to_property(self, value): - map_types_properties = self.type_config.properties - if value is None: - return None - elif type(value) in map_types_properties: - return map_types_properties[type(value)]( - type_config=self.type_config) - else: - for value_type, prop_class in map_types_properties.items(): - if isinstance(value, value_type): - return prop_class(type_config=self.type_config) - else: - raise BadValueError( - 'value {0!r} not in allowed types: {1!r}'.format( - value, map_types_properties.keys()) - ) - - def value_to_python(self, value): - """ - convert encoded string values to the proper python type - - ex: - >>> DefaultProperty().value_to_python('2013-10-09T10:05:51Z') - datetime.datetime(2013, 10, 9, 10, 5, 51) - - other values will be passed through unmodified - Note: containers' items are NOT recursively converted - - """ - if isinstance(value, six.string_types): - convert = None - for pattern, _convert in self.type_config.string_conversions: - if pattern.match(value): - convert = _convert - break - - if convert is not None: - try: - # sometimes regex fail so return value - value = convert(value) - except Exception: - pass - return value - - -class AssertTypeProperty(JsonProperty): - _type = None - - def assert_type(self, obj): - if not isinstance(obj, self._type): - raise BadValueError( - '{0!r} not of type {1!r}'.format(obj, self._type) - ) - - def selective_coerce(self, obj): - return obj - - def wrap(self, obj): - obj = self.selective_coerce(obj) - self.assert_type(obj) - return obj - - def unwrap(self, obj): - obj = self.selective_coerce(obj) - self.assert_type(obj) - return obj, obj - - -class AbstractDateProperty(JsonProperty): - _type = None - - def __init__(self, exact=False, *args, **kwargs): - super(AbstractDateProperty, self).__init__(*args, **kwargs) - self.exact = exact - - def wrap(self, obj): - try: - if not isinstance(obj, six.string_types): - raise ValueError() - return self._wrap(obj) - except ValueError: - raise BadValueError('{0!r} is not a {1}-formatted string'.format( - obj, - self._type.__name__, - )) - - def unwrap(self, obj): - if not isinstance(obj, self._type): - raise BadValueError('{0!r} is not a {1} object'.format( - obj, - self._type.__name__, - )) - return self._unwrap(obj) - - def _wrap(self, obj): - raise NotImplementedError() - - def _unwrap(self, obj): - raise NotImplementedError() diff --git a/meta/jsonobject/containers.py b/meta/jsonobject/containers.py deleted file mode 100644 index 1150ab9d23..0000000000 --- a/meta/jsonobject/containers.py +++ /dev/null @@ -1,252 +0,0 @@ -from __future__ import absolute_import -from .base_properties import DefaultProperty -from .utils import check_type, SimpleDict -import copy - - -class JsonArray(list): - def __init__(self, _obj=None, wrapper=None, type_config=None): - super(JsonArray, self).__init__() - self._obj = check_type(_obj, list, - 'JsonArray must wrap a list or None') - - assert type_config is not None - self._type_config = type_config - self._wrapper = ( - wrapper or - DefaultProperty(type_config=self._type_config) - ) - for item in self._obj: - super(JsonArray, self).append(self._wrapper.wrap(item)) - - def validate(self, required=True): - for obj in self: - self._wrapper.validate(obj, required=required) - - def to_json(self): - self.validate() - return copy.deepcopy(self._obj) - - def append(self, wrapped): - wrapped, unwrapped = self._wrapper.unwrap(wrapped) - self._obj.append(unwrapped) - super(JsonArray, self).append(wrapped) - - def __delitem__(self, i): - super(JsonArray, self).__delitem__(i) - del self._obj[i] - - def __setitem__(self, i, wrapped): - wrapped, unwrapped = self._wrapper.unwrap(wrapped) - self._obj[i] = unwrapped - super(JsonArray, self).__setitem__(i, wrapped) - - def extend(self, wrapped_list): - if wrapped_list: - wrapped_list, unwrapped_list = zip( - *map(self._wrapper.unwrap, wrapped_list) - ) - else: - unwrapped_list = [] - self._obj.extend(unwrapped_list) - super(JsonArray, self).extend(wrapped_list) - - def insert(self, index, wrapped): - wrapped, unwrapped = self._wrapper.unwrap(wrapped) - self._obj.insert(index, unwrapped) - super(JsonArray, self).insert(index, wrapped) - - def remove(self, value): - i = self.index(value) - super(JsonArray, self).remove(value) - self._obj.pop(i) - - def pop(self, index=-1): - self._obj.pop(index) - return super(JsonArray, self).pop(index) - - def sort(self, cmp=None, key=None, reverse=False): - zipped = zip(self, self._obj) - if key: - new_key = lambda pair: key(pair[0]) - zipped.sort(key=new_key, reverse=reverse) - elif cmp: - new_cmp = lambda pair1, pair2: cmp(pair1[0], pair2[0]) - zipped.sort(cmp=new_cmp, reverse=reverse) - else: - zipped.sort(reverse=reverse) - - wrapped_list, unwrapped_list = zip(*zipped) - while self: - self.pop() - super(JsonArray, self).extend(wrapped_list) - self._obj.extend(unwrapped_list) - - def reverse(self): - self._obj.reverse() - super(JsonArray, self).reverse() - - def __fix_slice(self, i, j): - length = len(self) - if j < 0: - j += length - if i < 0: - i += length - if i > length: - i = length - if j > length: - j = length - return i, j - - def __setslice__(self, i, j, sequence): - i, j = self.__fix_slice(i, j) - for _ in range(j - i): - self.pop(i) - for k, wrapped in enumerate(sequence): - self.insert(i + k, wrapped) - - def __delslice__(self, i, j): - i, j = self.__fix_slice(i, j) - for _ in range(j - i): - self.pop(i) - - -class JsonDict(SimpleDict): - - def __init__(self, _obj=None, wrapper=None, type_config=None): - super(JsonDict, self).__init__() - self._obj = check_type(_obj, dict, 'JsonDict must wrap a dict or None') - assert type_config is not None - self._type_config = type_config - self._wrapper = ( - wrapper or - DefaultProperty(type_config=self._type_config) - ) - for key, value in self._obj.items(): - self[key] = self.__wrap(key, value) - - def validate(self, required=True): - for obj in self.values(): - self._wrapper.validate(obj, required=required) - - def __wrap(self, key, unwrapped): - return self._wrapper.wrap(unwrapped) - - def __unwrap(self, key, wrapped): - return self._wrapper.unwrap(wrapped) - - def __setitem__(self, key, value): - if isinstance(key, int): - key = str(key) - - wrapped, unwrapped = self.__unwrap(key, value) - self._obj[key] = unwrapped - super(JsonDict, self).__setitem__(key, wrapped) - - def __delitem__(self, key): - del self._obj[key] - super(JsonDict, self).__delitem__(key) - - def __getitem__(self, key): - if isinstance(key, int): - key = str(key) - return super(JsonDict, self).__getitem__(key) - - -class JsonSet(set): - def __init__(self, _obj=None, wrapper=None, type_config=None): - super(JsonSet, self).__init__() - if isinstance(_obj, set): - _obj = list(_obj) - self._obj = check_type(_obj, list, 'JsonSet must wrap a list or None') - assert type_config is not None - self._type_config = type_config - self._wrapper = ( - wrapper or - DefaultProperty(type_config=self._type_config) - ) - for item in self._obj: - super(JsonSet, self).add(self._wrapper.wrap(item)) - - def validate(self, required=True): - for obj in self: - self._wrapper.validate(obj, required=required) - - def add(self, wrapped): - wrapped, unwrapped = self._wrapper.unwrap(wrapped) - if wrapped not in self: - self._obj.append(unwrapped) - super(JsonSet, self).add(wrapped) - - def remove(self, wrapped): - wrapped, unwrapped = self._wrapper.unwrap(wrapped) - if wrapped in self: - self._obj.remove(unwrapped) - super(JsonSet, self).remove(wrapped) - else: - raise KeyError(wrapped) - - def discard(self, wrapped): - try: - self.remove(wrapped) - except KeyError: - pass - - def pop(self): - # get first item - for wrapped in self: - break - else: - raise KeyError() - wrapped_, unwrapped = self._wrapper.unwrap(wrapped) - assert wrapped is wrapped_ - self.remove(unwrapped) - return wrapped - - def clear(self): - while self: - self.pop() - - def __ior__(self, other): - for wrapped in other: - self.add(wrapped) - return self - - def update(self, *args): - for wrapped_list in args: - self |= set(wrapped_list) - - union_update = update - - def __iand__(self, other): - for wrapped in list(self): - if wrapped not in other: - self.remove(wrapped) - return self - - def intersection_update(self, *args): - for wrapped_list in args: - self &= set(wrapped_list) - - def __isub__(self, other): - for wrapped in list(self): - if wrapped in other: - self.remove(wrapped) - return self - - def difference_update(self, *args): - for wrapped_list in args: - self -= set(wrapped_list) - - def __ixor__(self, other): - removed = set() - for wrapped in list(self): - if wrapped in other: - self.remove(wrapped) - removed.add(wrapped) - self.update(other - removed) - return self - - def symmetric_difference_update(self, *args): - for wrapped_list in args: - self ^= set(wrapped_list) diff --git a/meta/jsonobject/exceptions.py b/meta/jsonobject/exceptions.py deleted file mode 100644 index a42022e120..0000000000 --- a/meta/jsonobject/exceptions.py +++ /dev/null @@ -1,10 +0,0 @@ -class DeleteNotAllowed(Exception): - pass - - -class BadValueError(Exception): - """raised when a value can't be validated or is required""" - - -class WrappingAttributeError(AttributeError): - pass diff --git a/meta/jsonobject/properties.py b/meta/jsonobject/properties.py deleted file mode 100644 index 05bba86da9..0000000000 --- a/meta/jsonobject/properties.py +++ /dev/null @@ -1,155 +0,0 @@ -# DateTimeProperty, DateProperty, and TimeProperty -# include code copied from couchdbkit -from __future__ import absolute_import -import sys -import datetime -import time -import decimal -from .base_properties import ( - AbstractDateProperty, - AssertTypeProperty, - JsonContainerProperty, - JsonProperty, - DefaultProperty, -) -from .containers import JsonArray, JsonDict, JsonSet - -if sys.version > '3': - unicode = str - long = int - - -class StringProperty(AssertTypeProperty): - _type = (unicode, str) - - def selective_coerce(self, obj): - if isinstance(obj, str): - obj = unicode(obj) - return obj - - -class BooleanProperty(AssertTypeProperty): - _type = bool - - -class IntegerProperty(AssertTypeProperty): - _type = (int, long) - - -class FloatProperty(AssertTypeProperty): - _type = float - - def selective_coerce(self, obj): - if isinstance(obj, (int, long)): - obj = float(obj) - return obj - - -class DecimalProperty(JsonProperty): - - def wrap(self, obj): - return decimal.Decimal(obj) - - def unwrap(self, obj): - if isinstance(obj, (int, long)): - obj = decimal.Decimal(obj) - elif isinstance(obj, float): - # python 2.6 doesn't allow a float to Decimal - obj = decimal.Decimal(unicode(obj)) - assert isinstance(obj, decimal.Decimal) - return obj, unicode(obj) - - -class DateProperty(AbstractDateProperty): - _type = datetime.date - - def _wrap(self, value): - fmt = '%Y-%m-%d' - try: - return datetime.date(*time.strptime(value, fmt)[:3]) - except ValueError as e: - raise ValueError('Invalid ISO date {0!r} [{1}]'.format(value, e)) - - def _unwrap(self, value): - return value, value.isoformat() - - -class DateTimeProperty(AbstractDateProperty): - _type = datetime.datetime - - def _wrap(self, value): - if not self.exact: - value = value.split('.', 1)[0] # strip out microseconds - value = value[0:19] # remove timezone - fmt = '%Y-%m-%dT%H:%M:%S' - else: - fmt = '%Y-%m-%dT%H:%M:%S.%fZ' - try: - return datetime.datetime.strptime(value, fmt) - except ValueError as e: - raise ValueError( - 'Invalid ISO date/time {0!r} [{1}]'.format(value, e)) - - def _unwrap(self, value): - if not self.exact: - value = value.replace(microsecond=0) - padding = '' - else: - padding = '' if value.microsecond else '.000000' - return value, value.isoformat() + padding + 'Z' - - -class TimeProperty(AbstractDateProperty): - _type = datetime.time - - def _wrap(self, value): - if not self.exact: - value = value.split('.', 1)[0] # strip out microseconds - fmt = '%H:%M:%S' - else: - fmt = '%H:%M:%S.%f' - try: - return datetime.time(*time.strptime(value, fmt)[3:6]) - except ValueError as e: - raise ValueError('Invalid ISO time {0!r} [{1}]'.format(value, e)) - - def _unwrap(self, value): - if not self.exact: - value = value.replace(microsecond=0) - return value, value.isoformat() - - -class ObjectProperty(JsonContainerProperty): - default = lambda self: self.item_type() - - def wrap(self, obj, string_conversions=None): - return self.item_type.wrap(obj) - - def unwrap(self, obj): - assert isinstance(obj, self.item_type), \ - '{0} is not an instance of {1}'.format(obj, self.item_type) - return obj, obj._obj - - -class ListProperty(JsonContainerProperty): - _type = default = list - container_class = JsonArray - - def _update(self, container, extension): - container.extend(extension) - - -class DictProperty(JsonContainerProperty): - _type = default = dict - container_class = JsonDict - - def _update(self, container, extension): - container.update(extension) - - -class SetProperty(JsonContainerProperty): - _type = default = set - container_class = JsonSet - - def _update(self, container, extension): - container.update(extension) diff --git a/meta/jsonobject/utils.py b/meta/jsonobject/utils.py deleted file mode 100644 index 9ee8569801..0000000000 --- a/meta/jsonobject/utils.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import absolute_import -from .exceptions import BadValueError - - -def check_type(obj, item_type, message): - if obj is None: - return item_type() - elif not isinstance(obj, item_type): - raise BadValueError('{}. Found object of type: {}'.format(message, type(obj))) - else: - return obj - - -class SimpleDict(dict): - """ - Re-implements destructive methods of dict - to use only setitem and getitem and delitem - """ - - def update(self, E=None, **F): - for dct in (E, F): - if dct: - for key, value in dct.items(): - self[key] = value - - def clear(self): - for key in list(self.keys()): - del self[key] - - def pop(self, key, *args): - if len(args) > 1: - raise TypeError('pop expected at most 2 arguments, got 3') - try: - val = self[key] - del self[key] - return val - except KeyError: - try: - return args[0] - except IndexError: - raise KeyError(key) - - def popitem(self): - try: - arbitrary_key = list(self.keys())[0] - except IndexError: - raise KeyError('popitem(): dictionary is empty') - val = self[arbitrary_key] - del self[arbitrary_key] - return (arbitrary_key, val) - - def setdefault(self, key, default=None): - try: - return self[key] - except KeyError: - self[key] = default - return default diff --git a/meta/metautil.py b/meta/metautil.py deleted file mode 100644 index ee8994acb3..0000000000 --- a/meta/metautil.py +++ /dev/null @@ -1,309 +0,0 @@ -import datetime -import json -import os - -import iso8601 -from .jsonobject import * -from .common import polymc_path - -PMC_DIR = polymc_path() - - -class ISOTimestampProperty(AbstractDateProperty): - _type = datetime.datetime - - def _wrap(self, value): - try: - return iso8601.parse_date(value) - except ValueError as e: - raise ValueError( - 'Invalid ISO date/time {0!r} [{1}]'.format(value, e)) - - def _unwrap(self, value): - return value, value.isoformat() - - -class GradleSpecifier: - ''' - A gradle specifier - a maven coordinate. Like one of these: - "org.lwjgl.lwjgl:lwjgl:2.9.0" - "net.java.jinput:jinput:2.0.5" - "net.minecraft:launchwrapper:1.5" - ''' - - def __init__(self, name): - atSplit = name.split('@') - - components = atSplit[0].split(':') - self.group = components[0] - self.artifact = components[1] - self.version = components[2] - - self.extension = 'jar' - if len(atSplit) == 2: - self.extension = atSplit[1] - - if len(components) == 4: - self.classifier = components[3] - else: - self.classifier = None - - def toString(self): - extensionStr = '' - if self.extension != 'jar': - extensionStr = "@%s" % self.extension - if self.classifier: - return "%s:%s:%s:%s%s" % (self.group, self.artifact, self.version, self.classifier, extensionStr) - else: - return "%s:%s:%s%s" % (self.group, self.artifact, self.version, extensionStr) - - def getFilename(self): - if self.classifier: - return "%s-%s-%s.%s" % (self.artifact, self.version, self.classifier, self.extension) - else: - return "%s-%s.%s" % (self.artifact, self.version, self.extension) - - def getBase(self): - return "%s/%s/%s/" % (self.group.replace('.', '/'), self.artifact, self.version) - - def getPath(self): - return self.getBase() + self.getFilename() - - def __repr__(self): - return "GradleSpecifier('" + self.toString() + "')" - - def isLwjgl(self): - return self.group in ("org.lwjgl", "org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils") - - def isLog4j(self): - return self.group == "org.apache.logging.log4j" - - def __lt__(self, other): - return self.toString() < other.toString() - - def __eq__(self, other): - return self.group == other.group and self.artifact == other.artifact and self.version == other.version and self.classifier == other.classifier - - def __ne__(self, other): - return not self.__eq__(other) - - def __hash__(self): - return self.toString().__hash__() - - -class GradleSpecifierProperty(JsonProperty): - def wrap(self, value): - return GradleSpecifier(value) - - def unwrap(self, value): - return value, value.toString() - - -class MojangArtifactBase(JsonObject): - sha1 = StringProperty(exclude_if_none=True, default=None) - size = IntegerProperty(exclude_if_none=True, default=None) - url = StringProperty() - - -class MojangArtifact(MojangArtifactBase): - path = StringProperty(exclude_if_none=True, default=None) - - -class MojangAssets(MojangArtifactBase): - id = StringProperty() - totalSize = IntegerProperty() - - -class MojangLibraryDownloads(JsonObject): - artifact = ObjectProperty(MojangArtifact, exclude_if_none=True, default=None) - classifiers = DictProperty(MojangArtifact, exclude_if_none=True, default=None) - - -class MojangLibraryExtractRules(JsonObject): - exclude = ListProperty(StringProperty) - - -''' - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx" - } - } - ] -''' - - -class OSRule(JsonObject): - name = StringProperty(choices=["osx", "linux", "windows"], required=True) - version = StringProperty(exclude_if_none=True, default=None) - - -class MojangRule(JsonObject): - action = StringProperty(choices=["allow", "disallow"], required=True) - os = ObjectProperty(OSRule, exclude_if_none=True, default=None) - - -class MojangLibrary(JsonObject): - extract = ObjectProperty(MojangLibraryExtractRules, exclude_if_none=True, default=None) - name = GradleSpecifierProperty(required=True) - downloads = ObjectProperty(MojangLibraryDownloads, exclude_if_none=True, default=None) - natives = DictProperty(StringProperty, exclude_if_none=True, default=None) - rules = ListProperty(MojangRule, exclude_if_none=True, default=None) - - -class MojangLoggingArtifact(MojangArtifactBase): - id = StringProperty() - - -class MojangLogging(JsonObject): - file = ObjectProperty(MojangLoggingArtifact, required=True) - argument = StringProperty(required=True) - type = StringProperty(required=True, choices=["log4j2-xml"]) - - -class MojangArguments(JsonObject): - game = ListProperty(exclude_if_none=True, default=None) - jvm = ListProperty(exclude_if_none=True, default=None) - - -class JavaVersion(JsonObject): - component = StringProperty(default="jre-legacy") - majorVersion = IntegerProperty(default=8) - - -class UnknownVersionException(Exception): - """Exception raised for unknown Mojang version file format versions. - - Attributes: - message -- explanation of the error - """ - - def __init__(self, message): - self.message = message - - -def validateSupportedMojangVersion(version): - supportedVersion = 21 - if version > supportedVersion: - raise UnknownVersionException( - "Unsupported Mojang format version: %d. Max supported is: %d" % (version, supportedVersion)) - - -class MojangVersionFile(JsonObject): - arguments = ObjectProperty(MojangArguments, exclude_if_none=True, default=None) - assetIndex = ObjectProperty(MojangAssets, exclude_if_none=True, default=None) - assets = StringProperty(exclude_if_none=True, default=None) - downloads = DictProperty(MojangArtifactBase, exclude_if_none=True, default=None) - id = StringProperty(exclude_if_none=True, default=None) - libraries = ListProperty(MojangLibrary, exclude_if_none=True, default=None) - mainClass = StringProperty(exclude_if_none=True, default=None) - processArguments = StringProperty(exclude_if_none=True, default=None) - minecraftArguments = StringProperty(exclude_if_none=True, default=None) - minimumLauncherVersion = IntegerProperty(exclude_if_none=True, default=None, - validators=validateSupportedMojangVersion) - releaseTime = ISOTimestampProperty(exclude_if_none=True, default=None) - time = ISOTimestampProperty(exclude_if_none=True, default=None) - type = StringProperty(exclude_if_none=True, default=None) - inheritsFrom = StringProperty(exclude_if_none=True, default=None) - logging = DictProperty(MojangLogging, exclude_if_none=True, default=None) - complianceLevel = IntegerProperty(exclude_if_none=True, default=None) - javaVersion = ObjectProperty(JavaVersion, exclude_if_none=True, default=None) - - -CurrentPolyMCFormatVersion = 1 - - -def validateSupportedPolyMCVersion(version): - if version > CurrentPolyMCFormatVersion: - raise UnknownVersionException( - "Unsupported PolyMC format version: %d. Max supported is: %d" % (version, CurrentPolyMCFormatVersion)) - - -class PolyMCLibrary(MojangLibrary): - url = StringProperty(exclude_if_none=True, default=None) - mmcHint = StringProperty(name="MMC-hint", exclude_if_none=True, default=None) # this is supposed to be MMC-hint! - - -class VersionedJsonObject(JsonObject): - formatVersion = IntegerProperty(default=CurrentPolyMCFormatVersion, validators=validateSupportedPolyMCVersion) - - -class DependencyEntry(JsonObject): - uid = StringProperty(required=True) - equals = StringProperty(exclude_if_none=True, default=None) - suggests = StringProperty(exclude_if_none=True, default=None) - - -class PolyMCVersionFile(VersionedJsonObject): - name = StringProperty(required=True) - version = StringProperty(required=True) - uid = StringProperty(required=True) - requires = ListProperty(DependencyEntry, exclude_if_none=True, default=None) - conflicts = ListProperty(DependencyEntry, exclude_if_none=True, default=None) - volatile = BooleanProperty(exclude_if_none=True, default=None) - assetIndex = ObjectProperty(MojangAssets, exclude_if_none=True, default=None) - libraries = ListProperty(PolyMCLibrary, exclude_if_none=True, default=None) - mavenFiles = ListProperty(PolyMCLibrary, exclude_if_none=True, default=None) - mainJar = ObjectProperty(PolyMCLibrary, exclude_if_none=True, default=None) - jarMods = ListProperty(PolyMCLibrary, exclude_if_none=True, default=None) - mainClass = StringProperty(exclude_if_none=True, default=None) - appletClass = StringProperty(exclude_if_none=True, default=None) - minecraftArguments = StringProperty(exclude_if_none=True, default=None) - releaseTime = ISOTimestampProperty(exclude_if_none=True, default=None) - type = StringProperty(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 PolyMCSharedPackageData(VersionedJsonObject): - name = StringProperty(required=True) - uid = StringProperty(required=True) - recommended = ListProperty(StringProperty, exclude_if_none=True, default=None) - authors = ListProperty(StringProperty, exclude_if_none=True, default=None) - description = StringProperty(exclude_if_none=True, default=None) - projectUrl = StringProperty(exclude_if_none=True, default=None) - - def write(self): - try: - with open(PMC_DIR + "/%s/package.json" % self.uid, 'w') as file: - json.dump(self.to_json(), file, sort_keys=True, indent=4) - except EnvironmentError as e: - print("Error while trying to save shared packaged data for %s:" % self.uid, e) - - -def readSharedPackageData(uid): - with open(PMC_DIR + "/%s/package.json" % uid, 'r') as file: - return PolyMCSharedPackageData(json.load(file)) - - -class PolyMCVersionIndexEntry(JsonObject): - version = StringProperty() - type = StringProperty(exclude_if_none=True, default=None) - releaseTime = ISOTimestampProperty() - requires = ListProperty(DependencyEntry, exclude_if_none=True, default=None) - conflicts = ListProperty(DependencyEntry, exclude_if_none=True, default=None) - recommended = BooleanProperty(exclude_if_none=True, default=None) - volatile = BooleanProperty(exclude_if_none=True, default=None) - sha256 = StringProperty() - - -class PolyMCVersionIndex(VersionedJsonObject): - name = StringProperty() - uid = StringProperty() - versions = ListProperty(PolyMCVersionIndexEntry) - - -class PolyMCPackageIndexEntry(JsonObject): - name = StringProperty() - uid = StringProperty() - sha256 = StringProperty() - - -class PolyMCPackageIndex(VersionedJsonObject): - packages = ListProperty(PolyMCPackageIndexEntry) -- cgit 0.0.5-2-1-g0f52 From 1bd80e57aaf2fb063b77a3cb7dce892b4b086bf1 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 15:10:28 +0200 Subject: refactor: move GradleSpecifier into model --- generateFabric.py | 3 +- generateForge.py | 1 + meta/model/__init__.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++++- meta/model/types.py | 92 -------------------------------------------------- updateFabric.py | 5 +-- 5 files changed, 96 insertions(+), 97 deletions(-) delete mode 100644 meta/model/types.py (limited to 'meta') diff --git a/generateFabric.py b/generateFabric.py index cfdcdf4e61..fb1c133bf1 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -3,9 +3,8 @@ import os from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT -from meta.model import MetaVersion, Dependency, Library, MetaPackage +from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses -from meta.model.types import GradleSpecifier PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() diff --git a/generateForge.py b/generateForge.py index 6c70d9e531..6327c112da 100755 --- a/generateForge.py +++ b/generateForge.py @@ -389,5 +389,6 @@ def main(): package.recommended = recommendedVersions package.write(os.path.join(PMC_DIR, FORGE_COMPONENT, "package.json")) + if __name__ == '__main__': main() diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 3cc6a3b96e..4371814a11 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -4,12 +4,102 @@ from typing import Optional, List, Dict, Any, Iterator import pydantic from pydantic import Field, validator -from .types import GradleSpecifier from ..common import serialize_datetime META_FORMAT_VERSION = 1 +class GradleSpecifier: + """ + A gradle specifier - a maven coordinate. Like one of these: + "org.lwjgl.lwjgl:lwjgl:2.9.0" + "net.java.jinput:jinput:2.0.5" + "net.minecraft:launchwrapper:1.5" + """ + + def __init__(self, group: str, artifact: str, version: str, classifier: Optional[str] = None, + extension: Optional[str] = None): + if extension is None: + extension = "jar" + self.group = group + self.artifact = artifact + self.version = version + self.classifier = classifier + self.extension = extension + + def __str__(self): + ext = '' + if self.extension != 'jar': + ext = "@%s" % self.extension + if self.classifier: + return "%s:%s:%s:%s%s" % (self.group, self.artifact, self.version, self.classifier, ext) + else: + return "%s:%s:%s%s" % (self.group, self.artifact, self.version, ext) + + def filename(self): + if self.classifier: + return "%s-%s-%s.%s" % (self.artifact, self.version, self.classifier, self.extension) + else: + return "%s-%s.%s" % (self.artifact, self.version, self.extension) + + def base(self): + return "%s/%s/%s/" % (self.group.replace('.', '/'), self.artifact, self.version) + + def path(self): + return self.base() + self.filename() + + def __repr__(self): + return f"GradleSpecifier('{self}')" + + def is_lwjgl(self): + return self.group in ("org.lwjgl", "org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils") + + def is_log4j(self): + return self.group == "org.apache.logging.log4j" + + def __eq__(self, other): + return str(self) == str(other) + + def __lt__(self, other): + return str(self) < str(other) + + def __gt__(self, other): + return str(self) > str(other) + + def __hash__(self): + return hash(str(self)) + + @classmethod + def __get_validators__(cls): + yield cls.validate + + @classmethod + def from_string(cls, v: str): + ext_split = v.split('@') + + components = ext_split[0].split(':') + group = components[0] + artifact = components[1] + version = components[2] + + extension = None + if len(ext_split) == 2: + extension = ext_split[1] + + classifier = None + if len(components) == 4: + classifier = components[3] + return cls(group, artifact, version, classifier, extension) + + @classmethod + def validate(cls, v): + if isinstance(v, cls): + return v + if isinstance(v, str): + return cls.from_string(v) + raise TypeError("Invalid type") + + class MetaBase(pydantic.BaseModel): def dict(self, **kwargs) -> Dict[str, Any]: for k in ["by_alias"]: diff --git a/meta/model/types.py b/meta/model/types.py deleted file mode 100644 index e06bfd615c..0000000000 --- a/meta/model/types.py +++ /dev/null @@ -1,92 +0,0 @@ -from typing import Optional - - -class GradleSpecifier: - """ - A gradle specifier - a maven coordinate. Like one of these: - "org.lwjgl.lwjgl:lwjgl:2.9.0" - "net.java.jinput:jinput:2.0.5" - "net.minecraft:launchwrapper:1.5" - """ - - def __init__(self, group: str, artifact: str, version: str, classifier: Optional[str] = None, - extension: Optional[str] = None): - if extension is None: - extension = "jar" - self.group = group - self.artifact = artifact - self.version = version - self.classifier = classifier - self.extension = extension - - def __str__(self): - ext = '' - if self.extension != 'jar': - ext = "@%s" % self.extension - if self.classifier: - return "%s:%s:%s:%s%s" % (self.group, self.artifact, self.version, self.classifier, ext) - else: - return "%s:%s:%s%s" % (self.group, self.artifact, self.version, ext) - - def filename(self): - if self.classifier: - return "%s-%s-%s.%s" % (self.artifact, self.version, self.classifier, self.extension) - else: - return "%s-%s.%s" % (self.artifact, self.version, self.extension) - - def base(self): - return "%s/%s/%s/" % (self.group.replace('.', '/'), self.artifact, self.version) - - def path(self): - return self.base() + self.filename() - - def __repr__(self): - return f"GradleSpecifier('{self}')" - - def is_lwjgl(self): - return self.group in ("org.lwjgl", "org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils") - - def is_log4j(self): - return self.group == "org.apache.logging.log4j" - - def __eq__(self, other): - return str(self) == str(other) - - def __lt__(self, other): - return str(self) < str(other) - - def __gt__(self, other): - return str(self) > str(other) - - def __hash__(self): - return hash(str(self)) - - @classmethod - def __get_validators__(cls): - yield cls.validate - - @classmethod - def from_string(cls, v: str): - ext_split = v.split('@') - - components = ext_split[0].split(':') - group = components[0] - artifact = components[1] - version = components[2] - - extension = None - if len(ext_split) == 2: - extension = ext_split[1] - - classifier = None - if len(components) == 4: - classifier = components[3] - return cls(group, artifact, version, classifier, extension) - - @classmethod - def validate(cls, v): - if isinstance(v, cls): - return v - if isinstance(v, str): - return cls.from_string(v) - raise TypeError("Invalid type") diff --git a/updateFabric.py b/updateFabric.py index 31708052c8..3d707797bd 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -1,15 +1,16 @@ import hashlib -import zipfile import json import os +import zipfile from datetime import datetime import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.model.fabric import FabricJarInfo + from meta.common import DATETIME_FORMAT_HTTP, upstream_path, ensure_upstream_dir, transform_maven_key from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR +from meta.model.fabric import FabricJarInfo UPSTREAM_DIR = upstream_path() -- cgit 0.0.5-2-1-g0f52 From 6d39c8dfe9b6b1d8b40d2ea90b1eb7f4c33e157c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 5 Apr 2022 17:50:43 +0200 Subject: refactor: cleanup --- generateFabric.py | 4 +- generateForge.py | 446 +++++++++++++++++++++++------------------------- meta/common/__init__.py | 2 - meta/common/fabric.py | 2 + meta/model/fabric.py | 2 +- meta/model/forge.py | 160 ++++++++--------- meta/model/mojang.py | 2 +- updateFabric.py | 4 +- updateForge.py | 168 +++++++++--------- 9 files changed, 384 insertions(+), 406 deletions(-) (limited to 'meta') diff --git a/generateFabric.py b/generateFabric.py index fb1c133bf1..dc81036ec3 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -9,8 +9,8 @@ from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainCl PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() -ensure_component_dir("net.fabricmc.fabric-loader") -ensure_component_dir("net.fabricmc.intermediary") +ensure_component_dir(LOADER_COMPONENT) +ensure_component_dir(INTERMEDIARY_COMPONENT) def load_jar_info(artifact_key) -> FabricJarInfo: diff --git a/generateForge.py b/generateForge.py index 6327c112da..b7057597d5 100755 --- a/generateForge.py +++ b/generateForge.py @@ -2,6 +2,8 @@ import os import re import sys from distutils.version import LooseVersion +from operator import attrgetter +from typing import Collection from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path from meta.common.forge import FORGE_COMPONENT, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, \ @@ -10,7 +12,7 @@ from meta.common.mojang import MINECRAFT_COMPONENT from meta.model import MetaVersion, Dependency, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, \ MetaPackage from meta.model.forge import ForgeVersion, ForgeInstallerProfile, ForgeLegacyInfo, fml_libs_for_version, \ - ForgeInstallerProfileV2, InstallerInfo, DerivedForgeIndex, ForgeLegacyInfoList + ForgeInstallerProfileV2, InstallerInfo, DerivedForgeIndex, ForgeLegacyInfoList, ForgeLibrary from meta.model.mojang import MojangVersion PMC_DIR = polymc_path() @@ -25,18 +27,16 @@ def eprint(*args, **kwargs): # Contruct a set of libraries out of a Minecraft version file, for filtering. -mcVersionCache = {} +mc_version_cache = {} -def loadMcVersionFilter(version): - if version in mcVersionCache: - return mcVersionCache[version] - libSet = set() - mcVersion = MetaVersion.parse_file(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version}.json")) - for lib in mcVersion.libraries: - libSet.add(lib.name) - mcVersionCache[version] = libSet - return libSet +def load_mc_version_filter(version: str): + if version in mc_version_cache: + return mc_version_cache[version] + v = MetaVersion.parse_file(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version}.json")) + libs = set(map(attrgetter("name"), v.libraries)) + mc_version_cache[version] = libs + return libs ''' @@ -46,31 +46,32 @@ Match a library coordinate to a set of library coordinates. ''' -def shouldIgnoreArtifact(libSet, match): - for ver in libSet: +def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpecifier): + for ver in libs: if ver.group == match.group and ver.artifact == match.artifact and ver.classifier == match.classifier: if ver.version == match.version: # Everything is matched perfectly - this one will be ignored return True + elif LooseVersion(ver.version) > LooseVersion(match.version): + # eprint ("Lower version on %s:%s:%s: OLD=%s NEW=%s" % (ver.group, ver.artifact, ver.classifier, ver.version, match.version)) + return True else: - # We say the lib matches (is the same) also when the new version is lower than the old one - if LooseVersion(ver.version) > LooseVersion(match.version): - # eprint ("Lower version on %s:%s:%s: OLD=%s NEW=%s" % (ver.group, ver.artifact, ver.classifier, ver.version, match.version)) - return True # Otherwise it did not match - new version is higher and this is an upgrade return False # No match found in the set - we need to keep this return False -def versionFromProfile(profile: ForgeInstallerProfile, version): - result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - mcversion = profile.install.minecraft - result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mcversion)] - result.main_class = profile.versionInfo.main_class - args = profile.versionInfo.minecraft_arguments +def version_from_profile(profile: ForgeInstallerProfile, version: ForgeVersion) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = profile.install.minecraft + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = profile.version_info.main_class + v.release_time = profile.version_info.time + + args = profile.version_info.minecraft_arguments tweakers = [] - expression = re.compile("--tweakClass ([a-zA-Z0-9\\.]+)") + expression = re.compile(r"--tweakClass ([a-zA-Z0-9.]+)") match = expression.search(args) while match is not None: tweakers.append(match.group(1)) @@ -78,48 +79,48 @@ def versionFromProfile(profile: ForgeInstallerProfile, version): match = expression.search(args) if len(tweakers) > 0: args = args.strip() - result.additional_tweakers = tweakers - # result.minecraftArguments = args - result.release_time = profile.versionInfo.time - libs = [] - mcFilter = loadMcVersionFilter(mcversion) - for forgeLib in profile.versionInfo.libraries: - if forgeLib.name.is_lwjgl(): - continue - if forgeLib.name.is_log4j(): - continue - if shouldIgnoreArtifact(mcFilter, forgeLib.name): + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + mc_filter = load_mc_version_filter(mc_version) + for forge_lib in profile.version_info.libraries: + if forge_lib.name.is_lwjgl() or forge_lib.name.is_log4j() or should_ignore_artifact(mc_filter, forge_lib.name): continue - fixedName = forgeLib.name - if fixedName.group == "net.minecraftforge": - if fixedName.artifact == "minecraftforge": - fixedName.artifact = "forge" - fixedName.classifier = "universal" - fixedName.version = "%s-%s" % (mcversion, fixedName.version) - elif fixedName.artifact == "forge": - fixedName.classifier = "universal" - ourLib = Library(name=fixedName) - if forgeLib.url == "http://files.minecraftforge.net/maven/": - ourLib.url = "https://maven.minecraftforge.net/" + + overridden_name = forge_lib.name + if overridden_name.group == "net.minecraftforge": + if overridden_name.artifact == "minecraftforge": + overridden_name.artifact = "forge" + overridden_name.version = "%s-%s" % (mc_version, overridden_name.version) + + overridden_name.classifier = "universal" + elif overridden_name.artifact == "forge": + overridden_name.classifier = "universal" + + overridden_lib = Library(name=overridden_name) + if forge_lib.url == "http://files.minecraftforge.net/maven/": + overridden_lib.url = "https://maven.minecraftforge.net/" else: - ourLib.url = forgeLib.url - # if forgeLib.checksums and len(forgeLib.checksums) == 2: - # ourLib.mmcHint = "forge-pack-xz" - libs.append(ourLib) - result.libraries = libs - result.order = 5 - return result - - -def versionFromModernizedInstaller(installerVersion: MojangVersion, version: ForgeVersion): - eprint("Generating Modernized Forge %s." % version.longVersion) - result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - mcversion = version.mcversion - result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mcversion)] - result.main_class = installerVersion.main_class - args = installerVersion.minecraft_arguments + overridden_lib.url = forge_lib.url + # if forge_lib.checksums and len(forge_lib.checksums) == 2: + # overridden_lib.mmcHint = "forge-pack-xz" + v.libraries.append(overridden_lib) + + v.order = 5 + return v + + +def version_from_modernized_installer(installer: MojangVersion, version: ForgeVersion) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = version.mc_version + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = installer.main_class + v.release_time = installer.release_time + + args = installer.minecraft_arguments tweakers = [] - expression = re.compile("--tweakClass ([a-zA-Z0-9\\.]+)") + expression = re.compile("--tweakClass ([a-zA-Z0-9.]+)") match = expression.search(args) while match is not None: tweakers.append(match.group(1)) @@ -127,146 +128,132 @@ def versionFromModernizedInstaller(installerVersion: MojangVersion, version: For match = expression.search(args) if len(tweakers) > 0: args = args.strip() - result.additional_tweakers = tweakers - # result.minecraftArguments = args - result.release_time = installerVersion.release_time - libs = [] - mcFilter = loadMcVersionFilter(mcversion) - for upstreamLib in installerVersion.libraries: - pmcLib = Library.parse_obj(upstreamLib.dict()) - if pmcLib.name.is_lwjgl(): - continue - if pmcLib.name.is_log4j(): - continue - if shouldIgnoreArtifact(mcFilter, pmcLib.name): + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + + mc_filter = load_mc_version_filter(mc_version) + for upstream_lib in installer.libraries: + forge_lib = Library.parse_obj(upstream_lib.dict()) # "cast" MojangLibrary to Library + if forge_lib.name.is_lwjgl() or forge_lib.name.is_log4j() or should_ignore_artifact(mc_filter, forge_lib.name): continue - if pmcLib.name.group == "net.minecraftforge": - if pmcLib.name.artifact == "forge": - fixedName = pmcLib.name - fixedName.classifier = "universal" - pmcLib.downloads.artifact.path = fixedName.path() - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.path() - pmcLib.name = fixedName - libs.append(pmcLib) - continue - elif pmcLib.name.artifact == "minecraftforge": - fixedName = pmcLib.name - fixedName.artifact = "forge" - fixedName.classifier = "universal" - fixedName.version = "%s-%s" % (mcversion, fixedName.version) - pmcLib.downloads.artifact.path = fixedName.path() - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.path() - pmcLib.name = fixedName - libs.append(pmcLib) - continue - libs.append(pmcLib) - - result.libraries = libs - result.order = 5 - return result - - -def versionFromLegacy(version: ForgeVersion, legacyinfo: ForgeLegacyInfo): - result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - mcversion = version.mcversion_sane - result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mcversion)] - result.release_time = legacyinfo.releaseTime - result.order = 5 - if fml_libs_for_version(mcversion): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING - result.additional_traits = ["legacyFML"] - url = version.url() - if "universal" in url: + + if forge_lib.name.group == "net.minecraftforge": + if forge_lib.name.artifact == "forge": + overridden_name = forge_lib.name + overridden_name.classifier = "universal" + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % overridden_name.path() + forge_lib.name = overridden_name + + elif forge_lib.name.artifact == "minecraftforge": + overridden_name = forge_lib.name + overridden_name.artifact = "forge" + overridden_name.classifier = "universal" + overridden_name.version = "%s-%s" % (mc_version, overridden_name.version) + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % overridden_name.path() + forge_lib.name = overridden_name + + v.libraries.append(forge_lib) + + v.order = 5 + return v + + +def version_from_legacy(info: ForgeLegacyInfo, version: ForgeVersion) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = version.mc_version_sane + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.release_time = info.release_time + v.order = 5 + if fml_libs_for_version(mc_version): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING + v.additional_traits = ["legacyFML"] + + classifier = "client" + if "universal" in version.url(): classifier = "universal" - else: - classifier = "client" - coord = GradleSpecifier("net.minecraftforge", "forge", version.longVersion, classifier) - mainmod = Library(name=coord) - mainmod.downloads = MojangLibraryDownloads() - mainmod.downloads.artifact = MojangArtifact(url=version.url(), sha1=legacyinfo.sha1, size=legacyinfo.size) - mainmod.downloads.artifact.path = None - result.jar_mods = [mainmod] - return result - - -def versionFromBuildSystemInstaller(installerVersion: MojangVersion, installerProfile: ForgeInstallerProfileV2, - version: ForgeVersion): - eprint("Generating Forge %s." % version.longVersion) - result = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - result.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mcversion_sane)] - result.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" + + main_mod = Library(name=GradleSpecifier("net.minecraftforge", "forge", version.long_version, classifier)) + main_mod.downloads = MojangLibraryDownloads() + main_mod.downloads.artifact = MojangArtifact(url=version.url(), sha1=info.sha1, size=info.size) + main_mod.downloads.artifact.path = None + v.jar_mods = [main_mod] + return v + + +def version_from_build_system_installer(installer: MojangVersion, profile: ForgeInstallerProfileV2, + version: ForgeVersion) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] + v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" # FIXME: Add the size and hash here - mavenLibs = [] + v.maven_files = [] # load the locally cached installer file info and use it to add the installer entry in the json - installerInfo = InstallerInfo.parse_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.longVersion}.json")) - InstallerLib = Library( - name=GradleSpecifier("net.minecraftforge", "forge", version.longVersion, "installer")) - InstallerLib.downloads = MojangLibraryDownloads() - InstallerLib.downloads.artifact = MojangArtifact( - url="https://files.minecraftforge.net/maven/%s" % (InstallerLib.name.path()), - sha1=installerInfo.sha1hash, - size=installerInfo.size) - mavenLibs.append(InstallerLib) - - for upstreamLib in installerProfile.libraries: - pmcLib = Library.parse_obj(upstreamLib.dict()) - if pmcLib.name.group == "net.minecraftforge": - if pmcLib.name.artifact == "forge": - if pmcLib.name.classifier == "universal": - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % pmcLib.name.path() - mavenLibs.append(pmcLib) - continue - if pmcLib.name.is_log4j(): + info = InstallerInfo.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json")) + installer_lib = Library( + name=GradleSpecifier("net.minecraftforge", "forge", version.long_version, "installer")) + installer_lib.downloads = MojangLibraryDownloads() + installer_lib.downloads.artifact = MojangArtifact( + url="https://files.minecraftforge.net/maven/%s" % (installer_lib.name.path()), + sha1=info.sha1hash, + size=info.size) + v.maven_files.append(installer_lib) + + for upstream_lib in profile.libraries: + forge_lib = Library.parse_obj(upstream_lib.dict()) + if forge_lib.name.is_log4j(): continue - mavenLibs.append(pmcLib) - - result.maven_files = mavenLibs - - libraries = [] - - wrapperLib = Library(name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2")) - wrapperLib.downloads = MojangLibraryDownloads() - wrapperLib.downloads.artifact = MojangArtifact(url=FORGEWRAPPER_MAVEN % (wrapperLib.name.path()), - sha1="4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", - size=34444) - libraries.append(wrapperLib) - - for upstreamLib in installerVersion.libraries: - pmcLib = Library.parse_obj(upstreamLib.dict()) - if pmcLib.name.group == "net.minecraftforge": - if pmcLib.name.artifact == "forge": - fixedName = pmcLib.name - fixedName.classifier = "launcher" - pmcLib.downloads.artifact.path = fixedName.path() - pmcLib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % fixedName.path() - pmcLib.name = fixedName - libraries.append(pmcLib) - continue - if pmcLib.name.is_log4j(): + + if forge_lib.name.group == "net.minecraftforge" and forge_lib.name.artifact == "forge" \ + and forge_lib.name.classifier == "universal": + forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % forge_lib.name.path() + v.maven_files.append(forge_lib) + + v.libraries = [] + + wrapper_lib = Library(name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2")) + wrapper_lib.downloads = MojangLibraryDownloads() + wrapper_lib.downloads.artifact = MojangArtifact(url=FORGEWRAPPER_MAVEN % (wrapper_lib.name.path()), + sha1="4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", + size=34444) + v.libraries.append(wrapper_lib) + + for upstream_lib in installer.libraries: + forge_lib = Library.parse_obj(upstream_lib.dict()) + if forge_lib.name.is_log4j(): continue - libraries.append(pmcLib) - result.libraries = libraries - result.release_time = installerVersion.release_time - result.order = 5 - mcArgs = "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" - for arg in installerVersion.arguments.game: - mcArgs += " %s" % arg - result.minecraft_arguments = mcArgs - return result + if forge_lib.name.group == "net.minecraftforge": + if forge_lib.name.artifact == "forge": + forge_lib.name.classifier = "launcher" + forge_lib.downloads.artifact.path = forge_lib.name.path() + forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % forge_lib.name.path() + forge_lib.name = forge_lib.name + v.libraries.append(forge_lib) + + v.release_time = installer.release_time + v.order = 5 + mc_args = "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " \ + "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " \ + "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + for arg in installer.arguments.game: + mc_args += f" {arg}" + v.minecraft_arguments = mc_args + return v def main(): # load the locally cached version list - remoteVersionlist = DerivedForgeIndex.parse_file(os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE)) + remote_versions = DerivedForgeIndex.parse_file(os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE)) + recommended_versions = [] - recommendedVersions = [] - - legacyinfolist = ForgeLegacyInfoList.parse_file(os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE)) - - legacyVersions = [ + legacy_info_list = ForgeLegacyInfoList.parse_file(os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE)) + legacy_versions = [ "1.1", "1.2.3", "1.2.4", @@ -303,90 +290,87 @@ def main(): "1.12.2", ] - for id, entry in remoteVersionlist.versions.items(): - if entry.mcversion is None: - eprint("Skipping %s with invalid MC version" % id) + for key, entry in remote_versions.versions.items(): + if entry.mc_version is None: + eprint("Skipping %s with invalid MC version" % key) continue version = ForgeVersion(entry) - if version.longVersion in BAD_VERSIONS: + if version.long_version in BAD_VERSIONS: # Version 1.12.2-14.23.5.2851 is ultra cringe, I can't imagine why you would even spend one second on # actually adding support for this version. # It is cringe, because it's installer info is broken af - eprint(f"Skipping bad version {version.longVersion}") + eprint(f"Skipping bad version {version.long_version}") continue if version.url() is None: - eprint("Skipping %s with no valid files" % id) + eprint("Skipping %s with no valid files" % key) continue eprint("Processing Forge %s" % version.rawVersion) - versionElements = version.rawVersion.split('.') - if len(versionElements) < 1: - eprint("Skipping version %s with not enough version elements" % (id)) + version_elements = version.rawVersion.split('.') + if len(version_elements) < 1: + eprint("Skipping version %s with not enough version elements" % key) continue - majorVersionStr = versionElements[0] - if not majorVersionStr.isnumeric(): - eprint("Skipping version %s with non-numeric major version %s" % (id, majorVersionStr)) + major_version_str = version_elements[0] + if not major_version_str.isnumeric(): + eprint("Skipping version %s with non-numeric major version %s" % (key, major_version_str)) continue - majorVersion = int(majorVersionStr) - # if majorVersion >= 37: - # eprint ("Skipping unsupported major version %d (%s)" % (majorVersion, id)) + major_version = int(major_version_str) + # if major_version >= 37: + # eprint ("Skipping unsupported major version %d (%s)" % (major_version, key)) # continue if entry.recommended: - recommendedVersions.append(version.rawVersion) + recommended_versions.append(version.rawVersion) # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version.mcversion_sane}.json")): - eprint("Skipping %s with no corresponding Minecraft version %s" % (id, version.mcversion_sane)) + if not os.path.isfile(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json")): + eprint("Skipping %s with no corresponding Minecraft version %s" % (key, version.mc_version_sane)) continue - outVersion = None - # Path for new-style build system based installers - installerVersionFilepath = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.longVersion}.json") - profileFilepath = os.path.join(UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.longVersion}.json") - - eprint(installerVersionFilepath) - if os.path.isfile(installerVersionFilepath): - installerVersion = MojangVersion.parse_file(installerVersionFilepath) - if entry.mcversion in legacyVersions: - outVersion = versionFromModernizedInstaller(installerVersion, version) + installer_version_filepath = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json") + profile_filepath = os.path.join(UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json") + + eprint(installer_version_filepath) + if os.path.isfile(installer_version_filepath): + installer = MojangVersion.parse_file(installer_version_filepath) + if entry.mc_version in legacy_versions: + v = version_from_modernized_installer(installer, version) else: - installerProfile = ForgeInstallerProfileV2.parse_file(profileFilepath) - outVersion = versionFromBuildSystemInstaller(installerVersion, installerProfile, version) + profile = ForgeInstallerProfileV2.parse_file(profile_filepath) + v = version_from_build_system_installer(installer, profile, version) else: if version.uses_installer(): # If we do not have the Forge json, we ignore this version - if not os.path.isfile(profileFilepath): - eprint("Skipping %s with missing profile json" % id) + if not os.path.isfile(profile_filepath): + eprint("Skipping %s with missing profile json" % key) continue - profile = ForgeInstallerProfile.parse_file(profileFilepath) - outVersion = versionFromProfile(profile, version) + profile = ForgeInstallerProfile.parse_file(profile_filepath) + v = version_from_profile(profile, version) else: # Generate json for legacy here - if version.mcversion_sane == "1.6.1": + if version.mc_version_sane == "1.6.1": continue build = version.build - if not str(build).encode('utf-8').decode('utf8') in legacyinfolist.number: + if not str(build).encode('utf-8').decode('utf8') in legacy_info_list.number: eprint("Legacy build %d is missing in legacy info. Ignoring." % build) continue - outVersion = versionFromLegacy(version, legacyinfolist.number[str(build)]) + v = version_from_legacy(legacy_info_list.number[str(build)], version) - outFilepath = os.path.join(PMC_DIR, FORGE_COMPONENT, f"{outVersion.version}.json") - outVersion.write(outFilepath) + v.write(os.path.join(PMC_DIR, FORGE_COMPONENT, f"{v.version}.json")) - recommendedVersions.sort() + recommended_versions.sort() - print('Recommended versions:', recommendedVersions) + print('Recommended versions:', recommended_versions) package = MetaPackage(uid=FORGE_COMPONENT, name="Forge", project_url="https://www.minecraftforge.net/forum/") - package.recommended = recommendedVersions + package.recommended = recommended_versions package.write(os.path.join(PMC_DIR, FORGE_COMPONENT, "package.json")) diff --git a/meta/common/__init__.py b/meta/common/__init__.py index d072287277..4db3c57b61 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -1,8 +1,6 @@ import os import datetime -DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" - def serialize_datetime(dt: datetime.datetime): if dt.tzinfo is None: diff --git a/meta/common/fabric.py b/meta/common/fabric.py index a306f15a16..2a35695cf1 100644 --- a/meta/common/fabric.py +++ b/meta/common/fabric.py @@ -8,3 +8,5 @@ META_DIR = join(BASE_DIR, "meta-v2") LOADER_COMPONENT = "net.fabricmc.fabric-loader" INTERMEDIARY_COMPONENT = "net.fabricmc.intermediary" + +DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" diff --git a/meta/model/fabric.py b/meta/model/fabric.py index cd326e54c2..3ae557bf85 100644 --- a/meta/model/fabric.py +++ b/meta/model/fabric.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Optional, List, Union, Dict +from typing import Optional, List, Union from pydantic import Field diff --git a/meta/model/forge.py b/meta/model/forge.py index 6290cc8dff..35af76b3ad 100644 --- a/meta/model/forge.py +++ b/meta/model/forge.py @@ -12,17 +12,17 @@ class ForgeFile(MetaBase): hash: str extension: str - def filename(self, longversion): - return "%s-%s-%s.%s" % ("forge", longversion, self.classifier, self.extension) + def filename(self, long_version): + return "%s-%s-%s.%s" % ("forge", long_version, self.classifier, self.extension) - def url(self, longversion): + def url(self, long_version): return "https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s/%s" % ( - longversion, self.filename(longversion)) + long_version, self.filename(long_version)) class ForgeEntry(MetaBase): - longversion: str - mcversion: str + long_version: str = Field(alias="longversion") + mc_version: str = Field(alias="mcversion") version: str build: int branch: Optional[str] @@ -39,7 +39,7 @@ class ForgeMCVersionInfo(MetaBase): class DerivedForgeIndex(MetaBase): versions: Dict[str, ForgeEntry] = Field({}) - by_mcversion: Dict[str, ForgeMCVersionInfo] = Field({}) + by_mc_version: Dict[str, ForgeMCVersionInfo] = Field({}, alias="by_mcversion") class FMLLib(MetaBase): # old ugly stuff. Maybe merge this with Library or MojangLibrary later @@ -74,29 +74,29 @@ class ForgeInstallerProfileInstallSection(MetaBase): "modList":"none" }, """ - profileName: str + profile_name: str = Field(alias="profileName") target: str path: GradleSpecifier version: str - filePath: str + file_path: str = Field(alias="filePath") welcome: str minecraft: str logo: str - mirrorList: str - modList: Optional[str] + mirror_list: str = Field(alias="mirrorList") + mod_list: Optional[str] = Field(alias="modList") class ForgeLibrary(MojangLibrary): url: Optional[str] - serverreq: Optional[bool] - clientreq: Optional[bool] + server_req: Optional[bool] = Field(alias="serverreq") + client_req: Optional[bool] = Field(alias="clientreq") checksums: Optional[List[str]] comment: Optional[str] class ForgeVersionFile(MojangVersion): libraries: Optional[List[ForgeLibrary]] # overrides Mojang libraries - inheritsFrom: Optional[str] + inherits_from: Optional[str] = Field("inheritsFrom") jar: Optional[str] @@ -129,12 +129,12 @@ class ForgeOptional(MetaBase): class ForgeInstallerProfile(MetaBase): install: ForgeInstallerProfileInstallSection - versionInfo: ForgeVersionFile + version_info: ForgeVersionFile = Field(alias="versionInfo") optionals: Optional[List[ForgeOptional]] class ForgeLegacyInfo(MetaBase): - releaseTime: Optional[datetime] + release_time: Optional[datetime] = Field(alias="releaseTime") size: Optional[int] sha256: Optional[str] sha1: Optional[str] @@ -171,8 +171,8 @@ class ForgeInstallerProfileV2(MetaBase): data: Optional[Dict[str, DataSpec]] processors: Optional[List[ProcessorSpec]] libraries: Optional[List[MojangLibrary]] - mirrorList: Optional[str] - serverJarPath: Optional[str] + mirror_list: Optional[str] = Field(alias="mirrorList") + server_jar_path: Optional[str] = Field(alias="serverJarPath") class InstallerInfo(MetaBase): @@ -181,83 +181,28 @@ class InstallerInfo(MetaBase): size: Optional[int] -def fml_libs_for_version(mc_version: str) -> List[FMLLib]: - argo_2_25 = FMLLib(filename="argo-2.25.jar", - checksum="bb672829fde76cb163004752b86b0484bd0a7f4b", - ours=False) - argo_small_3_2 = FMLLib(filename="argo-small-3.2.jar", - checksum="58912ea2858d168c50781f956fa5b59f0f7c6b51", - ours=False) - guava_12_0_1 = FMLLib(filename="guava-12.0.1.jar", - checksum="b8e78b9af7bf45900e14c6f958486b6ca682195f", - ours=False) - guava_14_0_rc3 = FMLLib(filename="guava-14.0-rc3.jar", - checksum="931ae21fa8014c3ce686aaa621eae565fefb1a6a", - ours=False) - asm_all_4_0 = FMLLib(filename="asm-all-4.0.jar", - checksum="98308890597acb64047f7e896638e0d98753ae82", - ours=False) - asm_all_4_1 = FMLLib(filename="asm-all-4.1.jar", - checksum="054986e962b88d8660ae4566475658469595ef58", - ours=False) - bcprov_jdk15on_147 = FMLLib(filename="bcprov-jdk15on-147.jar", - checksum="b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", - ours=False) - bcprov_jdk15on_148 = FMLLib(filename="bcprov-jdk15on-148.jar", - checksum="960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", - ours=True) - scala_library = FMLLib(filename="scala-library.jar", - checksum="458d046151ad179c85429ed7420ffb1eaf6ddf85", - ours=True) - - deobfuscation_data_1_5 = FMLLib(filename="deobfuscation_data_1.5.zip", - checksum="5f7c142d53776f16304c0bbe10542014abad6af8", - ours=False) - - deobfuscation_data_1_5_1 = FMLLib(filename="deobfuscation_data_1.5.1.zip", - checksum="22e221a0d89516c1f721d6cab056a7e37471d0a6", - ours=False) - deobfuscation_data_1_5_2 = FMLLib(filename="deobfuscation_data_1.5.2.zip", - checksum="446e55cd986582c70fcf12cb27bc00114c5adfd9", - ours=False) - if mc_version == "1.3.2": - return [argo_2_25, guava_12_0_1, asm_all_4_0] - elif mc_version in ["1.4", "1.4.1", "1.4.2", "1.4.3", "1.4.4", "1.4.5", "1.4.6", "1.4.7"]: - return [argo_2_25, guava_12_0_1, asm_all_4_0, bcprov_jdk15on_147] - elif mc_version == "1.5": - return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5, - scala_library] - elif mc_version == "1.5.1": - return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_1, - scala_library] - elif mc_version == "1.5.2": - return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_2, - scala_library] - return [] - - # A post-processed entry constructed from the reconstructed Forge version index class ForgeVersion: def __init__(self, entry: ForgeEntry): self.build = entry.build self.rawVersion = entry.version - self.mcversion = entry.mcversion - self.mcversion_sane = self.mcversion.replace("_pre", "-pre", 1) + self.mc_version = entry.mc_version + self.mc_version_sane = self.mc_version.replace("_pre", "-pre", 1) self.branch = entry.branch self.installer_filename = None self.installer_url = None self.universal_filename = None self.universal_url = None self.changelog_url = None - self.longVersion = "%s-%s" % (self.mcversion, self.rawVersion) + self.long_version = "%s-%s" % (self.mc_version, self.rawVersion) if self.branch is not None: - self.longVersion = self.longVersion + "-%s" % self.branch + self.long_version = self.long_version + "-%s" % self.branch # this comment's whole purpose is to say this: cringe for classifier, file in entry.files.items(): extension = file.extension - filename = file.filename(self.longVersion) - url = file.url(self.longVersion) + filename = file.filename(self.long_version) + url = file.url(self.long_version) if (classifier == "installer") and (extension == "jar"): self.installer_filename = filename self.installer_url = url @@ -273,7 +218,7 @@ class ForgeVersion: def uses_installer(self): if self.installer_url is None: return False - if self.mcversion == "1.5.2": + if self.mc_version == "1.5.2": return False return True @@ -304,3 +249,58 @@ class ForgeVersion: # return False return True + + +def fml_libs_for_version(mc_version: str) -> List[FMLLib]: + argo_2_25 = FMLLib(filename="argo-2.25.jar", + checksum="bb672829fde76cb163004752b86b0484bd0a7f4b", + ours=False) + argo_small_3_2 = FMLLib(filename="argo-small-3.2.jar", + checksum="58912ea2858d168c50781f956fa5b59f0f7c6b51", + ours=False) + guava_12_0_1 = FMLLib(filename="guava-12.0.1.jar", + checksum="b8e78b9af7bf45900e14c6f958486b6ca682195f", + ours=False) + guava_14_0_rc3 = FMLLib(filename="guava-14.0-rc3.jar", + checksum="931ae21fa8014c3ce686aaa621eae565fefb1a6a", + ours=False) + asm_all_4_0 = FMLLib(filename="asm-all-4.0.jar", + checksum="98308890597acb64047f7e896638e0d98753ae82", + ours=False) + asm_all_4_1 = FMLLib(filename="asm-all-4.1.jar", + checksum="054986e962b88d8660ae4566475658469595ef58", + ours=False) + bcprov_jdk15on_147 = FMLLib(filename="bcprov-jdk15on-147.jar", + checksum="b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", + ours=False) + bcprov_jdk15on_148 = FMLLib(filename="bcprov-jdk15on-148.jar", + checksum="960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", + ours=True) + scala_library = FMLLib(filename="scala-library.jar", + checksum="458d046151ad179c85429ed7420ffb1eaf6ddf85", + ours=True) + + deobfuscation_data_1_5 = FMLLib(filename="deobfuscation_data_1.5.zip", + checksum="5f7c142d53776f16304c0bbe10542014abad6af8", + ours=False) + + deobfuscation_data_1_5_1 = FMLLib(filename="deobfuscation_data_1.5.1.zip", + checksum="22e221a0d89516c1f721d6cab056a7e37471d0a6", + ours=False) + deobfuscation_data_1_5_2 = FMLLib(filename="deobfuscation_data_1.5.2.zip", + checksum="446e55cd986582c70fcf12cb27bc00114c5adfd9", + ours=False) + if mc_version == "1.3.2": + return [argo_2_25, guava_12_0_1, asm_all_4_0] + elif mc_version in ["1.4", "1.4.1", "1.4.2", "1.4.3", "1.4.4", "1.4.5", "1.4.6", "1.4.7"]: + return [argo_2_25, guava_12_0_1, asm_all_4_0, bcprov_jdk15on_147] + elif mc_version == "1.5": + return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5, + scala_library] + elif mc_version == "1.5.1": + return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_1, + scala_library] + elif mc_version == "1.5.2": + return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_2, + scala_library] + return [] diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 0df4cbcfc0..e5ea072acd 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -156,7 +156,7 @@ class MojangVersion(MetaBase): release_time: Optional[datetime] = Field(alias="releaseTime") time: Optional[datetime] type: Optional[str] - inheritsFrom: Optional[str] + inherits_from: Optional[str] = Field("inheritsFrom") logging: Optional[Dict[str, MojangLogging]] # TODO improve this? compliance_level: Optional[int] = Field(alias="complianceLevel") javaVersion: Optional[JavaVersion] diff --git a/updateFabric.py b/updateFabric.py index 3d707797bd..2f9ac262dd 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -8,8 +8,8 @@ import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.common import DATETIME_FORMAT_HTTP, upstream_path, ensure_upstream_dir, transform_maven_key -from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR +from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key +from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, DATETIME_FORMAT_HTTP from meta.model.fabric import FabricJarInfo UPSTREAM_DIR = upstream_path() diff --git a/updateForge.py b/updateForge.py index 0492339b83..4106bd8a8b 100755 --- a/updateForge.py +++ b/updateForge.py @@ -167,55 +167,55 @@ def main(): print("") print("Processing versions:") - for mcversion, value in main_json.items(): - assert type(mcversion) == str + for mc_version, value in main_json.items(): + assert type(mc_version) == str assert type(value) == list - for longversion in value: - assert type(longversion) == str - match = versionExpression.match(longversion) + for long_version in value: + assert type(long_version) == str + match = versionExpression.match(long_version) if not match: - pprint(longversion) + pprint(long_version) assert match - assert match.group('mc') == mcversion + assert match.group('mc') == mc_version - files = get_single_forge_files_manifest(longversion) + files = get_single_forge_files_manifest(long_version) build = int(match.group('build')) version = match.group('ver') branch = match.group('branch') - isRecommended = (version in recommendedSet) + is_recommended = (version in recommendedSet) entry = ForgeEntry( - longversion=longversion, - mcversion=mcversion, + long_version=long_version, + mc_version=mc_version, version=version, build=build, branch=branch, # NOTE: we add this later after the fact. The forge promotions file lies about these. latest=False, - recommended=isRecommended, + recommended=is_recommended, files=files ) - newIndex.versions[longversion] = entry - if not newIndex.by_mcversion: - newIndex.by_mcversion = dict() - if not mcversion in newIndex.by_mcversion: - newIndex.by_mcversion.setdefault(mcversion, ForgeMCVersionInfo()) - newIndex.by_mcversion[mcversion].versions.append(longversion) + newIndex.versions[long_version] = entry + if not newIndex.by_mc_version: + newIndex.by_mc_version = dict() + if mc_version not in newIndex.by_mc_version: + newIndex.by_mc_version.setdefault(mc_version, ForgeMCVersionInfo()) + newIndex.by_mc_version[mc_version].versions.append(long_version) # NOTE: we add this later after the fact. The forge promotions file lies about these. # if entry.latest: - # newIndex.by_mcversion[mcversion].latest = longversion + # newIndex.by_mc_version[mc_version].latest = long_version if entry.recommended: - newIndex.by_mcversion[mcversion].recommended = longversion + newIndex.by_mc_version[mc_version].recommended = long_version print("") print("Post processing promotions and adding missing 'latest':") - for mcversion, info in newIndex.by_mcversion.items(): - latestVersion = info.versions[-1] - info.latest = latestVersion - newIndex.versions[latestVersion].latest = True - print("Added %s as latest for %s" % (latestVersion, mcversion)) + for mc_version, info in newIndex.by_mc_version.items(): + latest_version = info.versions[-1] + info.latest = latest_version + newIndex.versions[latest_version].latest = True + print("Added %s as latest for %s" % (latest_version, mc_version)) print("") print("Dumping index files...") @@ -228,13 +228,13 @@ def main(): newIndex.write(UPSTREAM_DIR + "/forge/derived_index.json") - legacyinfolist = ForgeLegacyInfoList() + legacy_info_list = ForgeLegacyInfoList() print("Grabbing installers and dumping installer profiles...") # get the installer jars - if needed - and get the installer profiles out of them - for id, entry in newIndex.versions.items(): - eprint("Updating Forge %s" % id) - if entry.mcversion is None: + for key, entry in newIndex.versions.items(): + eprint("Updating Forge %s" % key) + if entry.mc_version is None: eprint("Skipping %d with invalid MC version" % entry.build) continue @@ -242,118 +242,112 @@ def main(): if version.url() is None: eprint("Skipping %d with no valid files" % version.build) continue - if version.longVersion in BAD_VERSIONS: - eprint(f"Skipping bad version {version.longVersion}") + if version.long_version in BAD_VERSIONS: + eprint(f"Skipping bad version {version.long_version}") continue - jarFilepath = UPSTREAM_DIR + "/forge/jars/%s" % version.filename() + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) if version.uses_installer(): - installerInfoFilepath = UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.longVersion - profileFilepath = UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.longVersion - versionJsonFilepath = UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.longVersion - installerRefreshRequired = False - if not os.path.isfile(profileFilepath): - installerRefreshRequired = True - if not os.path.isfile(installerInfoFilepath): - installerRefreshRequired = True - - if installerRefreshRequired: + installer_info_path = UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version + profile_path = UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.long_version + version_file_path = UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version + + installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile(installer_info_path) + + if installer_refresh_required: # grab the installer if it's not there - if not os.path.isfile(jarFilepath): + if not os.path.isfile(jar_path): eprint("Downloading %s" % version.url()) rfile = sess.get(version.url(), stream=True) rfile.raise_for_status() - with open(jarFilepath, 'wb') as f: + with open(jar_path, 'wb') as f: for chunk in rfile.iter_content(chunk_size=128): f.write(chunk) eprint("Processing %s" % version.url()) # harvestables from the installer - if not os.path.isfile(profileFilepath): - print(jarFilepath) - with zipfile.ZipFile(jarFilepath, 'r') as jar: + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path, 'r') as jar: with suppress(KeyError): - with jar.open('version.json', 'r') as profileZipEntry: - versionJsonData = profileZipEntry.read() - profileZipEntry.close() + with jar.open('version.json', 'r') as profile_zip_entry: + version_data = profile_zip_entry.read() # Process: does it parse? - doesItParse = MojangVersion.parse_raw(versionJsonData) + MojangVersion.parse_raw(version_data) - with open(versionJsonFilepath, 'wb') as versionJsonFile: - versionJsonFile.write(versionJsonData) + with open(version_file_path, 'wb') as versionJsonFile: + versionJsonFile.write(version_data) versionJsonFile.close() - with jar.open('install_profile.json', 'r') as profileZipEntry: - installProfileJsonData = profileZipEntry.read() - profileZipEntry.close() + with jar.open('install_profile.json', 'r') as profile_zip_entry: + install_profile_data = profile_zip_entry.read() # Process: does it parse? - atLeastOneFormatWorked = False + is_parsable = False exception = None try: - ForgeInstallerProfile.parse_raw(installProfileJsonData) - atLeastOneFormatWorked = True + ForgeInstallerProfile.parse_raw(install_profile_data) + is_parsable = True except ValidationError as err: exception = err try: - ForgeInstallerProfileV2.parse_raw(installProfileJsonData) - atLeastOneFormatWorked = True + ForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True except ValidationError as err: exception = err - if not atLeastOneFormatWorked: + if not is_parsable: if version.is_supported(): raise exception else: eprint( - "Version %s is not supported and won't be generated later." % version.longVersion) + "Version %s is not supported and won't be generated later." % version.long_version) - with open(profileFilepath, 'wb') as profileFile: - profileFile.write(installProfileJsonData) + with open(profile_path, 'wb') as profileFile: + profileFile.write(install_profile_data) profileFile.close() # installer info v1 - if not os.path.isfile(installerInfoFilepath): - installerInfo = InstallerInfo() - installerInfo.sha1hash = filehash(jarFilepath, hashlib.sha1) - installerInfo.sha256hash = filehash(jarFilepath, hashlib.sha256) - installerInfo.size = os.path.getsize(jarFilepath) - installerInfo.write(installerInfoFilepath) + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = filehash(jar_path, hashlib.sha1) + installer_info.sha256hash = filehash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) else: # ignore the two versions without install manifests and jar mod class files # TODO: fix those versions? - if version.mcversion_sane == "1.6.1": + if version.mc_version_sane == "1.6.1": continue # only gather legacy info if it's missing if not os.path.isfile(LEGACYINFO_PATH): # grab the jar/zip if it's not there - if not os.path.isfile(jarFilepath): + if not os.path.isfile(jar_path): rfile = sess.get(version.url(), stream=True) rfile.raise_for_status() - with open(jarFilepath, 'wb') as f: + with open(jar_path, 'wb') as f: for chunk in rfile.iter_content(chunk_size=128): f.write(chunk) # find the latest timestamp in the zip file tstamp = datetime.fromtimestamp(0) - with zipfile.ZipFile(jarFilepath, 'r') as jar: - allinfo = jar.infolist() - for info in allinfo: - tstampNew = datetime(*info.date_time) - if tstampNew > tstamp: - tstamp = tstampNew - legacyInfo = ForgeLegacyInfo() - legacyInfo.releaseTime = tstamp - legacyInfo.sha1 = filehash(jarFilepath, hashlib.sha1) - legacyInfo.sha256 = filehash(jarFilepath, hashlib.sha256) - legacyInfo.size = os.path.getsize(jarFilepath) - legacyinfolist.number[id] = legacyInfo + with zipfile.ZipFile(jar_path, 'r') as jar: + for info in jar.infolist(): + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + legacy_info = ForgeLegacyInfo() + legacy_info.release_time = tstamp + legacy_info.sha1 = filehash(jar_path, hashlib.sha1) + legacy_info.sha256 = filehash(jar_path, hashlib.sha256) + legacy_info.size = os.path.getsize(jar_path) + legacy_info_list.number[key] = legacy_info # only write legacy info if it's missing if not os.path.isfile(LEGACYINFO_PATH): - legacyinfolist.write(LEGACYINFO_PATH) + legacy_info_list.write(LEGACYINFO_PATH) if __name__ == '__main__': -- cgit 0.0.5-2-1-g0f52 From 8ad8ed95cb67e277fc749b75e34eac574ed368a4 Mon Sep 17 00:00:00 2001 From: txtsd Date: Wed, 6 Apr 2022 14:53:16 +0530 Subject: chore: Replace assignments with augmented assignments --- meta/model/forge.py | 2 +- meta/model/mojang.py | 2 +- updateForge.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'meta') diff --git a/meta/model/forge.py b/meta/model/forge.py index 35af76b3ad..2db191b941 100644 --- a/meta/model/forge.py +++ b/meta/model/forge.py @@ -196,7 +196,7 @@ class ForgeVersion: self.changelog_url = None self.long_version = "%s-%s" % (self.mc_version, self.rawVersion) if self.branch is not None: - self.long_version = self.long_version + "-%s" % self.branch + self.long_version += "-%s" % self.branch # this comment's whole purpose is to say this: cringe for classifier, file in entry.files.items(): diff --git a/meta/model/mojang.py b/meta/model/mojang.py index e5ea072acd..468c372ad7 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -92,7 +92,7 @@ class LegacyOverrideEntry(MetaBase): 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 + meta_version.additional_traits += self.additional_traits if legacy: # remove all libraries - they are not needed for legacy diff --git a/updateForge.py b/updateForge.py index 4106bd8a8b..b459e636dc 100755 --- a/updateForge.py +++ b/updateForge.py @@ -87,14 +87,14 @@ def get_single_forge_files_manifest(longversion): pprint(classifier) pprint(extensionObj) print('%s: Skipping missing hash for extension %s:' % (longversion, extension)) - index = index + 1 + index += 1 continue assert type(classifier) == str processedHash = re.sub(r"\W", "", hash) if not len(processedHash) == 32: print('%s: Skipping invalid hash for extension %s:' % (longversion, extension)) pprint(extensionObj) - index = index + 1 + index += 1 continue fileObj = ForgeFile( @@ -104,8 +104,8 @@ def get_single_forge_files_manifest(longversion): ) if count == 0: retDict[classifier] = fileObj - index = index + 1 - count = count + 1 + index += 1 + count += 1 else: print('%s: Multiple objects detected for classifier %s:' % (longversion, classifier)) pprint(extensionObj) -- cgit 0.0.5-2-1-g0f52 From a312e6d5332dda9d715998f51638f2057305255c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 6 Apr 2022 21:13:21 +0200 Subject: refactor: improve compatibleJavaMajors mapping --- meta/model/mojang.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 468c372ad7..d76ff41313 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -8,6 +8,12 @@ from . import MetaBase, MojangArtifactBase, MojangAssets, MojangLibrary, MojangA SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 +DEFAULT_JAVA_MAJOR = 8 # by default we should recommend Java 8 if we don't know better +COMPATIBLE_JAVA_MAPPINGS = { + 16: [17, 18], + 17: [18] +} + ''' Mojang index files look like this: @@ -152,7 +158,7 @@ class MojangVersion(MetaBase): processArguments: Optional[str] minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") minimum_launcher_version: Optional[int] = Field( - alias="minimumLauncherVersion") # TODO: validate validateSupportedMojangVersion + alias="minimumLauncherVersion") release_time: Optional[datetime] = Field(alias="releaseTime") time: Optional[datetime] type: Optional[str] @@ -181,13 +187,15 @@ class MojangVersion(MetaBase): else: raise Exception(f"Unsupported compliance level {self.compliance_level}") + major = DEFAULT_JAVA_MAJOR 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 + compatible_java_majors = [major] + if major in COMPATIBLE_JAVA_MAPPINGS: # add more compatible Java versions, e.g. 16 and 17 both work for MC 1.17 + compatible_java_majors += COMPATIBLE_JAVA_MAPPINGS[major] + + if new_type == "pending": # experiments from upstream are type=pending new_type = "experiment" return MetaVersion( -- cgit 0.0.5-2-1-g0f52 From 4d351a293799926d3d6e104cf97b45eafbd871a5 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 7 Apr 2022 18:49:43 +0200 Subject: refactor: switch quilt to pydantic models --- generateQuilt.py | 198 +++++++++++++++++++++++++-------------------------- meta/common/quilt.py | 17 +++++ updateQuilt.py | 103 ++++++++++++++------------- 3 files changed, 168 insertions(+), 150 deletions(-) create mode 100644 meta/common/quilt.py (limited to 'meta') diff --git a/generateQuilt.py b/generateQuilt.py index ad0e0db3a5..377982fd67 100755 --- a/generateQuilt.py +++ b/generateQuilt.py @@ -1,111 +1,111 @@ -from fabricutil import * +import json +import os -PMC_DIR = os.environ["PMC_DIR"] -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] +from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key +from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT, \ + USE_QUILT_MAPPINGS +from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier +from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses -# TODO: Switch to Quilt Mappings once the time has come -USE_QUILT_MAPPINGS = False +PMC_DIR = polymc_path() +UPSTREAM_DIR = upstream_path() -# turn loader versions into packages -loaderRecommended = [] -loaderVersions = [] -intermediaryRecommended = [] -intermediaryVersions = [] +ensure_component_dir(LOADER_COMPONENT) +ensure_component_dir(INTERMEDIARY_COMPONENT) -def mkdirs(path): - if not os.path.exists(path): - os.makedirs(path) +def load_jar_info(artifact_key) -> FabricJarInfo: + return FabricJarInfo.parse_file(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json")) -mkdirs(PMC_DIR + "/org.quiltmc.quilt-loader") -mkdirs(PMC_DIR + "/org.quiltmc.quilt-mappings") +def load_installer_info(version) -> FabricInstallerDataV1: + return FabricInstallerDataV1.parse_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json")) -def loadJarInfo(mavenKey): - with open(UPSTREAM_DIR + "/quilt/jars/" + mavenKey.replace(":", ".") + ".json", 'r', - encoding='utf-8') as jarInfoFile: - return FabricJarInfo(json.load(jarInfoFile)) +def process_loader_version(entry) -> MetaVersion: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + installer_info = load_installer_info(entry["version"]) + v = MetaVersion(name="Quilt Loader", uid=LOADER_COMPONENT, version=entry["version"]) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid=INTERMEDIARY_COMPONENT)] + v.order = 10 + v.type = "release" + if isinstance(installer_info.main_class, FabricMainClasses): + v.main_class = installer_info.main_class.client + else: + v.main_class = installer_info.main_class + v.libraries = [] + v.libraries.extend(installer_info.libraries.common) + v.libraries.extend(installer_info.libraries.client) + loader_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release") + v.libraries.append(loader_lib) + return v + + +def process_intermediary_version(entry) -> MetaVersion: + minecraft_version = entry["version"].split("+", 2)[0] # version format is like 1.18.2-pre1+build.1 + + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + + v = MetaVersion(name="Quilt Intermediary Mappings", uid=INTERMEDIARY_COMPONENT, version=entry["version"]) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid='net.minecraft', equals=minecraft_version)] + v.order = 11 + v.type = "release" + v.libraries = [] + v.volatile = True + intermediary_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release") + v.libraries.append(intermediary_lib) + return v + + +def main(): + recommended_loader_versions = [] + recommended_intermediary_versions = [] + + with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as f: + loader_version_index = json.load(f) + for entry in loader_version_index: + version = entry["version"] + print(f"Processing loader {version}") + + v = process_loader_version(entry) + + if not recommended_loader_versions: # first (newest) loader is recommended + recommended_loader_versions.append(version) + + v.write(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json")) -def processLoaderVersion(loaderVersion, it, loaderData): - if (len(loaderRecommended) < 1): # TODO figure out actual stable version - loaderRecommended.append(loaderVersion) - versionJarInfo = loadJarInfo(it["maven"]) - version = PolyMCVersionFile(name="Quilt Loader", uid="org.quiltmc.quilt-loader", version=loaderVersion) - version.releaseTime = versionJarInfo.releaseTime if USE_QUILT_MAPPINGS: - version.requires = [DependencyEntry(uid='org.quiltmc.quilt-mappings')] - else: - version.requires = [DependencyEntry(uid='net.fabricmc.intermediary')] - version.order = 10 - version.type = "release" - if isinstance(loaderData.mainClass, dict): - version.mainClass = loaderData.mainClass["client"] - else: - version.mainClass = loaderData.mainClass - version.libraries = [] - version.libraries.extend(loaderData.libraries.common) - version.libraries.extend(loaderData.libraries.client) - loaderLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.quiltmc.org/repository/release") - version.libraries.append(loaderLib) - loaderVersions.append(version) - - -def processIntermediaryVersion(it): - minecraftVersion = it["version"].split("+", 2)[0] # version format is like 1.18.2-pre1+build.1 - - intermediaryRecommended.append(it["version"]) - versionJarInfo = loadJarInfo(it["maven"]) - version = PolyMCVersionFile(name="Quilt Intermediary Mappings", uid="org.quiltmc.quilt-mappings", version=it["version"]) - version.releaseTime = versionJarInfo.releaseTime - version.requires = [DependencyEntry(uid='net.minecraft', equals=minecraftVersion)] - version.order = 11 - version.type = "release" - version.libraries = [] - version.volatile = True - mappingLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.quiltmc.org/repository/release") - version.libraries.append(mappingLib) - intermediaryVersions.append(version) - - -with open(UPSTREAM_DIR + "/quilt/meta-v3/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile: - loaderVersionIndex = json.load(loaderVersionIndexFile) - for it in loaderVersionIndex: - version = it["version"] - with open(UPSTREAM_DIR + "/quilt/loader-installer-json/" + version + ".json", 'r', - encoding='utf-8') as loaderVersionFile: - ldata = json.load(loaderVersionFile) - ldata = FabricInstallerDataV1(ldata) - processLoaderVersion(version, it, ldata) - -if USE_QUILT_MAPPINGS: - with open(UPSTREAM_DIR + "/quilt/meta-v3/quilt-mappings.json", 'r', encoding='utf-8') as intermediaryVersionIndexFile: - intermediaryVersionIndex = json.load(intermediaryVersionIndexFile) - for it in intermediaryVersionIndex: - processIntermediaryVersion(it) - -for version in loaderVersions: - outFilepath = PMC_DIR + "/org.quiltmc.quilt-loader/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) - -sharedData = PolyMCSharedPackageData(uid='org.quiltmc.quilt-loader', name='Quilt Loader') -sharedData.recommended = loaderRecommended -sharedData.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." -sharedData.projectUrl = "https://quiltmc.org" -sharedData.authors = ["Quilt Project"] -sharedData.write() - -if USE_QUILT_MAPPINGS: - for version in intermediaryVersions: - outFilepath = PMC_DIR + "/org.quiltmc.quilt-mappings/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) - - sharedData = PolyMCSharedPackageData(uid='org.quiltmc.quilt-mappings', name='Quilt Intermediary Mappings') - sharedData.recommended = intermediaryRecommended - sharedData.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." - sharedData.projectUrl = "https://quiltmc.org" - sharedData.authors = ["Quilt Project"] - sharedData.write() + with open(os.path.join(UPSTREAM_DIR, META_DIR, "quilt-mappings.json"), 'r', encoding='utf-8') as f: + intermediary_version_index = json.load(f) + for entry in intermediary_version_index: + version = entry["version"] + print(f"Processing intermediary {version}") + + v = process_intermediary_version(entry) + + recommended_intermediary_versions.append(version) # all intermediaries are recommended + + v.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) + + package = MetaPackage(uid=LOADER_COMPONENT, name='Quilt Loader') + package.recommended = recommended_loader_versions + package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." + package.project_url = "https://quiltmc.org/" + package.authors = ["Quilt Project"] + package.write(os.path.join(PMC_DIR, LOADER_COMPONENT, "package.json")) + + package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Quilt Intermediary Mappings') + package.recommended = recommended_intermediary_versions + package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." + package.project_url = "https://quiltmc.org/" + package.authors = ["Quilt Project"] + package.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, "package.json")) + + +if __name__ == '__main__': + main() diff --git a/meta/common/quilt.py b/meta/common/quilt.py new file mode 100644 index 0000000000..6cf4fe0e97 --- /dev/null +++ b/meta/common/quilt.py @@ -0,0 +1,17 @@ +from os.path import join +from .fabric import INTERMEDIARY_COMPONENT as FABRIC_INTERMEDIARY_COMPONENT + +# Right now Quilt recommends using Fabric's intermediary +USE_QUILT_MAPPINGS = False + +BASE_DIR = "quilt" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json") +META_DIR = join(BASE_DIR, "meta-v3") + +LOADER_COMPONENT = "org.quiltmc.quilt-loader" +INTERMEDIARY_COMPONENT = "org.quiltmc.quilt-mappings" + +if not USE_QUILT_MAPPINGS: + INTERMEDIARY_COMPONENT = FABRIC_INTERMEDIARY_COMPONENT diff --git a/updateQuilt.py b/updateQuilt.py index c4f76a9734..c8594fb3ba 100755 --- a/updateQuilt.py +++ b/updateQuilt.py @@ -1,37 +1,41 @@ import hashlib +import json +import os import zipfile +from datetime import datetime import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from fabricutil import * -DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" +from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key +from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR +from meta.common.fabric import DATETIME_FORMAT_HTTP +from meta.model.fabric import FabricJarInfo -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(META_DIR) forever_cache = FileCache('caches/http_cache', forever=True) sess = CacheControl(requests.Session(), forever_cache) -def mkdirs(path): - if not os.path.exists(path): - os.makedirs(path) - - def filehash(filename, hashtype, blocksize=65536): - hash = hashtype() + h = hashtype() with open(filename, "rb") as f: for block in iter(lambda: f.read(blocksize), b""): - hash.update(block) - return hash.hexdigest() + h.update(block) + return h.hexdigest() -def get_maven_url(mavenKey, server, ext): - mavenParts = mavenKey.split(":", 3) - mavenVerUrl = server + mavenParts[0].replace(".", "/") + "/" + mavenParts[1] + "/" + mavenParts[2] + "/" - mavenUrl = mavenVerUrl + mavenParts[1] + "-" + mavenParts[2] + ext - return mavenUrl +def get_maven_url(maven_key, server, ext): + parts = maven_key.split(":", 3) + maven_ver_url = server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext + return maven_url def get_json_file(path, url): @@ -56,12 +60,11 @@ def head_file(url): def get_binary_file(path, url): - with open(path, 'w', encoding='utf-8') as f: + with open(path, 'wb') as f: r = sess.get(url) r.raise_for_status() - with open(path, 'wb') as f: - for chunk in r.iter_content(chunk_size=128): - f.write(chunk) + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) def compute_jar_file(path, url): @@ -70,7 +73,7 @@ def compute_jar_file(path, url): try: # Let's not download a Jar file if we don't need to. headers = head_file(url) - tstamp = datetime.datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) + tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) sha1 = get_plaintext(url + ".sha1") sha256 = get_plaintext(url + ".sha256") size = int(headers["Content-Length"]) @@ -80,11 +83,11 @@ def compute_jar_file(path, url): jar_path = path + ".jar" get_binary_file(jar_path, url) - tstamp = datetime.datetime.fromtimestamp(0) - with zipfile.ZipFile(jar_path, 'r') as jar: + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: allinfo = jar.infolist() for info in allinfo: - tstamp_new = datetime.datetime(*info.date_time) + tstamp_new = datetime(*info.date_time) if tstamp_new > tstamp: tstamp = tstamp_new @@ -92,30 +95,28 @@ def compute_jar_file(path, url): sha256 = filehash(jar_path, hashlib.sha256) size = os.path.getsize(jar_path) - data = FabricJarInfo() - data.releaseTime = tstamp - data.sha1 = sha1 - data.sha256 = sha256 - data.size = size - with open(path + ".json", 'w') as outfile: - json.dump(data.to_json(), outfile, sort_keys=True, indent=4) - - -mkdirs(UPSTREAM_DIR + "/quilt/meta-v3") -mkdirs(UPSTREAM_DIR + "/quilt/loader-installer-json") -mkdirs(UPSTREAM_DIR + "/quilt/jars") - -# get the version list for each component we are interested in -for component in ["quilt-mappings", "loader"]: - index = get_json_file(UPSTREAM_DIR + "/quilt/meta-v3/" + component + ".json", - "https://meta.quiltmc.org/v3/versions/" + component) - for it in index: - jarMavenUrl = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar") - compute_jar_file(UPSTREAM_DIR + "/quilt/jars/" + it["maven"].replace(":", "."), jarMavenUrl) - -# for each loader, download installer JSON file from maven -with open(UPSTREAM_DIR + "/quilt/meta-v3/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile: - loaderVersionIndex = json.load(loaderVersionIndexFile) - for it in loaderVersionIndex: - mavenUrl = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".json") - get_json_file(UPSTREAM_DIR + "/quilt/loader-installer-json/" + it["version"] + ".json", mavenUrl) + data = FabricJarInfo(release_time=tstamp, sha1=sha1, sha256=sha256, size=size) + data.write(path + ".json") + + +def main(): + # get the version list for each component we are interested in + for component in ["quilt-mappings", "loader"]: + index = get_json_file(os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.quiltmc.org/v3/versions/" + component) + for it in index: + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar") + compute_jar_file(os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), jar_maven_url) + + # for each loader, download installer JSON file from maven + with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile: + loader_version_index = json.load(loaderVersionIndexFile) + for it in loader_version_index: + print(f"Downloading installer info for loader {it['version']} ") + maven_url = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".json") + get_json_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), maven_url) + + +if __name__ == '__main__': + main() -- cgit 0.0.5-2-1-g0f52 From 623c5fb19df605c4d8b06905ceaafae65e4dbc96 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 9 Apr 2022 14:56:34 +0200 Subject: refactor: switch Quilt mappings to hashed MojMap --- generateQuilt.py | 6 ++---- meta/common/quilt.py | 2 +- updateQuilt.py | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'meta') diff --git a/generateQuilt.py b/generateQuilt.py index 377982fd67..efee32338c 100755 --- a/generateQuilt.py +++ b/generateQuilt.py @@ -45,13 +45,11 @@ def process_loader_version(entry) -> MetaVersion: def process_intermediary_version(entry) -> MetaVersion: - minecraft_version = entry["version"].split("+", 2)[0] # version format is like 1.18.2-pre1+build.1 - jar_info = load_jar_info(transform_maven_key(entry["maven"])) v = MetaVersion(name="Quilt Intermediary Mappings", uid=INTERMEDIARY_COMPONENT, version=entry["version"]) v.release_time = jar_info.release_time - v.requires = [Dependency(uid='net.minecraft', equals=minecraft_version)] + v.requires = [Dependency(uid='net.minecraft', equals=entry["version"])] v.order = 11 v.type = "release" v.libraries = [] @@ -80,7 +78,7 @@ def main(): v.write(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json")) if USE_QUILT_MAPPINGS: - with open(os.path.join(UPSTREAM_DIR, META_DIR, "quilt-mappings.json"), 'r', encoding='utf-8') as f: + with open(os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), 'r', encoding='utf-8') as f: intermediary_version_index = json.load(f) for entry in intermediary_version_index: version = entry["version"] diff --git a/meta/common/quilt.py b/meta/common/quilt.py index 6cf4fe0e97..6d5f47989e 100644 --- a/meta/common/quilt.py +++ b/meta/common/quilt.py @@ -11,7 +11,7 @@ INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json") META_DIR = join(BASE_DIR, "meta-v3") LOADER_COMPONENT = "org.quiltmc.quilt-loader" -INTERMEDIARY_COMPONENT = "org.quiltmc.quilt-mappings" +INTERMEDIARY_COMPONENT = "org.quiltmc.hashed" if not USE_QUILT_MAPPINGS: INTERMEDIARY_COMPONENT = FABRIC_INTERMEDIARY_COMPONENT diff --git a/updateQuilt.py b/updateQuilt.py index c8594fb3ba..55bb63fdeb 100755 --- a/updateQuilt.py +++ b/updateQuilt.py @@ -101,7 +101,7 @@ def compute_jar_file(path, url): def main(): # get the version list for each component we are interested in - for component in ["quilt-mappings", "loader"]: + for component in ["hashed", "loader"]: index = get_json_file(os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), "https://meta.quiltmc.org/v3/versions/" + component) for it in index: -- cgit 0.0.5-2-1-g0f52 From e823ee4a4b712a49615598e97ad1b08d1c48e0d3 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 22 May 2022 11:29:30 +0200 Subject: fix: fix missing tinyfd in LWJGL 3.2.2 --- generateMojang.py | 9 +- meta/common/mojang.py | 1 + static/mojang/lwjgl-3.2.2.json | 322 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+), 2 deletions(-) create mode 100644 static/mojang/lwjgl-3.2.2.json (limited to 'meta') diff --git a/generateMojang.py b/generateMojang.py index 4d662c4b24..d12c2b566c 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -8,7 +8,7 @@ from typing import Optional from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path from meta.common.mojang import VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, LWJGL_COMPONENT, \ - STATIC_OVERRIDES_FILE, VERSIONS_DIR + STATIC_LWJGL322_FILE, STATIC_OVERRIDES_FILE, VERSIONS_DIR from meta.model import MetaVersion, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ MetaPackage, MojangRules from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, LegacyOverrideIndex @@ -62,7 +62,7 @@ LOG4J_HASHES = { PASS_VARIANTS = [ # "beed62ec1d40ae89d808fe70b83df6bd4b3be81f", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, without workaround "8836c419f90f69a278b97d945a34af165c24ff60", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, with workaround - "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) + "e13abfa8c5f45ae4a7e87e0b388de46066d31a67", # 3.2.2 (2019-06-19 11:44:29+00:00) our fixed version "8e1f89b96c6f583a0e494949c75115ed13412ba1", # 3.2.1 (2019-02-13 16:12:08+00:00) "7ed2372097dbd635f5aef3137711141ce91c4ee9", # 3.1.6 (2018-11-29 13:11:38+00:00) "5a006b7c72a080ac673fff02b259f3127c376655", # 3.1.2 (2018-06-21 12:57:11+00:00) @@ -80,6 +80,7 @@ BAD_VARIANTS = [ "d986df9598fa2bcf4a5baab5edf044548e66d011", # 3.2.2 (2021-12-10 03:36:38+00:00) only linux, windows "4b73fccb9e5264c2068bdbc26f9651429abbf21a", # 3.2.2 (2021-08-25 14:41:57+00:00) only linux, windows "ab463e9ebc6a36abf22f2aa27b219dd372ff5069", # 3.2.2 (2019-07-19 09:25:47+00:00) only linux, windows + "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) fine but replaced by fixed version "8bde129ef334023c365bd7f57512a4bf5e72a378", # 3.2.1 (2019-04-18 11:05:19+00:00) only osx, windows "65b2ce1f2b869bf98b8dd7ec0bc6956967d04811", # 3.1.6 (2019-04-18 11:05:19+00:00) only linux "f04052162b50fa1433f67e1a90bc79466c4ab776", # 2.9.0 (2013-10-21 16:34:47+00:00) only linux, windows @@ -394,6 +395,10 @@ def main(): override.apply_onto_meta_version(v) v.write(out_filename) + # Add our own 3.2.2, which includes the missing tinyfd libraries + lwjgl322 = MetaVersion.parse_file(os.path.join(STATIC_DIR, STATIC_LWJGL322_FILE)) + add_lwjgl_version(lwjglVersionVariants, lwjgl322) + for lwjglVersionVariant in lwjglVersionVariants: decided_variant = None passed_variants = 0 diff --git a/meta/common/mojang.py b/meta/common/mojang.py index 3bf8281942..06821433e1 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -7,6 +7,7 @@ VERSIONS_DIR = join(BASE_DIR, "versions") ASSETS_DIR = join(BASE_DIR, "assets") STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") +STATIC_LWJGL322_FILE = join(BASE_DIR, "lwjgl-3.2.2.json") STATIC_OVERRIDES_FILE = join(BASE_DIR, "minecraft-legacy-override.json") MINECRAFT_COMPONENT = "net.minecraft" diff --git a/static/mojang/lwjgl-3.2.2.json b/static/mojang/lwjgl-3.2.2.json new file mode 100644 index 0000000000..e910729bb8 --- /dev/null +++ b/static/mojang/lwjgl-3.2.2.json @@ -0,0 +1,322 @@ + +{ + "conflicts": [ + { + "uid": "org.lwjgl" + } + ], + "formatVersion": 1, + "libraries": [ + { + "downloads": { + "artifact": { + "sha1": "d3ad4df38e400b8afba1de63f84338809399df5b", + "size": 108907, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "d3ad4df38e400b8afba1de63f84338809399df5b", + "size": 108907, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "0957733f26a6661d4883da0335f7ef46d3bbbd7d", + "size": 159198, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "98f745038d17ac3192fcd01dc44126b03ec1570d", + "size": 67311, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "dc6826d636bf796b33a49038c354210e661bfc17", + "size": 266648, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + }, + { + "downloads": { + "artifact": { + "sha1": "ee8e57a79300f78294576d87c4a587f8c99402e2", + "size": 34848, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "ee8e57a79300f78294576d87c4a587f8c99402e2", + "size": 34848, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "268c08a150347e04e44ba56e359d62c9b78669df", + "size": 156173, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "805f5a10465375ba034b27b72331912fd2846690", + "size": 117127, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "338b25b99da3ba5f441f6492f2ce2a9c608860ed", + "size": 220623, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + }, + { + "downloads": { + "artifact": { + "sha1": "2b772a102b0a11ee5f2109a5b136f4dc7c630827", + "size": 80012, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "2b772a102b0a11ee5f2109a5b136f4dc7c630827", + "size": 80012, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "0364f9f5c3947393083ab5f37a571f5603aadd0b", + "size": 590997, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "a97b6345d5a9ddf889e262bd7ad8eed43b1bb063", + "size": 528006, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "ec20a7d42a2438528fca87e60b1705f1e2339ddb", + "size": 1310102, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + }, + { + "downloads": { + "artifact": { + "sha1": "6ac5bb88b44c43ea195a570aab059f63da004cd8", + "size": 929780, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "6ac5bb88b44c43ea195a570aab059f63da004cd8", + "size": 929780, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "338d33387919cb3f4cdba143c2b738a71ccfda60", + "size": 77392, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "cf4f43e69ee70d8ebfbb6ba93dec9016339e4fdc", + "size": 38989, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "d8dcdc91066cae2d2d8279cb4a9f9f05d9525826", + "size": 170798, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + }, + { + "downloads": { + "artifact": { + "sha1": "3b8e6ebc5851dd3d17e37e5cadce2eff2a429f0f", + "size": 104469, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "3b8e6ebc5851dd3d17e37e5cadce2eff2a429f0f", + "size": 104469, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "172c52e586fecf43f759bc4f70a778c01f6fdcc1", + "size": 203476, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "ee059b129b09fdecbd8595273926ae930bf5a5d7", + "size": 196796, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "811f705cbb29e8ae8d60bdf8fdd38c0c123ad3ef", + "size": 465810, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + }, + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + }, + "classifiers": { + "javadoc": { + "sha1": "ba657a222ee267b75fa81ae5ab29ae29b50f725f", + "size": 368913, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-javadoc.jar" + }, + "natives-linux": { + "sha1": "39e35b161c130635d9c8918ce04e887a30c5b687", + "size": 38804, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "46d0798228b8a28e857a2a0f02310fd6ba2a4eab", + "size": 42136, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "e9115958773644e863332a6a06488d26f9e1fc9f", + "size": 208314, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar" + }, + "sources": { + "sha1": "2fe76dcf2ca02ae0e64ac7c69eb251c09df0e922", + "size": 5034, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-sources.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + }, + { + "downloads": { + "artifact": { + "sha1": "8ad6294407e15780b43e84929c40e4c5e997972e", + "size": 321900, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "8ad6294407e15780b43e84929c40e4c5e997972e", + "size": 321900, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "ae7976827ca2a3741f6b9a843a89bacd637af350", + "size": 124776, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "bbfb75693bdb714c0c69c2c9f9be73d259b43b62", + "size": 48462, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "05359f3aa50d36352815fc662ea73e1c00d22170", + "size": 279593, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + } + ], + "name": "LWJGL 3", + "order": -1, + "releaseTime": "2019-06-19T11:44:29+00:00", + "type": "release", + "uid": "org.lwjgl3", + "version": "3.2.2", + "volatile": true +} -- cgit 0.0.5-2-1-g0f52 From 07b05bd81514f82279d7bd5e2410ccc7c1162adb Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 27 May 2022 13:20:43 +0200 Subject: refactor: remove unused metadata This should reduce the amount of times we would need to download JAR files for Fabric or Quilt --- meta/model/fabric.py | 3 --- updateFabric.py | 20 +++----------------- updateQuilt.py | 20 +++----------------- 3 files changed, 6 insertions(+), 37 deletions(-) (limited to 'meta') diff --git a/meta/model/fabric.py b/meta/model/fabric.py index 3ae557bf85..5cb0e9caab 100644 --- a/meta/model/fabric.py +++ b/meta/model/fabric.py @@ -38,6 +38,3 @@ class FabricInstallerDataV1(MetaBase): class FabricJarInfo(MetaBase): release_time: Optional[datetime] = Field(alias="releaseTime") - size: Optional[int] - sha256: Optional[str] - sha1: Optional[str] diff --git a/updateFabric.py b/updateFabric.py index 539d79ba5b..d61c1730aa 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -1,4 +1,3 @@ -import hashlib import json import os import zipfile @@ -46,12 +45,6 @@ def get_json_file(path, url): return version_json -def get_plaintext(url): - r = sess.get(url) - r.raise_for_status() - return r.text - - def head_file(url): r = sess.head(url) r.raise_for_status() @@ -73,11 +66,8 @@ def compute_jar_file(path, url): # Let's not download a Jar file if we don't need to. headers = head_file(url) tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) - sha1 = get_plaintext(url + ".sha1") - sha256 = get_plaintext(url + ".sha256") - size = int(headers["Content-Length"]) except requests.HTTPError: - # Some older versions don't have a .sha256 file :( + # Just in case something changes in the future print(f"Falling back to downloading jar for {url}") jar_path = path + ".jar" @@ -90,11 +80,7 @@ def compute_jar_file(path, url): if tstamp_new > tstamp: tstamp = tstamp_new - sha1 = filehash(jar_path, hashlib.sha1) - sha256 = filehash(jar_path, hashlib.sha256) - size = os.path.getsize(jar_path) - - data = FabricJarInfo(release_time=tstamp, sha1=sha1, sha256=sha256, size=size) + data = FabricJarInfo(release_time=tstamp) data.write(path + ".json") @@ -112,7 +98,7 @@ def main(): with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) for it in loader_version_index: - print(f"Downloading installer info for loader {it['version']} ") + print(f"Downloading JAR info for loader {it['version']} ") maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") get_json_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), maven_url) diff --git a/updateQuilt.py b/updateQuilt.py index 60b85608d6..4ffc8e510f 100755 --- a/updateQuilt.py +++ b/updateQuilt.py @@ -1,4 +1,3 @@ -import hashlib import json import os import zipfile @@ -47,12 +46,6 @@ def get_json_file(path, url): return version_json -def get_plaintext(url): - r = sess.get(url) - r.raise_for_status() - return r.text - - def head_file(url): r = sess.head(url) r.raise_for_status() @@ -74,11 +67,8 @@ def compute_jar_file(path, url): # Let's not download a Jar file if we don't need to. headers = head_file(url) tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) - sha1 = get_plaintext(url + ".sha1") - sha256 = get_plaintext(url + ".sha256") - size = int(headers["Content-Length"]) except requests.HTTPError: - # Some older versions don't have a .sha256 file :( + # Just in case something changes in the future print(f"Falling back to downloading jar for {url}") jar_path = path + ".jar" @@ -91,11 +81,7 @@ def compute_jar_file(path, url): if tstamp_new > tstamp: tstamp = tstamp_new - sha1 = filehash(jar_path, hashlib.sha1) - sha256 = filehash(jar_path, hashlib.sha256) - size = os.path.getsize(jar_path) - - data = FabricJarInfo(release_time=tstamp, sha1=sha1, sha256=sha256, size=size) + data = FabricJarInfo(release_time=tstamp) data.write(path + ".json") @@ -116,7 +102,7 @@ def main(): with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) for it in loader_version_index: - print(f"Downloading installer info for loader {it['version']} ") + print(f"Downloading JAR info for loader {it['version']} ") maven_url = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".json") get_json_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), maven_url) -- cgit 0.0.5-2-1-g0f52 From 51cdb9b0c449f69488ce951b955c635a5eb8f329 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 22 Jun 2022 20:38:54 +0200 Subject: fix: workaround Mojang forgetting to change all URLs --- meta/common/__init__.py | 8 ++++++++ meta/model/__init__.py | 6 +++++- updateMojang.py | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 4db3c57b61..8e463f8448 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -1,5 +1,6 @@ import os import datetime +from urllib.parse import urlparse def serialize_datetime(dt: datetime.datetime): @@ -41,3 +42,10 @@ def ensure_component_dir(component_id): def transform_maven_key(maven_key: str): return maven_key.replace(":", ".") + +def replace_old_launchermeta_url(url): + o = urlparse(url) + if o.netloc == "launchermeta.mojang.com": + return o._replace(netloc="piston-meta.mojang.com").geturl() + + return url diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 4371814a11..15004b9674 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -4,7 +4,7 @@ from typing import Optional, List, Dict, Any, Iterator import pydantic from pydantic import Field, validator -from ..common import serialize_datetime +from ..common import serialize_datetime, replace_old_launchermeta_url META_FORMAT_VERSION = 1 @@ -144,6 +144,10 @@ class MojangArtifactBase(MetaBase): class MojangAssets(MojangArtifactBase): + @validator("url") + def validate_url(cls, v): + return replace_old_launchermeta_url(v) + id: str totalSize: int diff --git a/updateMojang.py b/updateMojang.py index 9117ee559d..ac11fd449d 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -53,7 +53,7 @@ def fetch_version(path, url): def main(): # get the remote version list - r = sess.get('https://launchermeta.mojang.com/mc/game/version_manifest_v2.json') + r = sess.get('https://piston-meta.mojang.com/mc/game/version_manifest_v2.json') r.raise_for_status() remote_versions = MojangIndexWrap(MojangIndex(**r.json())) -- cgit 0.0.5-2-1-g0f52 From e4eb48cc7ed258618a287beedd0dd7441c701bde Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 26 Jun 2022 12:14:52 +0200 Subject: feat: support osx-arm64 and linux-arm64 --- meta/model/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 15004b9674..81fbf0ad82 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -181,7 +181,7 @@ class MojangLibraryDownloads(MetaBase): class OSRule(MetaBase): @validator("name") def name_must_be_os(cls, v): - assert v in ["osx", "linux", "windows"] + assert v in ["osx", "linux", "windows", "osx-arm64", "linux-arm64"] return v name: str -- cgit 0.0.5-2-1-g0f52 From d5e359508bbec270fe81191b6eb209998559cc20 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 26 Jun 2022 12:15:29 +0200 Subject: refactor: make MojangLibrary name optional In preparation for the library override system --- meta/model/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 81fbf0ad82..b089040ee8 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -210,7 +210,7 @@ class MojangRules(MetaBase): class MojangLibrary(MetaBase): extract: Optional[MojangLibraryExtractRules] - name: GradleSpecifier + name: Optional[GradleSpecifier] downloads: Optional[MojangLibraryDownloads] natives: Optional[Dict[str, str]] rules: Optional[MojangRules] -- cgit 0.0.5-2-1-g0f52 From 75006147ddc166ed3f6f148940018475159bd326 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 26 Jun 2022 12:16:11 +0200 Subject: feat: implement merge function for MetaBase --- meta/common/__init__.py | 19 +++++++++++++++++++ meta/model/__init__.py | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 8e463f8448..ee294f00b3 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -49,3 +49,22 @@ def replace_old_launchermeta_url(url): return o._replace(netloc="piston-meta.mojang.com").geturl() return url + + +def get_all_bases(cls, bases=None): + bases = bases or [] + bases.append(cls) + for c in cls.__bases__: + get_all_bases(c, bases) + return tuple(bases) + + +def merge_dict(base: dict, overlay: dict): + for k, v in base.items(): + if isinstance(v, dict): + merge_dict(v, overlay.setdefault(k, {})) + else: + if k not in overlay: + overlay[k] = v + + return overlay diff --git a/meta/model/__init__.py b/meta/model/__init__.py index b089040ee8..caa0e6d893 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -1,10 +1,11 @@ +import copy from datetime import datetime from typing import Optional, List, Dict, Any, Iterator import pydantic from pydantic import Field, validator -from ..common import serialize_datetime, replace_old_launchermeta_url +from ..common import serialize_datetime, replace_old_launchermeta_url, get_all_bases, merge_dict META_FORMAT_VERSION = 1 @@ -119,6 +120,40 @@ class MetaBase(pydantic.BaseModel): with open(file_path, "w") as f: f.write(self.json()) + def merge(self, other): + """ + Merge other object with self. + - Concatenates lists + - Combines sets + - Merges dictionaries (other takes priority) + - Recurses for all fields that are also MetaBase classes + - Overwrites for any other field type (int, string, ...) + """ + assert type(other) is type(self) + for key, field in self.__fields__.items(): + ours = getattr(self, key) + theirs = getattr(other, key) + if theirs is None: + continue + if ours is None: + setattr(self, key, theirs) + continue + + if isinstance(ours, list): + ours += theirs + elif isinstance(ours, set): + ours |= theirs + elif isinstance(ours, dict): + result = merge_dict(ours, copy.deepcopy(theirs)) + setattr(self, key, result) + elif MetaBase in get_all_bases(field.type_): + ours.merge(theirs) + else: + setattr(self, key, theirs) + + def __hash__(self): + return hash(self.json()) + class Config: allow_population_by_field_name = True -- cgit 0.0.5-2-1-g0f52 From 79ff11d653919b702dcdab20289c2580d19408fb Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 26 Jun 2022 12:16:33 +0200 Subject: feat: add LibraryPatches model --- meta/model/mojang.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index d76ff41313..e99145cc5c 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Optional, List, Dict, Any +from typing import Optional, List, Dict, Any, Iterator from pydantic import validator, Field @@ -14,7 +14,6 @@ COMPATIBLE_JAVA_MAPPINGS = { 17: [18] } - ''' Mojang index files look like this: { @@ -111,6 +110,22 @@ class LegacyOverrideIndex(MetaBase): versions: Dict[str, LegacyOverrideEntry] +class LibraryPatch(MetaBase): + match: List[GradleSpecifier] + override: Optional[Library] + additionalLibraries: Optional[List[Library]] + + +class LibraryPatches(MetaBase): + __root__: List[LibraryPatch] + + def __iter__(self) -> Iterator[LibraryPatch]: + return iter(self.__root__) + + def __getitem__(self, item) -> LibraryPatch: + return self.__root__[item] + + class MojangArguments(MetaBase): game: Optional[List[Any]] # mixture of strings and objects jvm: Optional[List[Any]] -- cgit 0.0.5-2-1-g0f52 From c3b1952a14bc42854c067013713c84e8153d9ebd Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 26 Jun 2022 12:18:46 +0200 Subject: feat: add library patches Co-authored-by: r58Playz Co-authored-by: Victor --- generateMojang.py | 30 +- meta/common/mojang.py | 1 + static/mojang/library-patches.json | 859 +++++++++++++++++++++++++++++++++++++ 3 files changed, 885 insertions(+), 5 deletions(-) create mode 100644 static/mojang/library-patches.json (limited to 'meta') diff --git a/generateMojang.py b/generateMojang.py index fb32fbda2f..39a5f30d8f 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -8,10 +8,10 @@ from typing import Optional from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path from meta.common.mojang import VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, LWJGL_COMPONENT, \ - STATIC_LWJGL322_FILE, STATIC_OVERRIDES_FILE, VERSIONS_DIR + STATIC_LWJGL322_FILE, STATIC_OVERRIDES_FILE, VERSIONS_DIR, LIBRARY_PATCHES_FILE from meta.model import MetaVersion, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ MetaPackage, MojangRules -from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, LegacyOverrideIndex +from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, LegacyOverrideIndex, LibraryPatches APPLY_SPLIT_NATIVES_WORKAROUND = True @@ -181,10 +181,27 @@ def is_macos_only(rules: Optional[MojangRules]): return False -def process_single_variant(lwjgl_variant: MetaVersion): +def patch_library(lib: Library, patches: LibraryPatches): + new_libraries = [] + for patch in patches: + if lib.name in patch.match: + if patch.override: + lib.merge(patch.override) + + if patch.additionalLibraries: + new_libraries += patch.additionalLibraries + return new_libraries + + +def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): lwjgl_version = lwjgl_variant.version v = copy.deepcopy(lwjgl_variant) + new_libraries = [] + for lib in v.libraries: + new_libraries += patch_library(lib, patches) + v.libraries += list(new_libraries) + if lwjgl_version[0] == '2': static_filename = os.path.join(STATIC_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") filename = os.path.join(PMC_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") @@ -216,7 +233,8 @@ def process_single_variant(lwjgl_variant: MetaVersion): v.order = -1 good = True for lib in v.libraries: - if not lib.natives: + # skip libraries without natives or that we patched + if not lib.natives or lib in new_libraries: continue checked_dict = {'linux', 'windows', 'osx'} if not checked_dict.issubset(lib.natives.keys()): @@ -253,6 +271,7 @@ def version_has_split_natives(v: MojangVersion) -> bool: def main(): # get the local version list override_index = LegacyOverrideIndex.parse_file(os.path.join(STATIC_DIR, STATIC_OVERRIDES_FILE)) + library_patches = LibraryPatches.parse_file(os.path.join(STATIC_DIR, LIBRARY_PATCHES_FILE)) found_any_lwjgl3 = False @@ -332,6 +351,7 @@ def main(): downloads=MojangLibraryDownloads(artifact=artifact) )) else: + libs_minecraft += patch_library(lib, library_patches) libs_minecraft.append(lib) if len(buckets) == 1: for key in buckets: @@ -424,7 +444,7 @@ def main(): print("") if decided_variant and passed_variants == 1 and unknown_variants == 0: - process_single_variant(decided_variant.version) + process_single_variant(decided_variant.version, library_patches) else: raise Exception("No variant decided for version %s out of %d possible ones and %d unknown ones." % ( lwjglVersionVariant, passed_variants, unknown_variants)) diff --git a/meta/common/mojang.py b/meta/common/mojang.py index 06821433e1..0b8dc0285e 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -9,6 +9,7 @@ ASSETS_DIR = join(BASE_DIR, "assets") STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") STATIC_LWJGL322_FILE = join(BASE_DIR, "lwjgl-3.2.2.json") STATIC_OVERRIDES_FILE = join(BASE_DIR, "minecraft-legacy-override.json") +LIBRARY_PATCHES_FILE = join(BASE_DIR, "library-patches.json") MINECRAFT_COMPONENT = "net.minecraft" LWJGL_COMPONENT = "org.lwjgl" diff --git a/static/mojang/library-patches.json b/static/mojang/library-patches.json new file mode 100644 index 0000000000..2eac327873 --- /dev/null +++ b/static/mojang/library-patches.json @@ -0,0 +1,859 @@ +[ + { + "_comment": "Add additional library just for osx-arm64. No override needed", + "match": [ + "ca.weblite:java-objc-bridge:1.0.0", + "ca.weblite:java-objc-bridge:1.1.0" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "369a83621e3c65496348491e533cb97fe5f2f37d", + "size": 91947, + "url": "https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar" + } + }, + "name": "ca.weblite:java-objc-bridge:1.1.0", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add additional classifiers for jinput-platform", + "match": [ + "net.java.jinput:jinput-platform:2.0.5" + ], + "override": { + "downloads": { + "classifiers": { + "natives-osx-arm64": { + "sha1": "5189eb40db3087fb11ca063b68fa4f4c20b199dd", + "size": 10031, + "url": "https://github.com/r58Playz/jinput-m1/raw/main/plugins/OSX/bin/jinput-platform-2.0.5.jar" + }, + "natives-linux-arm64": { + "sha1": "5aa2edeb64ddfe117d5985152280b55864ce694a", + "size": 6266, + "url": "https://github.com/r58Playz/lwjgl2-m1/raw/linux-aarch64-built/jinput-platform-2.0.5.jar" + } + } + }, + "natives": { + "linux-arm64": "natives-linux-arm64", + "osx-arm64": "natives-osx-arm64" + } + } + }, + { + "_comment": "Use a newer version on osx-arm64 and linux-arm64", + "match": [ + "com.mojang:text2speech:1.0.10", + "com.mojang:text2speech:1.5", + "com.mojang:text2speech:1.6", + "com.mojang:text2speech:1.7", + "com.mojang:text2speech:1.10.1", + "com.mojang:text2speech:1.10.3", + "com.mojang:text2speech:1.11.2", + "com.mojang:text2speech:1.12.4", + "com.mojang:text2speech:1.13.9" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f378f889797edd7df8d32272c06ca80a1b6b0f58", + "size": 13164, + "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar" + } + }, + "name": "com.mojang:text2speech:1.11.3", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", + "org.lwjgl.lwjgl:lwjgl:2.9.3", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl:2.9.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "697517568c68e78ae0b4544145af031c81082dfe", + "size": 1047168, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar" + } + }, + "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", + "org.lwjgl.lwjgl:lwjgl_util:2.9.3", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", + "size": 173887, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar" + } + }, + "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131017", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.3", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1" + ], + "override": { + "downloads": { + "classifiers": { + "natives-osx-arm64": { + "sha1": "eff546c0b319d6ffc7a835652124c18089c67f36", + "size": 488316, + "url": "https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" + }, + "natives-linux-arm64": { + "sha1": "ba120169db0180f4188ddf4b240668a41f11d35f", + "size": 480907, + "url": "https://github.com/r58Playz/lwjgl2-m1/raw/linux-aarch64-built/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + } + } + }, + "natives": { + "linux-arm64": "natives-linux-arm64", + "osx-arm64": "natives-osx-arm64" + } + } + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl:lwjgl-glfw:3.2.2", + "org.lwjgl:lwjgl-glfw:3.2.1", + "org.lwjgl:lwjgl-glfw:3.1.6", + "org.lwjgl:lwjgl-glfw:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "074ad243761147df0d060fbefc814614d2ff75cc", + "size": 85072, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", + "size": 130128, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "71d793d0a5a42e3dfe78eb882abc2523a2c6b496", + "size": 129076, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw-natives-osx-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.2.2", + "org.lwjgl:lwjgl-jemalloc:3.2.1", + "org.lwjgl:lwjgl-jemalloc:3.1.6", + "org.lwjgl:lwjgl-jemalloc:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "19c7d57e1ab7fee54f35a8615babd5defc355d78", + "size": 156163, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "4fb94224378d3588d52d2beb172f2eeafea2d546", + "size": 36976, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "b0be721188d2e7195798780b1c5fe7eafe8091c1", + "size": 103478, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc-natives-osx-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl:lwjgl-openal:3.2.2", + "org.lwjgl:lwjgl-openal:3.2.1", + "org.lwjgl:lwjgl-openal:3.1.6", + "org.lwjgl:lwjgl-openal:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "948e415b5b2a2c650c25b377a4a9f443b21ce92e", + "size": 469432, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "d48e753d85916fc8a200ccddc709b36e3865cc4e", + "size": 88880, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "6b80fc0b982a0723b141e88859c42d6f71bd723f", + "size": 346131, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal-natives-osx-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl:lwjgl-opengl:3.2.2", + "org.lwjgl:lwjgl-opengl:3.2.1", + "org.lwjgl:lwjgl-opengl:3.1.6", + "org.lwjgl:lwjgl-opengl:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "bd40897077bf7d12f562da898b18ac2c68e1f9d7", + "size": 56109, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "962c2a8d2a8cdd3b89de3d78d766ab5e2133c2f4", + "size": 929233, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "bb575058e0372f515587b5d2d04ff7db185f3ffe", + "size": 41667, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl-natives-osx-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl:lwjgl-stb:3.2.2", + "org.lwjgl:lwjgl-stb:3.2.1", + "org.lwjgl:lwjgl-stb:3.1.6", + "org.lwjgl:lwjgl-stb:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "077efa7d7ea41b32df5c6078e912e724cccd06db", + "size": 202038, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "703e4b533e2542560e9f94d6d8bd148be1c1d572", + "size": 113273, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "98f0ad956c754723ef354d50057cc30417ef376a", + "size": 178409, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb-natives-osx-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.2.2", + "org.lwjgl:lwjgl-tinyfd:3.2.1", + "org.lwjgl:lwjgl-tinyfd:3.1.6", + "org.lwjgl:lwjgl-tinyfd:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "37c744ca289b5d7ae155d79e39029488b3254e5b", + "size": 37893, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "1203660b3131cbb8681b17ce6437412545be95e0", + "size": 6802, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "015b931a2daba8f0c317d84c9d14e8e98ae56e0c", + "size": 41384, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd-natives-osx-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64 and linux-arm64", + "match": [ + "org.lwjgl:lwjgl:3.2.2", + "org.lwjgl:lwjgl:3.2.1", + "org.lwjgl:lwjgl:3.1.6", + "org.lwjgl:lwjgl:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "360899386df83d6a8407844a94478607af937f97", + "size": 318833, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "612efd57d12b2e48e554858eb35e7e2eb46ebb4c", + "size": 87121, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.2.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8e664dd69ad7bbcf2053da23efc7848e39e498db", + "size": 719038, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "984df31fadaab86838877b112e5b4e4f68a00ccf", + "size": 42693, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-natives-osx-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.2.2", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + } +] -- cgit 0.0.5-2-1-g0f52 From eba932312d09604c32ef2d8fc09f15daa924ade5 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 29 Jun 2022 00:07:06 +0200 Subject: refactor: patch tinyfd in LWJGL 3.2.2 When we have this cool patching mechanism, we could just use it to patch our existing LWJGL, instead of providing a static one --- generateMojang.py | 42 +++-- meta/common/mojang.py | 1 - meta/model/mojang.py | 4 + static/mojang/library-patches.json | 51 ++++++ static/mojang/lwjgl-3.2.2.json | 322 ------------------------------------- 5 files changed, 74 insertions(+), 346 deletions(-) delete mode 100644 static/mojang/lwjgl-3.2.2.json (limited to 'meta') diff --git a/generateMojang.py b/generateMojang.py index 7d11c30824..e458ca11d7 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -4,11 +4,11 @@ import os from collections import defaultdict, namedtuple from operator import attrgetter from pprint import pprint -from typing import Optional +from typing import Optional, List from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path from meta.common.mojang import VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, LWJGL_COMPONENT, \ - STATIC_LWJGL322_FILE, STATIC_OVERRIDES_FILE, VERSIONS_DIR, LIBRARY_PATCHES_FILE + STATIC_OVERRIDES_FILE, VERSIONS_DIR, LIBRARY_PATCHES_FILE from meta.model import MetaVersion, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ MetaPackage, MojangRules from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, LegacyOverrideIndex, LibraryPatches @@ -62,7 +62,7 @@ LOG4J_HASHES = { PASS_VARIANTS = [ # "beed62ec1d40ae89d808fe70b83df6bd4b3be81f", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, without workaround "8836c419f90f69a278b97d945a34af165c24ff60", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, with workaround - "e13abfa8c5f45ae4a7e87e0b388de46066d31a67", # 3.2.2 (2019-06-19 11:44:29+00:00) our fixed version + "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) will be patched by us, missing tinyfd "8e1f89b96c6f583a0e494949c75115ed13412ba1", # 3.2.1 (2019-02-13 16:12:08+00:00) "7ed2372097dbd635f5aef3137711141ce91c4ee9", # 3.1.6 (2018-11-29 13:11:38+00:00) "5a006b7c72a080ac673fff02b259f3127c376655", # 3.1.2 (2018-06-21 12:57:11+00:00) @@ -81,7 +81,6 @@ BAD_VARIANTS = [ "4b73fccb9e5264c2068bdbc26f9651429abbf21a", # 3.2.2 (2021-08-25 14:41:57+00:00) only linux, windows "090cec3577ecfe438b890b2a9410ea07aa725e16", # 3.2.2 (2021-04-07 14:04:09+00:00) only linux, windows "ab463e9ebc6a36abf22f2aa27b219dd372ff5069", # 3.2.2 (2019-07-19 09:25:47+00:00) only linux, windows - "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) fine but replaced by fixed version "8bde129ef334023c365bd7f57512a4bf5e72a378", # 3.2.1 (2019-04-18 11:05:19+00:00) only osx, windows "65b2ce1f2b869bf98b8dd7ec0bc6956967d04811", # 3.1.6 (2019-04-18 11:05:19+00:00) only linux "f04052162b50fa1433f67e1a90bc79466c4ab776", # 2.9.0 (2013-10-21 16:34:47+00:00) only linux, windows @@ -181,15 +180,24 @@ def is_macos_only(rules: Optional[MojangRules]): return False -def patch_library(lib: Library, patches: LibraryPatches): +def patch_library(lib: Library, patches: LibraryPatches) -> List[Library]: + to_patch = [lib] + new_libraries = [] - for patch in patches: - if lib.name in patch.match: - if patch.override: - lib.merge(patch.override) + while to_patch: + target = to_patch.pop(0) + + for patch in patches: + if patch.applies(target): + if patch.override: + target.merge(patch.override) + + if patch.additionalLibraries: + additional_copy = copy.deepcopy(patch.additionalLibraries) + new_libraries += set(additional_copy) + if patch.patchAdditionalLibraries: + to_patch += additional_copy - if patch.additionalLibraries: - new_libraries += patch.additionalLibraries return new_libraries @@ -203,21 +211,13 @@ def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): v.libraries += list(dict.fromkeys(new_libraries)) if lwjgl_version[0] == '2': - static_filename = os.path.join(STATIC_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") filename = os.path.join(PMC_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") - if os.path.isfile(static_filename): - v = MetaVersion.parse_file(static_filename) - print("LWJGL2 is static:", v.version) v.name = 'LWJGL 2' v.uid = LWJGL_COMPONENT v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] elif lwjgl_version[0] == '3': - static_filename = os.path.join(STATIC_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") filename = os.path.join(PMC_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") - if os.path.isfile(static_filename): - v = MetaVersion.parse_file(static_filename) - print("LWJGL3 is static:", v.version) v.name = 'LWJGL 3' v.uid = LWJGL3_COMPONENT @@ -417,10 +417,6 @@ def main(): override.apply_onto_meta_version(v) v.write(out_filename) - # Add our own 3.2.2, which includes the missing tinyfd libraries - lwjgl322 = MetaVersion.parse_file(os.path.join(STATIC_DIR, STATIC_LWJGL322_FILE)) - add_lwjgl_version(lwjglVersionVariants, lwjgl322) - for lwjglVersionVariant in lwjglVersionVariants: decided_variant = None passed_variants = 0 diff --git a/meta/common/mojang.py b/meta/common/mojang.py index 0b8dc0285e..a2d39e9f1a 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -7,7 +7,6 @@ VERSIONS_DIR = join(BASE_DIR, "versions") ASSETS_DIR = join(BASE_DIR, "assets") STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") -STATIC_LWJGL322_FILE = join(BASE_DIR, "lwjgl-3.2.2.json") STATIC_OVERRIDES_FILE = join(BASE_DIR, "minecraft-legacy-override.json") LIBRARY_PATCHES_FILE = join(BASE_DIR, "library-patches.json") diff --git a/meta/model/mojang.py b/meta/model/mojang.py index e99145cc5c..65814179da 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -114,6 +114,10 @@ class LibraryPatch(MetaBase): match: List[GradleSpecifier] override: Optional[Library] additionalLibraries: Optional[List[Library]] + patchAdditionalLibraries: bool = Field(False) + + def applies(self, target: Library) -> bool: + return target.name in self.match class LibraryPatches(MetaBase): diff --git a/static/mojang/library-patches.json b/static/mojang/library-patches.json index 2eac327873..baa078992c 100644 --- a/static/mojang/library-patches.json +++ b/static/mojang/library-patches.json @@ -1,4 +1,55 @@ [ + { + "_comment": "Add missing tinyfd to the broken LWJGL 3.2.2 variant", + "match": [ + "org.lwjgl:lwjgl:3.2.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "39e35b161c130635d9c8918ce04e887a30c5b687", + "size": 38804, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "46d0798228b8a28e857a2a0f02310fd6ba2a4eab", + "size": 42136, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "e9115958773644e863332a6a06488d26f9e1fc9f", + "size": 208314, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + } + ], + "patchAdditionalLibraries": true + }, { "_comment": "Add additional library just for osx-arm64. No override needed", "match": [ diff --git a/static/mojang/lwjgl-3.2.2.json b/static/mojang/lwjgl-3.2.2.json deleted file mode 100644 index e910729bb8..0000000000 --- a/static/mojang/lwjgl-3.2.2.json +++ /dev/null @@ -1,322 +0,0 @@ - -{ - "conflicts": [ - { - "uid": "org.lwjgl" - } - ], - "formatVersion": 1, - "libraries": [ - { - "downloads": { - "artifact": { - "sha1": "d3ad4df38e400b8afba1de63f84338809399df5b", - "size": 108907, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "d3ad4df38e400b8afba1de63f84338809399df5b", - "size": 108907, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "0957733f26a6661d4883da0335f7ef46d3bbbd7d", - "size": 159198, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "98f745038d17ac3192fcd01dc44126b03ec1570d", - "size": 67311, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "dc6826d636bf796b33a49038c354210e661bfc17", - "size": 266648, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-windows.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - }, - { - "downloads": { - "artifact": { - "sha1": "ee8e57a79300f78294576d87c4a587f8c99402e2", - "size": 34848, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "ee8e57a79300f78294576d87c4a587f8c99402e2", - "size": 34848, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "268c08a150347e04e44ba56e359d62c9b78669df", - "size": 156173, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "805f5a10465375ba034b27b72331912fd2846690", - "size": 117127, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "338b25b99da3ba5f441f6492f2ce2a9c608860ed", - "size": 220623, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-windows.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - }, - { - "downloads": { - "artifact": { - "sha1": "2b772a102b0a11ee5f2109a5b136f4dc7c630827", - "size": 80012, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "2b772a102b0a11ee5f2109a5b136f4dc7c630827", - "size": 80012, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "0364f9f5c3947393083ab5f37a571f5603aadd0b", - "size": 590997, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "a97b6345d5a9ddf889e262bd7ad8eed43b1bb063", - "size": 528006, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "ec20a7d42a2438528fca87e60b1705f1e2339ddb", - "size": 1310102, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-windows.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-openal:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - }, - { - "downloads": { - "artifact": { - "sha1": "6ac5bb88b44c43ea195a570aab059f63da004cd8", - "size": 929780, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "6ac5bb88b44c43ea195a570aab059f63da004cd8", - "size": 929780, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "338d33387919cb3f4cdba143c2b738a71ccfda60", - "size": 77392, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "cf4f43e69ee70d8ebfbb6ba93dec9016339e4fdc", - "size": 38989, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "d8dcdc91066cae2d2d8279cb4a9f9f05d9525826", - "size": 170798, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-windows.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - }, - { - "downloads": { - "artifact": { - "sha1": "3b8e6ebc5851dd3d17e37e5cadce2eff2a429f0f", - "size": 104469, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "3b8e6ebc5851dd3d17e37e5cadce2eff2a429f0f", - "size": 104469, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "172c52e586fecf43f759bc4f70a778c01f6fdcc1", - "size": 203476, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "ee059b129b09fdecbd8595273926ae930bf5a5d7", - "size": 196796, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "811f705cbb29e8ae8d60bdf8fdd38c0c123ad3ef", - "size": 465810, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-windows.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-stb:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - }, - { - "downloads": { - "artifact": { - "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", - "size": 7092, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", - "size": 7092, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" - }, - "classifiers": { - "javadoc": { - "sha1": "ba657a222ee267b75fa81ae5ab29ae29b50f725f", - "size": 368913, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-javadoc.jar" - }, - "natives-linux": { - "sha1": "39e35b161c130635d9c8918ce04e887a30c5b687", - "size": 38804, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "46d0798228b8a28e857a2a0f02310fd6ba2a4eab", - "size": 42136, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "e9115958773644e863332a6a06488d26f9e1fc9f", - "size": 208314, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar" - }, - "sources": { - "sha1": "2fe76dcf2ca02ae0e64ac7c69eb251c09df0e922", - "size": 5034, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-sources.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - }, - { - "downloads": { - "artifact": { - "sha1": "8ad6294407e15780b43e84929c40e4c5e997972e", - "size": 321900, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "8ad6294407e15780b43e84929c40e4c5e997972e", - "size": 321900, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "ae7976827ca2a3741f6b9a843a89bacd637af350", - "size": 124776, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "bbfb75693bdb714c0c69c2c9f9be73d259b43b62", - "size": 48462, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "05359f3aa50d36352815fc662ea73e1c00d22170", - "size": 279593, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-windows.jar" - } - } - }, - "name": "org.lwjgl:lwjgl:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - } - ], - "name": "LWJGL 3", - "order": -1, - "releaseTime": "2019-06-19T11:44:29+00:00", - "type": "release", - "uid": "org.lwjgl3", - "version": "3.2.2", - "volatile": true -} -- cgit 0.0.5-2-1-g0f52 From 0f88f27853b427913aa95f61ad6ee3a838977519 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 15 Oct 2022 15:47:29 +0200 Subject: fix: add linux-arm32 to supported OS rules Signed-off-by: Sefa Eyeoglu --- meta/model/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index caa0e6d893..58c2a0c021 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -216,7 +216,7 @@ class MojangLibraryDownloads(MetaBase): class OSRule(MetaBase): @validator("name") def name_must_be_os(cls, v): - assert v in ["osx", "linux", "windows", "osx-arm64", "linux-arm64"] + assert v in ["osx", "linux", "windows", "osx-arm64", "linux-arm64", "linux-arm32"] return v name: str -- cgit 0.0.5-2-1-g0f52 From ee9fafc89617f7d8771a18adf43c6b36c3e42abe Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 16 Oct 2022 12:15:36 +0200 Subject: fix: add Java 19 to compatible Javas Signed-off-by: Sefa Eyeoglu --- meta/model/mojang.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 65814179da..15b865dde5 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -10,8 +10,8 @@ SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 DEFAULT_JAVA_MAJOR = 8 # by default we should recommend Java 8 if we don't know better COMPATIBLE_JAVA_MAPPINGS = { - 16: [17, 18], - 17: [18] + 16: [17, 18, 19], + 17: [18, 19] } ''' -- cgit 0.0.5-2-1-g0f52 From 4fdad5137194a61de760b294ed84caa21f7dcf0b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 18 Oct 2022 00:26:47 +0200 Subject: fix: use files.scrumplex.rocks Signed-off-by: Sefa Eyeoglu --- generateMojang.py | 2 +- meta/common/forge.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/generateMojang.py b/generateMojang.py index 1a7df21a7e..aae6164bfb 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -26,7 +26,7 @@ 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.0-beta9-fixed", "https://files.scrumplex.rocks/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) diff --git a/meta/common/forge.py b/meta/common/forge.py index d39249cc0c..a6697300de 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -13,5 +13,5 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" -FORGEWRAPPER_MAVEN = "https://polymc.github.io/files/maven/%s" +FORGEWRAPPER_MAVEN = "https://files.scrumplex.rocks/maven/%s" BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From c6f60ad6772d9617bf548640d183614b545f904b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 18 Oct 2022 11:57:00 +0200 Subject: fix: update files URL Signed-off-by: Sefa Eyeoglu --- generateMojang.py | 2 +- meta/common/forge.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/generateMojang.py b/generateMojang.py index aae6164bfb..2b365a9adb 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -26,7 +26,7 @@ ensure_component_dir(LWJGL3_COMPONENT) def map_log4j_artifact(version): if version == "2.0-beta9": - return "2.0-beta9-fixed", "https://files.scrumplex.rocks/maven/%s" + return "2.0-beta9-fixed", "https://files.prismlauncher.org/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) diff --git a/meta/common/forge.py b/meta/common/forge.py index a6697300de..be626599ff 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -13,5 +13,5 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" -FORGEWRAPPER_MAVEN = "https://files.scrumplex.rocks/maven/%s" +FORGEWRAPPER_MAVEN = "https://files.prismlauncher.org/maven/%s" BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 852b490c0428ff8296ae11abe931c69af734ac57 Mon Sep 17 00:00:00 2001 From: txtsd Date: Thu, 20 Oct 2022 12:09:47 +0530 Subject: feat: Rebrand Signed-off-by: txtsd --- .dockerignore | 2 +- .gitignore | 2 +- README.md | 6 +++--- clone.sh | 4 ++-- config.sh | 6 +++--- docker-compose.yaml | 2 +- generateFabric.py | 12 ++++++------ generateForge.py | 12 ++++++------ generateLiteloader.py | 8 ++++---- generateMojang.py | 16 ++++++++-------- generateQuilt.py | 12 ++++++------ index.py | 16 ++++++++-------- meta/common/__init__.py | 10 +++++----- status.sh | 4 ++-- update.sh | 30 +++++++++++++++--------------- 15 files changed, 71 insertions(+), 71 deletions(-) (limited to 'meta') diff --git a/.dockerignore b/.dockerignore index e56aea5790..e29e962db8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,6 @@ caches/ __pycache__/ public/ -polymc/ +prismlauncher/ upstream/ config/ diff --git a/.gitignore b/.gitignore index a50a8b44ff..7ed1ec8c7c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,5 @@ caches/ .idea/ __pycache__ config_local.sh -polymc +prismlauncher upstream diff --git a/README.md b/README.md index 5c7dacba38..c515e121ce 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# PolyMC Meta -Scripts to generate jsons and jars that PolyMC will access. +# Prism Launcher Meta +Scripts to generate jsons and jars that Prism Launcher will access. ## Deployment It is recommended to use Docker to deploy the environment. @@ -8,7 +8,7 @@ It is recommended to use Docker to deploy the environment. - Make sure it's writable by the container later: `chown -R 1337:1337 .` - Configure `config/config_local.sh` - The defaults should be fine (apart from committer email and name perhaps) -- Put your SSH key (which has push access to meta-upstream and meta-polymc) at `config/deploy.key` +- Put your SSH key (which has push access to meta-upstream and meta-prismlauncher) at `config/deploy.key` - Pull meta- repos: `bash clone.sh` - Customize docker-compose.yaml - Run `docker-compose up -d --build` diff --git a/clone.sh b/clone.sh index 1dfaba5895..00c0896838 100755 --- a/clone.sh +++ b/clone.sh @@ -15,6 +15,6 @@ if [ ! -d "${UPSTREAM_DIR}" ]; then git clone "${UPSTREAM_REPO}" "${UPSTREAM_DIR}" fi -if [ ! -d "${PMC_DIR}" ]; then - git clone "${PMC_REPO}" "${PMC_DIR}" +if [ ! -d "${PL_DIR}" ]; then + git clone "${PL_REPO}" "${PL_DIR}" fi diff --git a/config.sh b/config.sh index 5a85fa5ce3..3c4592ba82 100644 --- a/config.sh +++ b/config.sh @@ -1,7 +1,7 @@ export UPSTREAM_DIR=upstream -export UPSTREAM_REPO=git@github.com:PolyMC/meta-upstream.git -export PMC_DIR=polymc -export PMC_REPO=git@github.com:PolyMC/meta-polymc.git +export UPSTREAM_REPO=git@github.com:PrismLauncher/meta-upstream.git +export PL_DIR=prismlauncher +export PL_REPO=git@github.com:PrismLauncher/meta-prismlauncher.git export BRANCH_master=master export BRANCH_develop=develop export DEPLOY_TO_S3=false diff --git a/docker-compose.yaml b/docker-compose.yaml index 94461752b0..4a5f910269 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,7 +7,7 @@ services: volumes: - "./caches:/app/caches" - "./upstream:/app/upstream" - - "./polymc:/app/polymc" + - "./prismlauncher:/app/prismlauncher" - "./public:/app/public" - "./config:/app/config" restart: unless-stopped diff --git a/generateFabric.py b/generateFabric.py index dc81036ec3..32f97d9c75 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -1,12 +1,12 @@ import json import os -from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key +from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, transform_maven_key from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses -PMC_DIR = polymc_path() +PL_DIR = prismlauncher_path() UPSTREAM_DIR = upstream_path() ensure_component_dir(LOADER_COMPONENT) @@ -72,7 +72,7 @@ def main(): if not recommended_loader_versions: # first (newest) loader is recommended recommended_loader_versions.append(version) - v.write(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(PL_DIR, LOADER_COMPONENT, f"{v.version}.json")) with open(os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), 'r', encoding='utf-8') as f: intermediary_version_index = json.load(f) @@ -84,21 +84,21 @@ def main(): recommended_intermediary_versions.append(version) # all intermediaries are recommended - v.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) package = MetaPackage(uid=LOADER_COMPONENT, name='Fabric Loader') package.recommended = recommended_loader_versions package.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] - package.write(os.path.join(PMC_DIR, LOADER_COMPONENT, "package.json")) + package.write(os.path.join(PL_DIR, LOADER_COMPONENT, "package.json")) package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') package.recommended = recommended_intermediary_versions package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] - package.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, "package.json")) + package.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateForge.py b/generateForge.py index ad7561272c..93c7e9b97b 100755 --- a/generateForge.py +++ b/generateForge.py @@ -5,7 +5,7 @@ from distutils.version import LooseVersion from operator import attrgetter from typing import Collection -from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path +from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, static_path from meta.common.forge import FORGE_COMPONENT, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, \ STATIC_LEGACYINFO_FILE, INSTALLER_INFO_DIR, BAD_VERSIONS, FORGEWRAPPER_MAVEN from meta.common.mojang import MINECRAFT_COMPONENT @@ -15,7 +15,7 @@ from meta.model.forge import ForgeVersion, ForgeInstallerProfile, ForgeLegacyInf ForgeInstallerProfileV2, InstallerInfo, DerivedForgeIndex, ForgeLegacyInfoList from meta.model.mojang import MojangVersion -PMC_DIR = polymc_path() +PL_DIR = prismlauncher_path() UPSTREAM_DIR = upstream_path() STATIC_DIR = static_path() @@ -33,7 +33,7 @@ mc_version_cache = {} def load_mc_version_filter(version: str): if version in mc_version_cache: return mc_version_cache[version] - v = MetaVersion.parse_file(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version}.json")) + v = MetaVersion.parse_file(os.path.join(PL_DIR, MINECRAFT_COMPONENT, f"{version}.json")) libs = set(map(attrgetter("name"), v.libraries)) mc_version_cache[version] = libs return libs @@ -321,7 +321,7 @@ def main(): recommended_versions.append(version.rawVersion) # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json")): + if not os.path.isfile(os.path.join(PL_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json")): eprint("Skipping %s with no corresponding Minecraft version %s" % (key, version.mc_version_sane)) continue @@ -357,7 +357,7 @@ def main(): v = version_from_legacy(legacy_info_list.number[str(build)], version) - v.write(os.path.join(PMC_DIR, FORGE_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(PL_DIR, FORGE_COMPONENT, f"{v.version}.json")) recommended_versions.sort() @@ -365,7 +365,7 @@ def main(): package = MetaPackage(uid=FORGE_COMPONENT, name="Forge", project_url="https://www.minecraftforge.net/forum/") package.recommended = recommended_versions - package.write(os.path.join(PMC_DIR, FORGE_COMPONENT, "package.json")) + package.write(os.path.join(PL_DIR, FORGE_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateLiteloader.py b/generateLiteloader.py index 17882d582b..76fccfd670 100755 --- a/generateLiteloader.py +++ b/generateLiteloader.py @@ -2,13 +2,13 @@ import os from datetime import datetime from typing import List, Tuple, Dict, Optional -from meta.common import ensure_component_dir, polymc_path, upstream_path +from meta.common import ensure_component_dir, prismlauncher_path, upstream_path from meta.common.liteloader import LITELOADER_COMPONENT, VERSIONS_FILE from meta.common.mojang import MINECRAFT_COMPONENT from meta.model import MetaVersion, GradleSpecifier, Library, MetaPackage, Dependency from meta.model.liteloader import LiteloaderIndex, LiteloaderArtefact -PMC_DIR = polymc_path() +PL_DIR = prismlauncher_path() UPSTREAM_DIR = upstream_path() ensure_component_dir(LITELOADER_COMPONENT) @@ -93,7 +93,7 @@ def main(): all_versions, recommended = process_versions(index) for version in all_versions: - version.write(os.path.join(PMC_DIR, LITELOADER_COMPONENT, f"{version.version}.json")) + version.write(os.path.join(PL_DIR, LITELOADER_COMPONENT, f"{version.version}.json")) package = MetaPackage(uid=LITELOADER_COMPONENT, name='LiteLoader', @@ -101,7 +101,7 @@ def main(): project_url=index.meta.url, authors=[index.meta.authors], recommended=recommended) - package.write(os.path.join(PMC_DIR, LITELOADER_COMPONENT, "package.json")) + package.write(os.path.join(PL_DIR, LITELOADER_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateMojang.py b/generateMojang.py index 2b365a9adb..dce4f4186d 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -6,7 +6,7 @@ from operator import attrgetter from pprint import pprint from typing import Optional, List -from meta.common import ensure_component_dir, polymc_path, upstream_path, static_path +from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, static_path from meta.common.mojang import VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, LWJGL_COMPONENT, \ STATIC_OVERRIDES_FILE, VERSIONS_DIR, LIBRARY_PATCHES_FILE from meta.model import MetaVersion, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ @@ -15,7 +15,7 @@ from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, Legac APPLY_SPLIT_NATIVES_WORKAROUND = True -PMC_DIR = polymc_path() +PL_DIR = prismlauncher_path() UPSTREAM_DIR = upstream_path() STATIC_DIR = static_path() @@ -211,13 +211,13 @@ def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): v.libraries += list(dict.fromkeys(new_libraries)) if lwjgl_version[0] == '2': - filename = os.path.join(PMC_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") + filename = os.path.join(PL_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") v.name = 'LWJGL 2' v.uid = LWJGL_COMPONENT v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] elif lwjgl_version[0] == '3': - filename = os.path.join(PMC_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") + filename = os.path.join(PL_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") v.name = 'LWJGL 3' v.uid = LWJGL3_COMPONENT @@ -411,7 +411,7 @@ def main(): # process 1.13 arguments into previous version if not mojang_version.minecraft_arguments and mojang_version.arguments: v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) - out_filename = os.path.join(PMC_DIR, MINECRAFT_COMPONENT, f"{v.version}.json") + out_filename = os.path.join(PL_DIR, MINECRAFT_COMPONENT, f"{v.version}.json") if v.version in override_index.versions: override = override_index.versions[v.version] override.apply_onto_meta_version(v) @@ -448,18 +448,18 @@ def main(): lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name='LWJGL 2') lwjgl_package.recommended = ['2.9.4-nightly-20150209'] - lwjgl_package.write(os.path.join(PMC_DIR, LWJGL_COMPONENT, "package.json")) + lwjgl_package.write(os.path.join(PL_DIR, LWJGL_COMPONENT, "package.json")) if found_any_lwjgl3: lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name='LWJGL 3') lwjgl_package.recommended = ['3.1.2'] - lwjgl_package.write(os.path.join(PMC_DIR, LWJGL3_COMPONENT, "package.json")) + lwjgl_package.write(os.path.join(PL_DIR, LWJGL3_COMPONENT, "package.json")) mojang_index = MojangIndexWrap(MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE))) minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name='Minecraft') minecraft_package.recommended = [mojang_index.latest.release] - minecraft_package.write(os.path.join(PMC_DIR, MINECRAFT_COMPONENT, "package.json")) + minecraft_package.write(os.path.join(PL_DIR, MINECRAFT_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateQuilt.py b/generateQuilt.py index e48573289f..d0563e1930 100755 --- a/generateQuilt.py +++ b/generateQuilt.py @@ -1,13 +1,13 @@ import json import os -from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key +from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, transform_maven_key from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT, \ USE_QUILT_MAPPINGS from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses -PMC_DIR = polymc_path() +PL_DIR = prismlauncher_path() UPSTREAM_DIR = upstream_path() ensure_component_dir(LOADER_COMPONENT) @@ -77,7 +77,7 @@ def main(): if not recommended_loader_versions and should_recommend: # newest stable loader is recommended recommended_loader_versions.append(version) - v.write(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(PL_DIR, LOADER_COMPONENT, f"{v.version}.json")) if USE_QUILT_MAPPINGS: with open(os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), 'r', encoding='utf-8') as f: @@ -90,14 +90,14 @@ def main(): recommended_intermediary_versions.append(version) # all intermediaries are recommended - v.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) package = MetaPackage(uid=LOADER_COMPONENT, name='Quilt Loader') package.recommended = recommended_loader_versions package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." package.project_url = "https://quiltmc.org/" package.authors = ["Quilt Project"] - package.write(os.path.join(PMC_DIR, LOADER_COMPONENT, "package.json")) + package.write(os.path.join(PL_DIR, LOADER_COMPONENT, "package.json")) if USE_QUILT_MAPPINGS: package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Quilt Intermediary Mappings') @@ -105,7 +105,7 @@ def main(): package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." package.project_url = "https://quiltmc.org/" package.authors = ["Quilt Project"] - package.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, "package.json")) + package.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/index.py b/index.py index 8bc71d7ec6..d812e0439e 100755 --- a/index.py +++ b/index.py @@ -2,11 +2,11 @@ import hashlib import os from operator import attrgetter -from meta.common import polymc_path +from meta.common import prismlauncher_path from meta.model import MetaVersion, MetaPackage from meta.model.index import MetaPackageIndex, MetaVersionIndex, MetaVersionIndexEntry, MetaPackageIndexEntry -PMC_DIR = polymc_path() +PL_DIR = prismlauncher_path() # take the hash type (like hashlib.md5) and filename, return hex string of hash @@ -25,11 +25,11 @@ ignore = {"index.json", "package.json", ".git", ".github"} packages = MetaPackageIndex() # walk thorugh all the package folders -for package in sorted(os.listdir(PMC_DIR)): +for package in sorted(os.listdir(PL_DIR)): if package in ignore: continue - sharedData = MetaPackage.parse_file(os.path.join(PMC_DIR, package, "package.json")) + sharedData = MetaPackage.parse_file(os.path.join(PL_DIR, package, "package.json")) recommendedVersions = set() if sharedData.recommended: recommendedVersions = set(sharedData.recommended) @@ -38,12 +38,12 @@ for package in sorted(os.listdir(PMC_DIR)): versionList = MetaVersionIndex(uid=package, name=sharedData.name) # walk through all the versions of the package - for filename in os.listdir(PMC_DIR + "/%s" % package): + for filename in os.listdir(PL_DIR + "/%s" % package): if filename in ignore: continue # parse and hash the version file - filepath = PMC_DIR + "/%s/%s" % (package, filename) + filepath = PL_DIR + "/%s/%s" % (package, filename) filehash = hash_file(hashlib.sha256, filepath) versionFile = MetaVersion.parse_file(filepath) is_recommended = versionFile.version in recommendedVersions @@ -56,7 +56,7 @@ for package in sorted(os.listdir(PMC_DIR)): versionList.versions = sorted(versionList.versions, key=attrgetter('release_time'), reverse=True) # write the version index for the package - outFilePath = PMC_DIR + "/%s/index.json" % package + outFilePath = PL_DIR + "/%s/index.json" % package versionList.write(outFilePath) # insert entry into the package index @@ -67,4 +67,4 @@ for package in sorted(os.listdir(PMC_DIR)): ) packages.packages.append(packageEntry) -packages.write(os.path.join(PMC_DIR, "index.json")) +packages.write(os.path.join(PL_DIR, "index.json")) diff --git a/meta/common/__init__.py b/meta/common/__init__.py index ee294f00b3..04ca0d3cc7 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -10,10 +10,10 @@ def serialize_datetime(dt: datetime.datetime): return dt.isoformat() -def polymc_path(): - if "PMC_DIR" in os.environ: - return os.environ["PMC_DIR"] - return "polymc" +def prismlauncher_path(): + if "PL_DIR" in os.environ: + return os.environ["PL_DIR"] + return "prismlauncher" def upstream_path(): @@ -35,7 +35,7 @@ def ensure_upstream_dir(path): def ensure_component_dir(component_id): - path = os.path.join(polymc_path(), component_id) + path = os.path.join(prismlauncher_path(), component_id) if not os.path.exists(path): os.makedirs(path) diff --git a/status.sh b/status.sh index 6d6c28ec4e..80df1797b2 100755 --- a/status.sh +++ b/status.sh @@ -13,8 +13,8 @@ popd || exit 1 echo -echo "PolyMC:" -pushd "${PMC_DIR}" || exit 1 +echo "PrismLauncher:" +pushd "${PL_DIR}" || exit 1 git status popd || exit 1 echo diff --git a/update.sh b/update.sh index 93d049e753..bc05a7674f 100755 --- a/update.sh +++ b/update.sh @@ -22,7 +22,7 @@ function fail_in { } function fail_out { - polymc_git reset --hard HEAD + prismlauncher_git reset --hard HEAD exit 1 } @@ -30,8 +30,8 @@ function upstream_git { git -C "${BASEDIR}/${UPSTREAM_DIR}" "$@" } -function polymc_git { - git -C "${BASEDIR}/${PMC_DIR}" "$@" +function prismlauncher_git { + git -C "${BASEDIR}/${PL_DIR}" "$@" } # make sure we *could* push to our repo @@ -59,8 +59,8 @@ if [ "${DEPLOY_TO_GIT}" = true ] ; then fi fi -polymc_git reset --hard HEAD || exit 1 -polymc_git checkout "${BRANCH}" || exit 1 +prismlauncher_git reset --hard HEAD || exit 1 +prismlauncher_git checkout "${BRANCH}" || exit 1 python generateMojang.py || fail_out python generateForge.py || fail_out @@ -70,15 +70,15 @@ python generateLiteloader.py || fail_out python index.py || fail_out if [ "${DEPLOY_TO_GIT}" = true ] ; then - polymc_git add index.json org.lwjgl/* org.lwjgl3/* net.minecraft/* || fail_out - polymc_git add net.minecraftforge/* || fail_out - polymc_git add net.fabricmc.fabric-loader/* net.fabricmc.intermediary/* || fail_out - polymc_git add org.quiltmc.quilt-loader/* || fail_out # TODO: add Quilt hashed, once it is actually used - polymc_git add com.mumfrey.liteloader/* || fail_out - - if ! polymc_git diff --cached --exit-code ; then - polymc_git commit -a -m "Update ${currentDate}" || fail_out - polymc_git push || exit 1 + prismlauncher_git add index.json org.lwjgl/* org.lwjgl3/* net.minecraft/* || fail_out + prismlauncher_git add net.minecraftforge/* || fail_out + prismlauncher_git add net.fabricmc.fabric-loader/* net.fabricmc.intermediary/* || fail_out + prismlauncher_git add org.quiltmc.quilt-loader/* || fail_out # TODO: add Quilt hashed, once it is actually used + prismlauncher_git add com.mumfrey.liteloader/* || fail_out + + if ! prismlauncher_git diff --cached --exit-code ; then + prismlauncher_git commit -a -m "Update ${currentDate}" || fail_out + prismlauncher_git push || exit 1 fi fi @@ -86,7 +86,7 @@ if [ "${DEPLOY_TO_FOLDER}" = true ] ; then DEPLOY_FOLDER_var="DEPLOY_FOLDER_$MODE" DEPLOY_FOLDER="${!DEPLOY_FOLDER_var}" echo "Deploying to ${DEPLOY_FOLDER}" - rsync -rvog --chown="${DEPLOY_FOLDER_USER}:${DEPLOY_FOLDER_GROUP}" --exclude=.git "${BASEDIR}/${PMC_DIR}/" "${DEPLOY_FOLDER}" + rsync -rvog --chown="${DEPLOY_FOLDER_USER}:${DEPLOY_FOLDER_GROUP}" --exclude=.git "${BASEDIR}/${PL_DIR}/" "${DEPLOY_FOLDER}" fi exit 0 -- cgit 0.0.5-2-1-g0f52 From e56756b32d02c50fa9eae435f3f2bfc854ee5e74 Mon Sep 17 00:00:00 2001 From: txtsd Date: Thu, 20 Oct 2022 12:18:02 +0530 Subject: fix: Grammar and typos Signed-off-by: txtsd --- README.md | 2 +- generateForge.py | 2 +- generateQuilt.py | 2 +- index.py | 2 +- meta/model/mojang.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'meta') diff --git a/README.md b/README.md index c515e121ce..c8c17d5b3e 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,5 @@ It is recommended to use Docker to deploy the environment. - Observe Cron logs using `docker-compose logs -f` (Runs hourly by default) - (Optional) Run once to fill caches: `docker-compose run meta update` -For local development you can also use `docker-compose.local.yaml`. By default it uses `UID=1000` and `GID=1000`. +For local development you can also use `docker-compose.local.yaml`. By default, it uses `UID=1000` and `GID=1000`. Make sure it's the same as your host instance. diff --git a/generateForge.py b/generateForge.py index 93c7e9b97b..02d237fc88 100755 --- a/generateForge.py +++ b/generateForge.py @@ -26,7 +26,7 @@ def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) -# Contruct a set of libraries out of a Minecraft version file, for filtering. +# Construct a set of libraries out of a Minecraft version file, for filtering. mc_version_cache = {} diff --git a/generateQuilt.py b/generateQuilt.py index d0563e1930..8ded782a79 100755 --- a/generateQuilt.py +++ b/generateQuilt.py @@ -23,7 +23,7 @@ def load_installer_info(version) -> FabricInstallerDataV1: def process_loader_version(entry) -> (MetaVersion, bool): - should_recommend = "-" not in entry["version"] # dont recommend pre releases as per SemVer + should_recommend = "-" not in entry["version"] # Don't recommend pre releases as per SemVer jar_info = load_jar_info(transform_maven_key(entry["maven"])) installer_info = load_installer_info(entry["version"]) diff --git a/index.py b/index.py index d812e0439e..8327e6ecb7 100755 --- a/index.py +++ b/index.py @@ -24,7 +24,7 @@ ignore = {"index.json", "package.json", ".git", ".github"} # initialize output structures - package list level packages = MetaPackageIndex() -# walk thorugh all the package folders +# walk through all the package folders for package in sorted(os.listdir(PL_DIR)): if package in ignore: continue diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 15b865dde5..f3a0771d4d 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -8,7 +8,7 @@ from . import MetaBase, MojangArtifactBase, MojangAssets, MojangLibrary, MojangA SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 -DEFAULT_JAVA_MAJOR = 8 # by default we should recommend Java 8 if we don't know better +DEFAULT_JAVA_MAJOR = 8 # By default, we should recommend Java 8 if we don't know better COMPATIBLE_JAVA_MAPPINGS = { 16: [17, 18, 19], 17: [18, 19] -- cgit 0.0.5-2-1-g0f52 From 3b62dad3ee9e192f2863ea990eedc59efea16bad Mon Sep 17 00:00:00 2001 From: txtsd Date: Thu, 20 Oct 2022 12:22:26 +0530 Subject: chore: Fix PEP8: E302 Signed-off-by: txtsd --- meta/common/__init__.py | 1 + 1 file changed, 1 insertion(+) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 04ca0d3cc7..c0bb11d476 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -43,6 +43,7 @@ def ensure_component_dir(component_id): def transform_maven_key(maven_key: str): return maven_key.replace(":", ".") + def replace_old_launchermeta_url(url): o = urlparse(url) if o.netloc == "launchermeta.mojang.com": -- cgit 0.0.5-2-1-g0f52 From fb056cdac1e352b2cf97d61f725c3c3e0a2b1f98 Mon Sep 17 00:00:00 2001 From: txtsd Date: Thu, 20 Oct 2022 13:21:55 +0530 Subject: feat: Agnostify launcher references Signed-off-by: txtsd --- .dockerignore | 2 +- .gitignore | 2 +- README.md | 2 +- clone.sh | 4 ++-- config.sh | 4 ++-- docker-compose.yaml | 2 +- generateFabric.py | 12 ++++++------ generateForge.py | 12 ++++++------ generateLiteloader.py | 8 ++++---- generateMojang.py | 18 +++++++++--------- generateQuilt.py | 12 ++++++------ index.py | 16 ++++++++-------- meta/common/__init__.py | 10 +++++----- meta/common/forge.py | 2 +- status.sh | 2 +- update.sh | 30 +++++++++++++++--------------- 16 files changed, 69 insertions(+), 69 deletions(-) (limited to 'meta') diff --git a/.dockerignore b/.dockerignore index e29e962db8..373630e9e5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,6 @@ caches/ __pycache__/ public/ -prismlauncher/ +launcher/ upstream/ config/ diff --git a/.gitignore b/.gitignore index b13aa67b7b..c413caa35d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,5 @@ caches/ !caches/*/.keep __pycache__ config_local.sh -prismlauncher +launcher upstream diff --git a/README.md b/README.md index c8c17d5b3e..352fe34b4b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ It is recommended to use Docker to deploy the environment. - Make sure it's writable by the container later: `chown -R 1337:1337 .` - Configure `config/config_local.sh` - The defaults should be fine (apart from committer email and name perhaps) -- Put your SSH key (which has push access to meta-upstream and meta-prismlauncher) at `config/deploy.key` +- Put your SSH key (which has push access to meta-upstream and meta-launcher) at `config/deploy.key` - Pull meta- repos: `bash clone.sh` - Customize docker-compose.yaml - Run `docker-compose up -d --build` diff --git a/clone.sh b/clone.sh index 00c0896838..350a9b5e8a 100755 --- a/clone.sh +++ b/clone.sh @@ -15,6 +15,6 @@ if [ ! -d "${UPSTREAM_DIR}" ]; then git clone "${UPSTREAM_REPO}" "${UPSTREAM_DIR}" fi -if [ ! -d "${PL_DIR}" ]; then - git clone "${PL_REPO}" "${PL_DIR}" +if [ ! -d "${LAUNCHER_DIR}" ]; then + git clone "${LAUNCHER_REPO}" "${LAUNCHER_DIR}" fi diff --git a/config.sh b/config.sh index 3c4592ba82..49c3b66f12 100644 --- a/config.sh +++ b/config.sh @@ -1,7 +1,7 @@ export UPSTREAM_DIR=upstream export UPSTREAM_REPO=git@github.com:PrismLauncher/meta-upstream.git -export PL_DIR=prismlauncher -export PL_REPO=git@github.com:PrismLauncher/meta-prismlauncher.git +export LAUNCHER_DIR=launcher +export LAUNCHER_REPO=git@github.com:PrismLauncher/meta-launcher.git export BRANCH_master=master export BRANCH_develop=develop export DEPLOY_TO_S3=false diff --git a/docker-compose.yaml b/docker-compose.yaml index 4a5f910269..f15ea051f4 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,7 +7,7 @@ services: volumes: - "./caches:/app/caches" - "./upstream:/app/upstream" - - "./prismlauncher:/app/prismlauncher" + - "./launcher:/app/launcher" - "./public:/app/public" - "./config:/app/config" restart: unless-stopped diff --git a/generateFabric.py b/generateFabric.py index 32f97d9c75..531f9f2e54 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -1,12 +1,12 @@ import json import os -from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, transform_maven_key +from meta.common import ensure_component_dir, launcher_path, upstream_path, transform_maven_key from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses -PL_DIR = prismlauncher_path() +LAUNCHER_DIR = launcher_path() UPSTREAM_DIR = upstream_path() ensure_component_dir(LOADER_COMPONENT) @@ -72,7 +72,7 @@ def main(): if not recommended_loader_versions: # first (newest) loader is recommended recommended_loader_versions.append(version) - v.write(os.path.join(PL_DIR, LOADER_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) with open(os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), 'r', encoding='utf-8') as f: intermediary_version_index = json.load(f) @@ -84,21 +84,21 @@ def main(): recommended_intermediary_versions.append(version) # all intermediaries are recommended - v.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) package = MetaPackage(uid=LOADER_COMPONENT, name='Fabric Loader') package.recommended = recommended_loader_versions package.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] - package.write(os.path.join(PL_DIR, LOADER_COMPONENT, "package.json")) + package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') package.recommended = recommended_intermediary_versions package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] - package.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, "package.json")) + package.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateForge.py b/generateForge.py index 02d237fc88..e6bca2534b 100755 --- a/generateForge.py +++ b/generateForge.py @@ -5,7 +5,7 @@ from distutils.version import LooseVersion from operator import attrgetter from typing import Collection -from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, static_path +from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path from meta.common.forge import FORGE_COMPONENT, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, \ STATIC_LEGACYINFO_FILE, INSTALLER_INFO_DIR, BAD_VERSIONS, FORGEWRAPPER_MAVEN from meta.common.mojang import MINECRAFT_COMPONENT @@ -15,7 +15,7 @@ from meta.model.forge import ForgeVersion, ForgeInstallerProfile, ForgeLegacyInf ForgeInstallerProfileV2, InstallerInfo, DerivedForgeIndex, ForgeLegacyInfoList from meta.model.mojang import MojangVersion -PL_DIR = prismlauncher_path() +LAUNCHER_DIR = launcher_path() UPSTREAM_DIR = upstream_path() STATIC_DIR = static_path() @@ -33,7 +33,7 @@ mc_version_cache = {} def load_mc_version_filter(version: str): if version in mc_version_cache: return mc_version_cache[version] - v = MetaVersion.parse_file(os.path.join(PL_DIR, MINECRAFT_COMPONENT, f"{version}.json")) + v = MetaVersion.parse_file(os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json")) libs = set(map(attrgetter("name"), v.libraries)) mc_version_cache[version] = libs return libs @@ -321,7 +321,7 @@ def main(): recommended_versions.append(version.rawVersion) # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile(os.path.join(PL_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json")): + if not os.path.isfile(os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json")): eprint("Skipping %s with no corresponding Minecraft version %s" % (key, version.mc_version_sane)) continue @@ -357,7 +357,7 @@ def main(): v = version_from_legacy(legacy_info_list.number[str(build)], version) - v.write(os.path.join(PL_DIR, FORGE_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, f"{v.version}.json")) recommended_versions.sort() @@ -365,7 +365,7 @@ def main(): package = MetaPackage(uid=FORGE_COMPONENT, name="Forge", project_url="https://www.minecraftforge.net/forum/") package.recommended = recommended_versions - package.write(os.path.join(PL_DIR, FORGE_COMPONENT, "package.json")) + package.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateLiteloader.py b/generateLiteloader.py index 76fccfd670..9f730da1c2 100755 --- a/generateLiteloader.py +++ b/generateLiteloader.py @@ -2,13 +2,13 @@ import os from datetime import datetime from typing import List, Tuple, Dict, Optional -from meta.common import ensure_component_dir, prismlauncher_path, upstream_path +from meta.common import ensure_component_dir, launcher_path, upstream_path from meta.common.liteloader import LITELOADER_COMPONENT, VERSIONS_FILE from meta.common.mojang import MINECRAFT_COMPONENT from meta.model import MetaVersion, GradleSpecifier, Library, MetaPackage, Dependency from meta.model.liteloader import LiteloaderIndex, LiteloaderArtefact -PL_DIR = prismlauncher_path() +LAUNCHER_DIR = launcher_path() UPSTREAM_DIR = upstream_path() ensure_component_dir(LITELOADER_COMPONENT) @@ -93,7 +93,7 @@ def main(): all_versions, recommended = process_versions(index) for version in all_versions: - version.write(os.path.join(PL_DIR, LITELOADER_COMPONENT, f"{version.version}.json")) + version.write(os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, f"{version.version}.json")) package = MetaPackage(uid=LITELOADER_COMPONENT, name='LiteLoader', @@ -101,7 +101,7 @@ def main(): project_url=index.meta.url, authors=[index.meta.authors], recommended=recommended) - package.write(os.path.join(PL_DIR, LITELOADER_COMPONENT, "package.json")) + package.write(os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateMojang.py b/generateMojang.py index dce4f4186d..b82517540b 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -6,7 +6,7 @@ from operator import attrgetter from pprint import pprint from typing import Optional, List -from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, static_path +from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path from meta.common.mojang import VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, LWJGL_COMPONENT, \ STATIC_OVERRIDES_FILE, VERSIONS_DIR, LIBRARY_PATCHES_FILE from meta.model import MetaVersion, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ @@ -15,7 +15,7 @@ from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, Legac APPLY_SPLIT_NATIVES_WORKAROUND = True -PL_DIR = prismlauncher_path() +LAUNCHER_DIR = launcher_path() UPSTREAM_DIR = upstream_path() STATIC_DIR = static_path() @@ -26,7 +26,7 @@ ensure_component_dir(LWJGL3_COMPONENT) def map_log4j_artifact(version): if version == "2.0-beta9": - return "2.0-beta9-fixed", "https://files.prismlauncher.org/maven/%s" + return "2.0-beta9-fixed", "https://files.launcher.org/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) @@ -211,13 +211,13 @@ def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): v.libraries += list(dict.fromkeys(new_libraries)) if lwjgl_version[0] == '2': - filename = os.path.join(PL_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") + filename = os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") v.name = 'LWJGL 2' v.uid = LWJGL_COMPONENT v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] elif lwjgl_version[0] == '3': - filename = os.path.join(PL_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") + filename = os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") v.name = 'LWJGL 3' v.uid = LWJGL3_COMPONENT @@ -411,7 +411,7 @@ def main(): # process 1.13 arguments into previous version if not mojang_version.minecraft_arguments and mojang_version.arguments: v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) - out_filename = os.path.join(PL_DIR, MINECRAFT_COMPONENT, f"{v.version}.json") + out_filename = os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{v.version}.json") if v.version in override_index.versions: override = override_index.versions[v.version] override.apply_onto_meta_version(v) @@ -448,18 +448,18 @@ def main(): lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name='LWJGL 2') lwjgl_package.recommended = ['2.9.4-nightly-20150209'] - lwjgl_package.write(os.path.join(PL_DIR, LWJGL_COMPONENT, "package.json")) + lwjgl_package.write(os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, "package.json")) if found_any_lwjgl3: lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name='LWJGL 3') lwjgl_package.recommended = ['3.1.2'] - lwjgl_package.write(os.path.join(PL_DIR, LWJGL3_COMPONENT, "package.json")) + lwjgl_package.write(os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, "package.json")) mojang_index = MojangIndexWrap(MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE))) minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name='Minecraft') minecraft_package.recommended = [mojang_index.latest.release] - minecraft_package.write(os.path.join(PL_DIR, MINECRAFT_COMPONENT, "package.json")) + minecraft_package.write(os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/generateQuilt.py b/generateQuilt.py index 8ded782a79..e628dac944 100755 --- a/generateQuilt.py +++ b/generateQuilt.py @@ -1,13 +1,13 @@ import json import os -from meta.common import ensure_component_dir, prismlauncher_path, upstream_path, transform_maven_key +from meta.common import ensure_component_dir, launcher_path, upstream_path, transform_maven_key from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT, \ USE_QUILT_MAPPINGS from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses -PL_DIR = prismlauncher_path() +LAUNCHER_DIR = launcher_path() UPSTREAM_DIR = upstream_path() ensure_component_dir(LOADER_COMPONENT) @@ -77,7 +77,7 @@ def main(): if not recommended_loader_versions and should_recommend: # newest stable loader is recommended recommended_loader_versions.append(version) - v.write(os.path.join(PL_DIR, LOADER_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) if USE_QUILT_MAPPINGS: with open(os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), 'r', encoding='utf-8') as f: @@ -90,14 +90,14 @@ def main(): recommended_intermediary_versions.append(version) # all intermediaries are recommended - v.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) + v.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) package = MetaPackage(uid=LOADER_COMPONENT, name='Quilt Loader') package.recommended = recommended_loader_versions package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." package.project_url = "https://quiltmc.org/" package.authors = ["Quilt Project"] - package.write(os.path.join(PL_DIR, LOADER_COMPONENT, "package.json")) + package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) if USE_QUILT_MAPPINGS: package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Quilt Intermediary Mappings') @@ -105,7 +105,7 @@ def main(): package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." package.project_url = "https://quiltmc.org/" package.authors = ["Quilt Project"] - package.write(os.path.join(PL_DIR, INTERMEDIARY_COMPONENT, "package.json")) + package.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json")) if __name__ == '__main__': diff --git a/index.py b/index.py index 8327e6ecb7..00c7b54671 100755 --- a/index.py +++ b/index.py @@ -2,11 +2,11 @@ import hashlib import os from operator import attrgetter -from meta.common import prismlauncher_path +from meta.common import launcher_path from meta.model import MetaVersion, MetaPackage from meta.model.index import MetaPackageIndex, MetaVersionIndex, MetaVersionIndexEntry, MetaPackageIndexEntry -PL_DIR = prismlauncher_path() +LAUNCHER_DIR = launcher_path() # take the hash type (like hashlib.md5) and filename, return hex string of hash @@ -25,11 +25,11 @@ ignore = {"index.json", "package.json", ".git", ".github"} packages = MetaPackageIndex() # walk through all the package folders -for package in sorted(os.listdir(PL_DIR)): +for package in sorted(os.listdir(LAUNCHER_DIR)): if package in ignore: continue - sharedData = MetaPackage.parse_file(os.path.join(PL_DIR, package, "package.json")) + sharedData = MetaPackage.parse_file(os.path.join(LAUNCHER_DIR, package, "package.json")) recommendedVersions = set() if sharedData.recommended: recommendedVersions = set(sharedData.recommended) @@ -38,12 +38,12 @@ for package in sorted(os.listdir(PL_DIR)): versionList = MetaVersionIndex(uid=package, name=sharedData.name) # walk through all the versions of the package - for filename in os.listdir(PL_DIR + "/%s" % package): + for filename in os.listdir(LAUNCHER_DIR + "/%s" % package): if filename in ignore: continue # parse and hash the version file - filepath = PL_DIR + "/%s/%s" % (package, filename) + filepath = LAUNCHER_DIR + "/%s/%s" % (package, filename) filehash = hash_file(hashlib.sha256, filepath) versionFile = MetaVersion.parse_file(filepath) is_recommended = versionFile.version in recommendedVersions @@ -56,7 +56,7 @@ for package in sorted(os.listdir(PL_DIR)): versionList.versions = sorted(versionList.versions, key=attrgetter('release_time'), reverse=True) # write the version index for the package - outFilePath = PL_DIR + "/%s/index.json" % package + outFilePath = LAUNCHER_DIR + "/%s/index.json" % package versionList.write(outFilePath) # insert entry into the package index @@ -67,4 +67,4 @@ for package in sorted(os.listdir(PL_DIR)): ) packages.packages.append(packageEntry) -packages.write(os.path.join(PL_DIR, "index.json")) +packages.write(os.path.join(LAUNCHER_DIR, "index.json")) diff --git a/meta/common/__init__.py b/meta/common/__init__.py index c0bb11d476..e3080ea819 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -10,10 +10,10 @@ def serialize_datetime(dt: datetime.datetime): return dt.isoformat() -def prismlauncher_path(): - if "PL_DIR" in os.environ: - return os.environ["PL_DIR"] - return "prismlauncher" +def launcher_path(): + if "LAUNCHER_DIR" in os.environ: + return os.environ["LAUNCHER_DIR"] + return "launcher" def upstream_path(): @@ -35,7 +35,7 @@ def ensure_upstream_dir(path): def ensure_component_dir(component_id): - path = os.path.join(prismlauncher_path(), component_id) + path = os.path.join(launcher_path(), component_id) if not os.path.exists(path): os.makedirs(path) diff --git a/meta/common/forge.py b/meta/common/forge.py index be626599ff..abb411b435 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -13,5 +13,5 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" -FORGEWRAPPER_MAVEN = "https://files.prismlauncher.org/maven/%s" +FORGEWRAPPER_MAVEN = "https://files.launcher.org/maven/%s" BAD_VERSIONS = ["1.12.2-14.23.5.2851"] diff --git a/status.sh b/status.sh index 80df1797b2..4f04e6a99e 100755 --- a/status.sh +++ b/status.sh @@ -14,7 +14,7 @@ echo echo "PrismLauncher:" -pushd "${PL_DIR}" || exit 1 +pushd "${LAUNCHER_DIR}" || exit 1 git status popd || exit 1 echo diff --git a/update.sh b/update.sh index bc05a7674f..1ed51bb155 100755 --- a/update.sh +++ b/update.sh @@ -22,7 +22,7 @@ function fail_in { } function fail_out { - prismlauncher_git reset --hard HEAD + launcher_git reset --hard HEAD exit 1 } @@ -30,8 +30,8 @@ function upstream_git { git -C "${BASEDIR}/${UPSTREAM_DIR}" "$@" } -function prismlauncher_git { - git -C "${BASEDIR}/${PL_DIR}" "$@" +function launcher_git { + git -C "${BASEDIR}/${LAUNCHER_DIR}" "$@" } # make sure we *could* push to our repo @@ -59,8 +59,8 @@ if [ "${DEPLOY_TO_GIT}" = true ] ; then fi fi -prismlauncher_git reset --hard HEAD || exit 1 -prismlauncher_git checkout "${BRANCH}" || exit 1 +launcher_git reset --hard HEAD || exit 1 +launcher_git checkout "${BRANCH}" || exit 1 python generateMojang.py || fail_out python generateForge.py || fail_out @@ -70,15 +70,15 @@ python generateLiteloader.py || fail_out python index.py || fail_out if [ "${DEPLOY_TO_GIT}" = true ] ; then - prismlauncher_git add index.json org.lwjgl/* org.lwjgl3/* net.minecraft/* || fail_out - prismlauncher_git add net.minecraftforge/* || fail_out - prismlauncher_git add net.fabricmc.fabric-loader/* net.fabricmc.intermediary/* || fail_out - prismlauncher_git add org.quiltmc.quilt-loader/* || fail_out # TODO: add Quilt hashed, once it is actually used - prismlauncher_git add com.mumfrey.liteloader/* || fail_out - - if ! prismlauncher_git diff --cached --exit-code ; then - prismlauncher_git commit -a -m "Update ${currentDate}" || fail_out - prismlauncher_git push || exit 1 + launcher_git add index.json org.lwjgl/* org.lwjgl3/* net.minecraft/* || fail_out + launcher_git add net.minecraftforge/* || fail_out + launcher_git add net.fabricmc.fabric-loader/* net.fabricmc.intermediary/* || fail_out + launcher_git add org.quiltmc.quilt-loader/* || fail_out # TODO: add Quilt hashed, once it is actually used + launcher_git add com.mumfrey.liteloader/* || fail_out + + if ! launcher_git diff --cached --exit-code ; then + launcher_git commit -a -m "Update ${currentDate}" || fail_out + launcher_git push || exit 1 fi fi @@ -86,7 +86,7 @@ if [ "${DEPLOY_TO_FOLDER}" = true ] ; then DEPLOY_FOLDER_var="DEPLOY_FOLDER_$MODE" DEPLOY_FOLDER="${!DEPLOY_FOLDER_var}" echo "Deploying to ${DEPLOY_FOLDER}" - rsync -rvog --chown="${DEPLOY_FOLDER_USER}:${DEPLOY_FOLDER_GROUP}" --exclude=.git "${BASEDIR}/${PL_DIR}/" "${DEPLOY_FOLDER}" + rsync -rvog --chown="${DEPLOY_FOLDER_USER}:${DEPLOY_FOLDER_GROUP}" --exclude=.git "${BASEDIR}/${LAUNCHER_DIR}/" "${DEPLOY_FOLDER}" fi exit 0 -- cgit 0.0.5-2-1-g0f52 From e0d7321aa6398b8350e4f50f481656756554c756 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 27 Oct 2022 22:12:18 +0200 Subject: feat: add LWJGL 3.3.1 natives for windows-arm64 Signed-off-by: Sefa Eyeoglu --- meta/model/__init__.py | 2 +- static/mojang/library-patches.json | 182 +++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 58c2a0c021..7a6d368c05 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -216,7 +216,7 @@ class MojangLibraryDownloads(MetaBase): class OSRule(MetaBase): @validator("name") def name_must_be_os(cls, v): - assert v in ["osx", "linux", "windows", "osx-arm64", "linux-arm64", "linux-arm32"] + assert v in ["osx", "linux", "windows", "windows-arm64", "osx-arm64", "linux-arm64", "linux-arm32"] return v name: str diff --git a/static/mojang/library-patches.json b/static/mojang/library-patches.json index cac9cd1a3c..71f12d6e8e 100644 --- a/static/mojang/library-patches.json +++ b/static/mojang/library-patches.json @@ -1971,5 +1971,187 @@ ] } ] + }, + { + "_comment": "Add windows-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "beda65ee503443e60aa196d58ed31f8d001dc22a", + "size": 123808, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-glfw/lwjgl-glfw-natives-windows-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add windows-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "cae85c4edb219c88b6a0c26a87955ad98dc9519d", + "size": 114250, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-windows-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add windows-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "40d65f1a7368a2aa47336f9cb69f5a190cf9975a", + "size": 505234, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-openal/lwjgl-openal-natives-windows-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add windows-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "527d78f1e9056aff3ed02ce93019c73c5e8f1721", + "size": 82445, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-opengl/lwjgl-opengl-natives-windows-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add windows-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fde63cdd2605c00636721a6c8b961e41d1f6b247", + "size": 216848, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-stb/lwjgl-stb-natives-windows-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add windows-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "83a5e780df610829ff3a737822b4f931cffecd91", + "size": 109139, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-windows-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add windows-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "0f46cadcf95675908fd3a550d63d9d709cb68998", + "size": 130064, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl/lwjgl-natives-windows-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-windows-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + ] } ] -- cgit 0.0.5-2-1-g0f52 From bd6d8ae35a3940ced7b3ef6851592cbd3a384fbc Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 31 Oct 2022 19:39:27 +0100 Subject: fix: fix invalid forge wrapper URL Signed-off-by: Sefa Eyeoglu --- meta/common/forge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index abb411b435..be626599ff 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -13,5 +13,5 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" -FORGEWRAPPER_MAVEN = "https://files.launcher.org/maven/%s" +FORGEWRAPPER_MAVEN = "https://files.prismlauncher.org/maven/%s" BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From d3a221a40a77ddd9f9366dd444d73433058d7936 Mon Sep 17 00:00:00 2001 From: jopejoe1 Date: Thu, 3 Nov 2022 00:21:41 +0100 Subject: Add old snapshots Signed-off-by: Johannes Joens --- meta/common/mojang.py | 1 + meta/model/mojang.py | 19 + static/mojang/minecraft-legacy-override.json | 225 ++++++++++ static/mojang/minecraft-old-snapshots.json | 604 +++++++++++++++++++++++++++ updateMojang.py | 45 +- 5 files changed, 892 insertions(+), 2 deletions(-) create mode 100644 static/mojang/minecraft-old-snapshots.json (limited to 'meta') diff --git a/meta/common/mojang.py b/meta/common/mojang.py index a2d39e9f1a..dc80f44412 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -7,6 +7,7 @@ VERSIONS_DIR = join(BASE_DIR, "versions") ASSETS_DIR = join(BASE_DIR, "assets") STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") +STATIC_OLD_SNAPSHOTS_FILE = join(BASE_DIR, "minecraft-old-snapshots.json") STATIC_OVERRIDES_FILE = join(BASE_DIR, "minecraft-legacy-override.json") LIBRARY_PATCHES_FILE = join(BASE_DIR, "library-patches.json") diff --git a/meta/model/mojang.py b/meta/model/mojang.py index f3a0771d4d..6d308b1586 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -79,6 +79,25 @@ class ExperimentIndexWrap: self.versions: Dict[str, ExperimentEntry] = dict((x.id, x) for x in index.experiments) +class OldSnapshotEntry(MetaBase): + id: str + url: str + wiki: Optional[str] + jar: str + sha1: str + size: int + + +class OldSnapshotIndex(MetaBase): + old_snapshots: List[OldSnapshotEntry] + + +class OldSnapshotIndexWrap: + def __init__(self, index: OldSnapshotIndex): + self.index: OldSnapshotIndex = index + self.versions: Dict[str, OldSnapshotEntry] = dict((x.id, x) for x in index.old_snapshots) + + class LegacyOverrideEntry(MetaBase): main_class: Optional[str] = Field(alias="mainClass") applet_class: Optional[str] = Field(alias="appletClass") diff --git a/static/mojang/minecraft-legacy-override.json b/static/mojang/minecraft-legacy-override.json index d30db4c10c..b9d6fbb916 100644 --- a/static/mojang/minecraft-legacy-override.json +++ b/static/mojang/minecraft-legacy-override.json @@ -8,10 +8,61 @@ "releaseTime": "2013-03-20T12:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "13w12~": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.5": { "releaseTime": "2013-03-07T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "13w10b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w10a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09c": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w11a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w07a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w06a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w05b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w05a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w04a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w03a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w02b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w02a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w01b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w01a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.4.7": { "releaseTime": "2012-12-28T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] @@ -20,6 +71,15 @@ "releaseTime": "2012-12-20T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "12w50b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w50a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w49a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.4.5": { "releaseTime": "2012-11-20T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] @@ -44,10 +104,55 @@ "releaseTime": "2012-10-19T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "12w42b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w42a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w41b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w41a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w40b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w40a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w39b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w39a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w38b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w38a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w37a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w36a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w34b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w34a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.3.2": { "releaseTime": "2012-08-16T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "12w32a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.3.1": { "releaseTime": "2012-08-01T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] @@ -56,6 +161,60 @@ "releaseTime": "2012-07-26T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "12w30e": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30d": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30c": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w27a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w26a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w25a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w24a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w23b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w23a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w22a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w21b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w21a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w19a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w18a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w17a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w16a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.2.5": { "releaseTime": "2012-03-30T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] @@ -76,14 +235,74 @@ "releaseTime": "2012-03-01T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "1.2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w08a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w07a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w07b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w06a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w05b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w05a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w04a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w03a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.1": { "releaseTime": "2012-01-12T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "12w01a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w50a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w49a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w48a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w47a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "1.0": { "releaseTime": "2011-11-18T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "b1.9-pre6": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre5": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre4": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre3": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre1": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "b1.8.1": { "releaseTime": "2011-09-19T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] @@ -92,6 +311,12 @@ "releaseTime": "2011-09-15T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] }, + "b1.8-pre2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8-pre1-2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, "b1.7.3": { "releaseTime": "2011-07-08T00:00:00+02:00", "+traits": ["legacyLaunch", "texturepacks"] diff --git a/static/mojang/minecraft-old-snapshots.json b/static/mojang/minecraft-old-snapshots.json new file mode 100644 index 0000000000..073ce8a62c --- /dev/null +++ b/static/mojang/minecraft-old-snapshots.json @@ -0,0 +1,604 @@ +{ + "old_snapshots": [ + { + "id": "1_2", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_1.2", + "url": "https://archive.org/download/Minecraft-JSONs/1.2.json", + "sha1": "a2064011425a5e5befd9dee5eeb4f968ddf5ac77", + "size": 3988919, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_2/minecraft.jar" + }, + { + "id": "11w47a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_11w47a", + "url": "https://archive.org/download/Minecraft-JSONs/11w47a.json", + "sha1": "4e327918708d22e7443fbadefb9831ca04af4b90", + "size": 2242242, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w47a/minecraft.jar" + }, + { + "id": "11w48a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_11w48a", + "url": "https://archive.org/download/Minecraft-JSONs/11w48a.json", + "sha1": "fede770abe88a19e844d99dda611a7d18184155a", + "size": 2242604, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w48a/minecraft.jar" + }, + { + "id": "11w49a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_11w49a", + "url": "https://archive.org/download/Minecraft-JSONs/11w49a.json", + "sha1": "6f92a726e6b8b64f66c7e4d236f983c278d5af54", + "size": 3510866, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w49a/minecraft.jar" + }, + { + "id": "11w50a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_11w50a", + "url": "https://archive.org/download/Minecraft-JSONs/11w50a.json", + "sha1": "f4981ba0fee00a16d8dc9ec87bf2c4fdb51e4b7c", + "size": 3509701, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w50a/minecraft.jar" + }, + { + "id": "12w01a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w01a", + "url": "https://archive.org/download/Minecraft-JSONs/12w01a.json", + "sha1": "653a9cf55884b6bc4dcf3c574331e04bd5ad1032", + "size": 3839447, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w01a/minecraft.jar" + }, + { + "id": "12w03a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w03a", + "url": "https://archive.org/download/Minecraft-JSONs/12w03a.json", + "sha1": "e581c7c9dd57cbf73f72b833be5eff6109187df0", + "size": 3875210, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w03a/minecraft.jar" + }, + { + "id": "12w04a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w04a", + "url": "https://archive.org/download/Minecraft-JSONs/12w04a.json", + "sha1": "4911c473e856ec8102b8419eb36d0f54dad029a0", + "size": 3911974, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w04a/minecraft.jar" + }, + { + "id": "12w05a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w05a", + "url": "https://archive.org/download/Minecraft-JSONs/12w05a.json", + "sha1": "28328e67b82564335aa8280095a0716a2eb790de", + "size": 3931639, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05a/minecraft.jar" + }, + { + "id": "12w05b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w05b", + "url": "https://archive.org/download/Minecraft-JSONs/12w05b.json", + "sha1": "75fbc4a39a244d0f1eb842ff8385e992e2b47dd5", + "size": 3931694, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05b/minecraft.jar" + }, + { + "id": "12w06a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w06a", + "url": "https://archive.org/download/Minecraft-JSONs/12w06a.json", + "sha1": "a8403c0d4c0cdb65722d864d9cf42663b8aab08b", + "size": 3934973, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w06a/minecraft.jar" + }, + { + "id": "12w07a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w07a", + "url": "https://archive.org/download/Minecraft-JSONs/12w07a.json", + "sha1": "e7ad115b29612b893972f0817030d993bc56fb7e", + "size": 3956252, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07a/minecraft.jar" + }, + { + "id": "12w07b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w07b", + "url": "https://archive.org/download/Minecraft-JSONs/12w07b.json", + "sha1": "0eea35d588fc2cee5d397472aa3565f48c220217", + "size": 3956323, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07b/minecraft.jar" + }, + { + "id": "12w08a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w08a", + "url": "https://archive.org/download/Minecraft-JSONs/12w08a.json", + "sha1": "db2fcfdd23526b0f381ef2f3f2fd049d36227230", + "size": 3981486, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w08a/minecraft.jar" + }, + { + "id": "12w16a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w16a", + "url": "https://archive.org/download/Minecraft-JSONs/12w16a.json", + "sha1": "6b0a9fe3ac275f79ac6d259f4279752274ec05f8", + "size": 4080437, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w16a/minecraft.jar" + }, + { + "id": "12w17a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w17a", + "url": "https://archive.org/download/Minecraft-JSONs/12w17a.json", + "sha1": "17d41f8a07e054040ba34e523593bdea7f0fb6ba", + "size": 4114768, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w17a/minecraft.jar" + }, + { + "id": "12w18a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w18a", + "url": "https://archive.org/download/Minecraft-JSONs/12w18a.json", + "sha1": "9e9ab992317048bee9158ad9d1e2bc758db2b4af", + "size": 4317820, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w18a/minecraft.zip/bin/minecraft.jar" + }, + { + "id": "12w19a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w19a", + "url": "https://archive.org/download/Minecraft-JSONs/12w19a.json", + "sha1": "474aaac9a8b1dcbf312a5c09c7eae4a6aa401225", + "size": 4343792, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w19a/minecraft.zip/bin/minecraft.jar" + }, + { + "id": "12w21a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w21a", + "url": "https://archive.org/download/Minecraft-JSONs/12w21a.json", + "sha1": "e755423a04b0efde01e035a9d651acadeba0aef9", + "size": 4409586, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21a/minecraft.jar" + }, + { + "id": "12w21b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w21b", + "url": "https://archive.org/download/Minecraft-JSONs/12w21b.json", + "sha1": "84437ded4839b29d34f83e9f3bab07cc48980faf", + "size": 4499708, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21b/minecraft.jar" + }, + { + "id": "12w22a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w22a", + "url": "https://archive.org/download/Minecraft-JSONs/12w22a.json", + "sha1": "3631a714cb465d39f5cb5c18aa23abf38031b359", + "size": 4542344, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w22a/minecraft.jar" + }, + { + "id": "12w23a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w23a", + "url": "https://archive.org/download/Minecraft-JSONs/12w23a.json", + "sha1": "4a5a8e3349ea2e9d67fa4dde6ec68d385bff46f0", + "size": 4543912, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23a/minecraft.jar" + }, + { + "id": "12w23b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w23b", + "url": "https://archive.org/download/Minecraft-JSONs/12w23b.json", + "sha1": "e107667bcbb4443afc160a7eeb8f347acc9826f8", + "size": 4543928, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23b/minecraft.jar" + }, + { + "id": "12w24a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w24a", + "url": "https://archive.org/download/Minecraft-JSONs/12w24a.json", + "sha1": "e479c425ffe6ca3512d97ad0e02a8cd85356bf83", + "size": 4540049, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w24a/minecraft.jar" + }, + { + "id": "12w25a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w25a", + "url": "https://archive.org/download/Minecraft-JSONs/12w25a.json", + "sha1": "eddf53994e40ecc44f582d4b47b9a441844909b6", + "size": 4556548, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w25a/minecraft.jar" + }, + { + "id": "12w26a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w26a", + "url": "https://archive.org/download/Minecraft-JSONs/12w26a.json", + "sha1": "2d1e782a4c4435fe921027ae464a272945cca925", + "size": 4573075, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w26a/minecraft.jar" + }, + { + "id": "12w27a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w27a", + "url": "https://archive.org/download/Minecraft-JSONs/12w27a.json", + "sha1": "5e69b80f9c757bdc8275c1f6ce7e71820fe6d79a", + "size": 4584956, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w27a/minecraft.jar" + }, + { + "id": "12w30a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w30a", + "url": "https://archive.org/download/Minecraft-JSONs/12w30a.json", + "sha1": "368215d7fd38ee3e829725e11b3f193d45801128", + "size": 4584574, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30a/minecraft.jar" + }, + { + "id": "12w30b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w30b", + "url": "https://archive.org/download/Minecraft-JSONs/12w30b.json", + "sha1": "9d1e450cdb300ec426b50762e031796a8349aa1c", + "size": 4584593, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30b/minecraft.jar" + }, + { + "id": "12w30c", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w30c", + "url": "https://archive.org/download/Minecraft-JSONs/12w30c.json", + "sha1": "92817a0c3f3c913ad68bdb082ac1f147db986282", + "size": 4584617, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30c/minecraft.jar" + }, + { + "id": "12w30d", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w30d", + "url": "https://archive.org/download/Minecraft-JSONs/12w30d.json", + "sha1": "a5e7508de2d3993cb5222d8e4f8415226745d6ff", + "size": 4585459, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30d/minecraft.jar" + }, + { + "id": "12w30e", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w30e", + "url": "https://archive.org/download/Minecraft-JSONs/12w30e.json", + "sha1": "1a37562cda14028dae15b331bfd36108e617a477", + "size": 4585506, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30e/minecraft.jar" + }, + { + "id": "12w32a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w32a", + "url": "https://archive.org/download/Minecraft-JSONs/12w32a.json", + "sha1": "13183e023c8918ed08c302c2fe1438f61b53d094", + "size": 4628354, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w32a/minecraft.jar" + }, + { + "id": "12w34a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w34a", + "url": "https://archive.org/download/Minecraft-JSONs/12w34a.json", + "sha1": "41769085c020f4651b5b5dd50a6f83be2b000b29", + "size": 4676139, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34a/minecraft.jar" + }, + { + "id": "12w34b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w34b", + "url": "https://archive.org/download/Minecraft-JSONs/12w34b.json", + "sha1": "5fb51efc8f07ea57ffc2a02a7dac8a2835651b61", + "size": 4682004, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34b/minecraft.jar" + }, + { + "id": "12w36a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w36a", + "url": "https://archive.org/download/Minecraft-JSONs/12w36a.json", + "sha1": "914bd89686c4621da327d50375a1edbdd9c177da", + "size": 4705667, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w36a/minecraft.jar" + }, + { + "id": "12w37a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w37a", + "url": "https://archive.org/download/Minecraft-JSONs/12w37a.json", + "sha1": "50ea0bac2c91b13c0881bbf99aad66a046533781", + "size": 4727781, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w37a/minecraft.jar" + }, + { + "id": "12w38a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w38a", + "url": "https://archive.org/download/Minecraft-JSONs/12w38a.json", + "sha1": "69e5a531fa615eb870345feb25f26126fe95586b", + "size": 4752649, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38a/minecraft.jar" + }, + { + "id": "12w38b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w38b", + "url": "https://archive.org/download/Minecraft-JSONs/12w38b.json", + "sha1": "867505cb4934016bf46cb8c7833ef0eaef8d39d9", + "size": 4767044, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38b/minecraft.jar" + }, + { + "id": "12w39a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w39a", + "url": "https://archive.org/download/Minecraft-JSONs/12w39a.json", + "sha1": "65247c02036156b9f34c17f7d8bb053641afd0e7", + "size": 4768937, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39a/minecraft.jar" + }, + { + "id": "12w39b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w39b", + "url": "https://archive.org/download/Minecraft-JSONs/12w39b.json", + "sha1": "620d02bfd74204462a810874f83929d0b8b0b936", + "size": 4766448, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39b/minecraft.jar" + }, + { + "id": "12w40a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w40a", + "url": "https://archive.org/download/Minecraft-JSONs/12w40a.json", + "sha1": "434652551e93fdfb4de30cbe64310037777f7eff", + "size": 4884173, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40a/minecraft.jar" + }, + { + "id": "12w40b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w40b", + "url": "https://archive.org/download/Minecraft-JSONs/12w40b.json", + "sha1": "1612e0fa6062f764844c5a71ff89660c311f38ae", + "size": 4884732, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40b/minecraft.jar" + }, + { + "id": "12w41a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w41a", + "url": "https://archive.org/download/Minecraft-JSONs/12w41a.json", + "sha1": "7327bcd4da0d194565d6ee732b1fa48e8b14b347", + "size": 4900512, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41a/minecraft.jar" + }, + { + "id": "12w41b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w41b", + "url": "https://archive.org/download/Minecraft-JSONs/12w41b.json", + "sha1": "d73a5b6919d10689811c11d1c3debcd817050039", + "size": 4900976, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41b/minecraft.jar" + }, + { + "id": "12w42a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w42a", + "url": "https://archive.org/download/Minecraft-JSONs/12w42a.json", + "sha1": "0b10f7afbd54392b387a23c34547cb0f30d48998", + "size": 4919860, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42a/minecraft.jar" + }, + { + "id": "12w42b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w42b", + "url": "https://archive.org/download/Minecraft-JSONs/12w42b.json", + "sha1": "74024eab7588bd33dd53baa756fd4deb92557b0a", + "size": 4921744, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42b/minecraft.jar" + }, + { + "id": "12w49a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w49a", + "url": "https://archive.org/download/Minecraft-JSONs/12w49a.json", + "sha1": "a5a4cf65cf89207eb6ad7371c9237973865eba81", + "size": 4990865, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w49a/minecraft.jar" + }, + { + "id": "12w50a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w50a", + "url": "https://archive.org/download/Minecraft-JSONs/12w50a.json", + "sha1": "96a6427720aef608a594ed1e0291e77cba398155", + "size": 5004175, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50a/minecraft.jar" + }, + { + "id": "12w50b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_12w50b", + "url": "https://archive.org/download/Minecraft-JSONs/12w50b.json", + "sha1": "73dc6efe46fef478cc5ed123e711872450e193fd", + "size": 5005360, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50b/minecraft.jar" + }, + { + "id": "13w01a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w01a", + "url": "https://archive.org/download/Minecraft-JSONs/13w01a.json", + "sha1": "e3256fe44cd7c6a1bf45570337e634b030589878", + "size": 5033591, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01a/minecraft.jar" + }, + { + "id": "13w01b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w01b", + "url": "https://archive.org/download/Minecraft-JSONs/13w01b.json", + "sha1": "87f9f88eb3dcc80dcf818e44af774ab7ff63eb66", + "size": 5035543, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01b/minecraft.jar" + }, + { + "id": "13w02a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w02a", + "url": "https://archive.org/download/Minecraft-JSONs/13w02a.json", + "sha1": "e9a57e8d5dcddcc9d919054c19b10eb71fcc304e", + "size": 5499864, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02a/minecraft.jar" + }, + { + "id": "13w02b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w02b", + "url": "https://archive.org/download/Minecraft-JSONs/13w02b.json", + "sha1": "9289953c82ce69ec3d2e59a6044a9c900a99478f", + "size": 5363159, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02b/minecraft.jar" + }, + { + "id": "13w03a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w03a", + "url": "https://archive.org/download/Minecraft-JSONs/13w03a.json", + "sha1": "6a2d3ffa88b7f5e0949f041193c6525d1c4cc22e", + "size": 6401672, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w03a/minecraft.jar" + }, + { + "id": "13w04a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w04a", + "url": "https://archive.org/download/Minecraft-JSONs/13w04a.json", + "sha1": "dff06285694aab7771682f949d51bca98ce52359", + "size": 6426112, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w04a/minecraft.jar" + }, + { + "id": "13w05a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w05a", + "url": "https://archive.org/download/Minecraft-JSONs/13w05a.json", + "sha1": "7808f090cb92afc8084545dd2ea305773bbd5e6e", + "size": 6442319, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05a/minecraft.jar" + }, + { + "id": "13w05b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w05b", + "url": "https://archive.org/download/Minecraft-JSONs/13w05b.json", + "sha1": "72074d7cb843229292f71ae917dcefbc0f01461d", + "size": 6442459, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05b/minecraft.jar" + }, + { + "id": "13w06a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w06a", + "url": "https://archive.org/download/Minecraft-JSONs/13w06a.json", + "sha1": "da409ce9f9c910c08cc729aadc6f592b8ff813cb", + "size": 6445893, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w06a/minecraft.jar" + }, + { + "id": "13w07a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w07a", + "url": "https://archive.org/download/Minecraft-JSONs/13w07a.json", + "sha1": "61f7dad52c34838be7a1e7d37a2370ac847ab87a", + "size": 6510193, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w07a/minecraft.jar" + }, + { + "id": "13w09a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w09a", + "url": "https://archive.org/download/Minecraft-JSONs/13w09a.json", + "sha1": "9ac49c55ca76eedfc985fa245dd0682e08b34982", + "size": 5574252, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09a/minecraft.jar" + }, + { + "id": "13w09b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w09b", + "url": "https://archive.org/download/Minecraft-JSONs/13w09b.json", + "sha1": "635161d84725b1988f814c890fe5841ad99121e1", + "size": 5578604, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09b/minecraft.jar" + }, + { + "id": "13w09c", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w09c", + "url": "https://archive.org/download/Minecraft-JSONs/13w09c.json", + "sha1": "1367ef1410c2ce7ac0f1c58727aa4883c8677469", + "size": 5533426, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09c/minecraft.jar" + }, + { + "id": "13w10a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w10a", + "url": "https://archive.org/download/Minecraft-JSONs/13w10a.json", + "sha1": "9162bca3ba8a77da2cd26cda1e46ca89a44bac4a", + "size": 5534991, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10a/minecraft.jar" + }, + { + "id": "13w10b", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w10b", + "url": "https://archive.org/download/Minecraft-JSONs/13w10b.json", + "sha1": "21e35ffe1772d1cf89aea653c7a883acb54b13a3", + "size": 5555235, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10b/minecraft.jar" + }, + { + "id": "13w11a", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w11a", + "url": "https://archive.org/download/Minecraft-JSONs/13w11a.json", + "sha1": "bec6c96bc4413ea3092428aba93d7425fe6a4ea9", + "size": 5556608, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w11a/minecraft.jar" + }, + { + "id": "13w12~", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_13w12~", + "url": "https://archive.org/download/Minecraft-JSONs/13w12~.json", + "sha1": "66d6c6b5205ae1e8f0ad3eb78ccf66500f39c0c7", + "size": 5561634, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w12_/minecraft.jar" + }, + { + "id": "b1_8-pre1", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.8-pre1-2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre1-2.json", + "sha1": "6789c69ede3aedf83b800c76bea56855d38a0afc", + "size": 1893151, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre/minecraft.jar" + }, + { + "id": "b1_8-pre2", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.8-pre2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre2.json", + "sha1": "44191f2895bf1e064269c9279778f2e3e9c3c9c7", + "size": 1897780, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre2/minecraft.jar" + }, + { + "id": "b1_9-pre1", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.9-pre1", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre1.json", + "sha1": "fdeef0129af130aa00702e53c37c5c4029b7d50e", + "size": 1966908, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre/minecraft.jar" + }, + { + "id": "b1_9-pre2", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.9-pre2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre2.json", + "sha1": "b0d40cf43b625631af65e2a645c34b533251da0e", + "size": 1988123, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre2/minecraft.jar" + }, + { + "id": "b1_9-pre3", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.9-pre3", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre3.json", + "sha1": "5b7fe76a602b7511c97740e36dc25040ccb6e76b", + "size": 2087104, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre3/minecraft.jar" + }, + { + "id": "b1_9-pre4", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.9-pre4", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre4.json", + "sha1": "5c4831d9705f2e00e3cd993e89b822636492932a", + "size": 2147107, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre4/minecraft.jar" + }, + { + "id": "b1_9-pre5", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.9-pre5", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre5.json", + "sha1": "e109b297d2c4ee7a0bd6aed72f38f7e3185654cf", + "size": 2211261, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre5/minecraft.jar" + }, + { + "id": "b1_9-pre6", + "wiki": "https://minecraft.fandom.com/wiki/Java_Edition_b1.9-pre6", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre6.json", + "sha1": "f0983e65cd1c0768b0d1fec471ce4f69173b8126", + "size": 2239270, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre6/minecraft.jar" + } + ] +} diff --git a/updateMojang.py b/updateMojang.py index ac11fd449d..08ec1dc817 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -8,8 +8,10 @@ from cachecontrol.caches import FileCache from meta.common import upstream_path, ensure_upstream_dir, static_path from meta.common.http import download_binary_file -from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR, STATIC_EXPERIMENTS_FILE -from meta.model.mojang import MojangIndexWrap, MojangIndex, ExperimentIndex, ExperimentIndexWrap +from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR, STATIC_EXPERIMENTS_FILE, \ + STATIC_OLD_SNAPSHOTS_FILE +from meta.model.mojang import MojangIndexWrap, MojangIndex, ExperimentIndex, ExperimentIndexWrap, OldSnapshotIndexWrap, \ + OldSnapshotIndex UPSTREAM_DIR = upstream_path() STATIC_DIR = static_path() @@ -40,6 +42,28 @@ def fetch_zipped_version(path, url): return version_json +def fetch_modified_version(path, version): + r = sess.get(version.url) + r.raise_for_status() + version_json = r.json() + + version_json["releaseTime"] = version_json["releaseTime"] + "T00:00:00+02:00" + version_json["time"] = version_json["releaseTime"] + + downloads = {"client": {"url": version.jar, + "sha1": version.sha1, + "size": version.size + } + } + + version_json["downloads"] = downloads + + with open(path, 'w', encoding='utf-8') as f: + json.dump(version_json, f, sort_keys=True, indent=4) + + return version_json + + def fetch_version(path, url): r = sess.get(url) r.raise_for_status() @@ -98,6 +122,23 @@ def main(): else: print("Already have experiment " + version.id) + static_old_snapshots_path = os.path.join(STATIC_DIR, STATIC_OLD_SNAPSHOTS_FILE) + + # deal with old snapshots + if os.path.exists(static_old_snapshots_path): + old_snapshots = OldSnapshotIndexWrap(OldSnapshotIndex.parse_file(static_old_snapshots_path)) + old_snapshots_ids = set(old_snapshots.versions.keys()) + + for x in old_snapshots_ids: + version = old_snapshots.versions[x] + old_snapshots_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") + + print("Updating old snapshot " + version.id) + if not os.path.isfile(old_snapshots_path): + fetch_modified_version(old_snapshots_path, version) + else: + print("Already have old snapshot " + version.id) + remote_versions.index.write(version_manifest_path) -- cgit 0.0.5-2-1-g0f52 From d551b0d81141fda91551544d45b4a4f299ccb068 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 16 Nov 2022 16:22:55 +0100 Subject: feat: add support for +jvmArgs on meta Signed-off-by: Sefa Eyeoglu --- meta/model/__init__.py | 1 + meta/model/mojang.py | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 7a6d368c05..dc466c3b0b 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -283,6 +283,7 @@ class MetaVersion(Versioned): 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") + additional_jvm_args: Optional[List[str]] = Field(alias="+jvmArgs") class MetaPackage(Versioned): diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 6d308b1586..d10dce3c30 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -103,6 +103,7 @@ class LegacyOverrideEntry(MetaBase): applet_class: Optional[str] = Field(alias="appletClass") release_time: Optional[datetime] = Field(alias="releaseTime") additional_traits: Optional[List[str]] = Field(alias="+traits") + additional_jvm_args: Optional[List[str]] = Field(alias="+jvmArgs") def apply_onto_meta_version(self, meta_version: MetaVersion, legacy: bool = True): # simply hard override classes @@ -118,6 +119,11 @@ class LegacyOverrideEntry(MetaBase): meta_version.additional_traits = [] meta_version.additional_traits += self.additional_traits + if self.additional_jvm_args: + if not meta_version.additional_jvm_args: + meta_version.additional_jvm_args = [] + meta_version.additional_jvm_args += self.additional_jvm_args + if legacy: # remove all libraries - they are not needed for legacy meta_version.libraries = None -- cgit 0.0.5-2-1-g0f52 From 9547400f18e42efc9b2161eb39b7b9368dadcc1c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 24 Nov 2022 13:02:42 +0100 Subject: fix: update Forge maven url Signed-off-by: Sefa Eyeoglu --- generateForge.py | 12 ++++++------ meta/model/forge.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'meta') diff --git a/generateForge.py b/generateForge.py index e6bca2534b..89f3cc6854 100755 --- a/generateForge.py +++ b/generateForge.py @@ -98,7 +98,7 @@ def version_from_profile(profile: ForgeInstallerProfile, version: ForgeVersion) overridden_name.classifier = "universal" overridden_lib = Library(name=overridden_name) - if forge_lib.url == "http://files.minecraftforge.net/maven/": + if forge_lib.url == "http://maven.minecraftforge.net/": overridden_lib.url = "https://maven.minecraftforge.net/" else: overridden_lib.url = forge_lib.url @@ -143,7 +143,7 @@ def version_from_modernized_installer(installer: MojangVersion, version: ForgeVe overridden_name = forge_lib.name overridden_name.classifier = "universal" forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % overridden_name.path() + forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % overridden_name.path() forge_lib.name = overridden_name elif forge_lib.name.artifact == "minecraftforge": @@ -152,7 +152,7 @@ def version_from_modernized_installer(installer: MojangVersion, version: ForgeVe overridden_name.classifier = "universal" overridden_name.version = "%s-%s" % (mc_version, overridden_name.version) forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % overridden_name.path() + forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % overridden_name.path() forge_lib.name = overridden_name v.libraries.append(forge_lib) @@ -198,7 +198,7 @@ def version_from_build_system_installer(installer: MojangVersion, profile: Forge name=GradleSpecifier("net.minecraftforge", "forge", version.long_version, "installer")) installer_lib.downloads = MojangLibraryDownloads() installer_lib.downloads.artifact = MojangArtifact( - url="https://files.minecraftforge.net/maven/%s" % (installer_lib.name.path()), + url="https://maven.minecraftforge.net/%s" % (installer_lib.name.path()), sha1=info.sha1hash, size=info.size) v.maven_files.append(installer_lib) @@ -210,7 +210,7 @@ def version_from_build_system_installer(installer: MojangVersion, profile: Forge if forge_lib.name.group == "net.minecraftforge" and forge_lib.name.artifact == "forge" \ and forge_lib.name.classifier == "universal": - forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % forge_lib.name.path() + forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % forge_lib.name.path() v.maven_files.append(forge_lib) v.libraries = [] @@ -231,7 +231,7 @@ def version_from_build_system_installer(installer: MojangVersion, profile: Forge if forge_lib.name.artifact == "forge": forge_lib.name.classifier = "launcher" forge_lib.downloads.artifact.path = forge_lib.name.path() - forge_lib.downloads.artifact.url = "https://files.minecraftforge.net/maven/%s" % forge_lib.name.path() + forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % forge_lib.name.path() forge_lib.name = forge_lib.name v.libraries.append(forge_lib) diff --git a/meta/model/forge.py b/meta/model/forge.py index 2db191b941..6112023e15 100644 --- a/meta/model/forge.py +++ b/meta/model/forge.py @@ -16,7 +16,7 @@ class ForgeFile(MetaBase): return "%s-%s-%s.%s" % ("forge", long_version, self.classifier, self.extension) def url(self, long_version): - return "https://files.minecraftforge.net/maven/net/minecraftforge/forge/%s/%s" % ( + return "https://maven.minecraftforge.net/net/minecraftforge/forge/%s/%s" % ( long_version, self.filename(long_version)) @@ -112,7 +112,7 @@ class ForgeOptional(MetaBase): "desc": "A mod that collects statistics about Minecraft and your system.
Useful for Forge to understand how Minecraft/Forge are used.", "url": "http://www.minecraftforge.net/forum/index.php?topic=43278.0", "artifact": "net.minecraftforge:MercuriusUpdater:1.11.2", - "maven": "http://files.minecraftforge.net/maven/" + "maven": "http://maven.minecraftforge.net/" } ] """ -- cgit 0.0.5-2-1-g0f52 From 3aa946cfc2b3d59a88df6d633b5bb05da27e2b74 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 29 Nov 2022 15:25:20 +0100 Subject: fix: remove EOL Java 18 from compatible Java majors Signed-off-by: Sefa Eyeoglu --- meta/model/mojang.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index d10dce3c30..f5bfcd5a58 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -10,8 +10,8 @@ SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 DEFAULT_JAVA_MAJOR = 8 # By default, we should recommend Java 8 if we don't know better COMPATIBLE_JAVA_MAPPINGS = { - 16: [17, 18, 19], - 17: [18, 19] + 16: [17, 19], + 17: [19] } ''' -- cgit 0.0.5-2-1-g0f52 From 13e82ebc0dc02554f17819a12eaf7f489993628a Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 15 Dec 2022 16:30:33 +0100 Subject: fix: remove Java 19 recommendation Many Forge versions break with Java 19. Signed-off-by: Sefa Eyeoglu --- meta/model/mojang.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index f5bfcd5a58..9f9a29c01a 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -10,8 +10,7 @@ SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 DEFAULT_JAVA_MAJOR = 8 # By default, we should recommend Java 8 if we don't know better COMPATIBLE_JAVA_MAPPINGS = { - 16: [17, 19], - 17: [19] + 16: [17] } ''' -- cgit 0.0.5-2-1-g0f52 From 5e4c32a0b5c169f32f785767aeecb033759469f9 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 27 Jan 2023 17:54:22 +0100 Subject: feat: add User-Agent header Signed-off-by: Sefa Eyeoglu --- meta/common/__init__.py | 14 ++++++++++++++ updateFabric.py | 9 ++------- updateForge.py | 8 ++------ updateLiteloader.py | 9 ++------- updateMojang.py | 9 ++------- updateQuilt.py | 7 ++----- 6 files changed, 24 insertions(+), 32 deletions(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index e3080ea819..10b35da50d 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -2,6 +2,10 @@ import os import datetime from urllib.parse import urlparse +import requests +from cachecontrol import CacheControl +from cachecontrol.caches import FileCache + def serialize_datetime(dt: datetime.datetime): if dt.tzinfo is None: @@ -69,3 +73,13 @@ def merge_dict(base: dict, overlay: dict): overlay[k] = v return overlay + + +def default_session(): + forever_cache = FileCache('caches/http_cache', forever=True) + sess = CacheControl(requests.Session(), forever_cache) + + sess.headers.update({"User-Agent": "PrismLauncherMeta/1.0"}) + + return sess + diff --git a/updateFabric.py b/updateFabric.py index d61c1730aa..1656e16057 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -3,11 +3,7 @@ import os import zipfile from datetime import datetime -import requests -from cachecontrol import CacheControl -from cachecontrol.caches import FileCache - -from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key +from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key, default_session from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, DATETIME_FORMAT_HTTP from meta.model.fabric import FabricJarInfo @@ -17,8 +13,7 @@ ensure_upstream_dir(JARS_DIR) ensure_upstream_dir(INSTALLER_INFO_DIR) ensure_upstream_dir(META_DIR) -forever_cache = FileCache('caches/http_cache', forever=True) -sess = CacheControl(requests.Session(), forever_cache) +sess = default_session() def filehash(filename, hashtype, blocksize=65536): diff --git a/updateForge.py b/updateForge.py index 736e3dd9ea..64ccb6a0c6 100755 --- a/updateForge.py +++ b/updateForge.py @@ -13,12 +13,9 @@ from datetime import datetime from pathlib import Path from pprint import pprint -import requests -from cachecontrol import CacheControl -from cachecontrol.caches import FileCache from pydantic import ValidationError -from meta.common import upstream_path, ensure_upstream_dir, static_path +from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session from meta.common.forge import JARS_DIR, INSTALLER_INFO_DIR, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, \ FILE_MANIFEST_DIR, BAD_VERSIONS, STATIC_LEGACYINFO_FILE from meta.model.forge import ForgeFile, ForgeEntry, ForgeMCVersionInfo, ForgeLegacyInfoList, DerivedForgeIndex, \ @@ -37,8 +34,7 @@ ensure_upstream_dir(FILE_MANIFEST_DIR) LEGACYINFO_PATH = os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE) -forever_cache = FileCache('caches/http_cache', forever=True) -sess = CacheControl(requests.Session(), forever_cache) +sess = default_session() def eprint(*args, **kwargs): diff --git a/updateLiteloader.py b/updateLiteloader.py index 39e7c65861..ebdfaefa24 100755 --- a/updateLiteloader.py +++ b/updateLiteloader.py @@ -1,11 +1,7 @@ import json import os -import requests -from cachecontrol import CacheControl -from cachecontrol.caches import FileCache - -from meta.common import upstream_path, ensure_upstream_dir +from meta.common import upstream_path, ensure_upstream_dir, default_session from meta.common.liteloader import VERSIONS_FILE, BASE_DIR from meta.model.liteloader import LiteloaderIndex @@ -13,8 +9,7 @@ UPSTREAM_DIR = upstream_path() ensure_upstream_dir(BASE_DIR) -forever_cache = FileCache('caches/http_cache', forever=True) -sess = CacheControl(requests.Session(), forever_cache) +sess = default_session() def main(): diff --git a/updateMojang.py b/updateMojang.py index c2a5aa4b1b..315cac395d 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -2,11 +2,7 @@ import json import os import zipfile -import requests -from cachecontrol import CacheControl -from cachecontrol.caches import FileCache - -from meta.common import upstream_path, ensure_upstream_dir, static_path +from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session from meta.common.http import download_binary_file from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR, STATIC_EXPERIMENTS_FILE, \ STATIC_OLD_SNAPSHOTS_FILE @@ -20,8 +16,7 @@ ensure_upstream_dir(BASE_DIR) ensure_upstream_dir(VERSIONS_DIR) ensure_upstream_dir(ASSETS_DIR) -forever_cache = FileCache('caches/http_cache', forever=True) -sess = CacheControl(requests.Session(), forever_cache) +sess = default_session() def fetch_zipped_version(path, url): diff --git a/updateQuilt.py b/updateQuilt.py index 4ffc8e510f..244d0b0d78 100755 --- a/updateQuilt.py +++ b/updateQuilt.py @@ -4,10 +4,8 @@ import zipfile from datetime import datetime import requests -from cachecontrol import CacheControl -from cachecontrol.caches import FileCache -from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key +from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key, default_session from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, USE_QUILT_MAPPINGS from meta.common.fabric import DATETIME_FORMAT_HTTP from meta.model.fabric import FabricJarInfo @@ -18,8 +16,7 @@ ensure_upstream_dir(JARS_DIR) ensure_upstream_dir(INSTALLER_INFO_DIR) ensure_upstream_dir(META_DIR) -forever_cache = FileCache('caches/http_cache', forever=True) -sess = CacheControl(requests.Session(), forever_cache) +sess = default_session() def filehash(filename, hashtype, blocksize=65536): -- cgit 0.0.5-2-1-g0f52 From 1c838d992edb070f571a8a46b39c3c0341d64b8b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 25 Feb 2023 00:19:55 +0100 Subject: chore: reformat using black Signed-off-by: Sefa Eyeoglu --- generateFabric.py | 73 ++++++++++++---- generateForge.py | 213 +++++++++++++++++++++++++++++++++++------------ generateLiteloader.py | 42 ++++++---- generateMojang.py | 198 ++++++++++++++++++++++++++++++------------- generateQuilt.py | 83 +++++++++++++----- index.py | 23 +++-- meta/common/__init__.py | 3 +- meta/common/http.py | 2 +- meta/model/__init__.py | 99 +++++++++++++++------- meta/model/forge.py | 157 +++++++++++++++++++++++----------- meta/model/index.py | 2 +- meta/model/liteloader.py | 88 ++++++++++---------- meta/model/mojang.py | 56 +++++++++---- updateFabric.py | 52 +++++++++--- updateForge.py | 141 ++++++++++++++++++++----------- updateLiteloader.py | 4 +- updateMojang.py | 61 +++++++++----- updateQuilt.py | 45 +++++++--- 18 files changed, 929 insertions(+), 413 deletions(-) (limited to 'meta') diff --git a/generateFabric.py b/generateFabric.py index 3a0629bcc3..7ca50dd6aa 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -1,8 +1,19 @@ import json import os -from meta.common import ensure_component_dir, launcher_path, upstream_path, transform_maven_key -from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT +from meta.common import ( + ensure_component_dir, + launcher_path, + upstream_path, + transform_maven_key, +) +from meta.common.fabric import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + INTERMEDIARY_COMPONENT, + LOADER_COMPONENT, +) from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses @@ -14,20 +25,26 @@ ensure_component_dir(INTERMEDIARY_COMPONENT) def load_jar_info(artifact_key) -> FabricJarInfo: - return FabricJarInfo.parse_file(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json")) + return FabricJarInfo.parse_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") + ) def load_installer_info(version) -> FabricInstallerDataV1: - return FabricInstallerDataV1.parse_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json")) + return FabricInstallerDataV1.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") + ) def process_loader_version(entry) -> MetaVersion: jar_info = load_jar_info(transform_maven_key(entry["maven"])) installer_info = load_installer_info(entry["version"]) - v = MetaVersion(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"]) + v = MetaVersion( + name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"] + ) v.release_time = jar_info.release_time - v.requires = [Dependency(uid='net.fabricmc.intermediary')] + v.requires = [Dependency(uid="net.fabricmc.intermediary")] v.order = 10 v.type = "release" if isinstance(installer_info.main_class, FabricMainClasses): @@ -37,7 +54,10 @@ def process_loader_version(entry) -> MetaVersion: v.libraries = [] v.libraries.extend(installer_info.libraries.common) v.libraries.extend(installer_info.libraries.client) - loader_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), url="https://maven.fabricmc.net") + loader_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.fabricmc.net", + ) v.libraries.append(loader_lib) return v @@ -45,14 +65,21 @@ def process_loader_version(entry) -> MetaVersion: def process_intermediary_version(entry) -> MetaVersion: jar_info = load_jar_info(transform_maven_key(entry["maven"])) - v = MetaVersion(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=entry["version"]) + v = MetaVersion( + name="Intermediary Mappings", + uid="net.fabricmc.intermediary", + version=entry["version"], + ) v.release_time = jar_info.release_time - v.requires = [Dependency(uid='net.minecraft', equals=entry["version"])] + v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] v.order = 11 v.type = "release" v.libraries = [] v.volatile = True - intermediary_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), url="https://maven.fabricmc.net") + intermediary_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.fabricmc.net", + ) v.libraries.append(intermediary_lib) return v @@ -61,7 +88,9 @@ def main(): recommended_loader_versions = [] recommended_intermediary_versions = [] - with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as f: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as f: loader_version_index = json.load(f) for entry in loader_version_index: version = entry["version"] @@ -75,7 +104,9 @@ def main(): v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) - with open(os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), 'r', encoding='utf-8') as f: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), "r", encoding="utf-8" + ) as f: intermediary_version_index = json.load(f) for entry in intermediary_version_index: version = entry["version"] @@ -83,18 +114,24 @@ def main(): v = process_intermediary_version(entry) - recommended_intermediary_versions.append(version) # all intermediaries are recommended + recommended_intermediary_versions.append( + version + ) # all intermediaries are recommended - v.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) + v.write( + os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json") + ) - package = MetaPackage(uid=LOADER_COMPONENT, name='Fabric Loader') + package = MetaPackage(uid=LOADER_COMPONENT, name="Fabric Loader") package.recommended = recommended_loader_versions - package.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." + package.description = ( + "Fabric Loader is a tool to load Fabric-compatible mods in game environments." + ) package.project_url = "https://fabricmc.net" package.authors = ["Fabric Developers"] package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) - package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') + package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name="Intermediary Mappings") package.recommended = recommended_intermediary_versions package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." package.project_url = "https://fabricmc.net" @@ -102,5 +139,5 @@ def main(): package.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json")) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/generateForge.py b/generateForge.py index 89f3cc6854..7f25544c55 100755 --- a/generateForge.py +++ b/generateForge.py @@ -6,13 +6,36 @@ from operator import attrgetter from typing import Collection from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path -from meta.common.forge import FORGE_COMPONENT, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, \ - STATIC_LEGACYINFO_FILE, INSTALLER_INFO_DIR, BAD_VERSIONS, FORGEWRAPPER_MAVEN +from meta.common.forge import ( + FORGE_COMPONENT, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + DERIVED_INDEX_FILE, + STATIC_LEGACYINFO_FILE, + INSTALLER_INFO_DIR, + BAD_VERSIONS, + FORGEWRAPPER_MAVEN, +) from meta.common.mojang import MINECRAFT_COMPONENT -from meta.model import MetaVersion, Dependency, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, \ - MetaPackage -from meta.model.forge import ForgeVersion, ForgeInstallerProfile, ForgeLegacyInfo, fml_libs_for_version, \ - ForgeInstallerProfileV2, InstallerInfo, DerivedForgeIndex, ForgeLegacyInfoList +from meta.model import ( + MetaVersion, + Dependency, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + MetaPackage, +) +from meta.model.forge import ( + ForgeVersion, + ForgeInstallerProfile, + ForgeLegacyInfo, + fml_libs_for_version, + ForgeInstallerProfileV2, + InstallerInfo, + DerivedForgeIndex, + ForgeLegacyInfoList, +) from meta.model.mojang import MojangVersion LAUNCHER_DIR = launcher_path() @@ -33,22 +56,28 @@ mc_version_cache = {} def load_mc_version_filter(version: str): if version in mc_version_cache: return mc_version_cache[version] - v = MetaVersion.parse_file(os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json")) + v = MetaVersion.parse_file( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json") + ) libs = set(map(attrgetter("name"), v.libraries)) mc_version_cache[version] = libs return libs -''' +""" Match a library coordinate to a set of library coordinates. * Block those that pass completely. * For others, block those with lower versions than in the set. -''' +""" def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpecifier): for ver in libs: - if ver.group == match.group and ver.artifact == match.artifact and ver.classifier == match.classifier: + if ( + ver.group == match.group + and ver.artifact == match.artifact + and ver.classifier == match.classifier + ): if ver.version == match.version: # Everything is matched perfectly - this one will be ignored return True @@ -61,7 +90,9 @@ def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpeci return False -def version_from_profile(profile: ForgeInstallerProfile, version: ForgeVersion) -> MetaVersion: +def version_from_profile( + profile: ForgeInstallerProfile, version: ForgeVersion +) -> MetaVersion: v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) mc_version = profile.install.minecraft v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] @@ -74,7 +105,7 @@ def version_from_profile(profile: ForgeInstallerProfile, version: ForgeVersion) match = expression.search(args) while match is not None: tweakers.append(match.group(1)) - args = args[:match.start()] + args[match.end():] + args = args[: match.start()] + args[match.end() :] match = expression.search(args) if len(tweakers) > 0: args = args.strip() @@ -84,14 +115,21 @@ def version_from_profile(profile: ForgeInstallerProfile, version: ForgeVersion) v.libraries = [] mc_filter = load_mc_version_filter(mc_version) for forge_lib in profile.version_info.libraries: - if forge_lib.name.is_lwjgl() or forge_lib.name.is_log4j() or should_ignore_artifact(mc_filter, forge_lib.name): + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): continue overridden_name = forge_lib.name if overridden_name.group == "net.minecraftforge": if overridden_name.artifact == "minecraftforge": overridden_name.artifact = "forge" - overridden_name.version = "%s-%s" % (mc_version, overridden_name.version) + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) overridden_name.classifier = "universal" elif overridden_name.artifact == "forge": @@ -110,7 +148,9 @@ def version_from_profile(profile: ForgeInstallerProfile, version: ForgeVersion) return v -def version_from_modernized_installer(installer: MojangVersion, version: ForgeVersion) -> MetaVersion: +def version_from_modernized_installer( + installer: MojangVersion, version: ForgeVersion +) -> MetaVersion: v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) mc_version = version.mc_version v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] @@ -123,7 +163,7 @@ def version_from_modernized_installer(installer: MojangVersion, version: ForgeVe match = expression.search(args) while match is not None: tweakers.append(match.group(1)) - args = args[:match.start()] + args[match.end():] + args = args[: match.start()] + args[match.end() :] match = expression.search(args) if len(tweakers) > 0: args = args.strip() @@ -134,8 +174,14 @@ def version_from_modernized_installer(installer: MojangVersion, version: ForgeVe mc_filter = load_mc_version_filter(mc_version) for upstream_lib in installer.libraries: - forge_lib = Library.parse_obj(upstream_lib.dict()) # "cast" MojangLibrary to Library - if forge_lib.name.is_lwjgl() or forge_lib.name.is_log4j() or should_ignore_artifact(mc_filter, forge_lib.name): + forge_lib = Library.parse_obj( + upstream_lib.dict() + ) # "cast" MojangLibrary to Library + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): continue if forge_lib.name.group == "net.minecraftforge": @@ -143,16 +189,23 @@ def version_from_modernized_installer(installer: MojangVersion, version: ForgeVe overridden_name = forge_lib.name overridden_name.classifier = "universal" forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) forge_lib.name = overridden_name elif forge_lib.name.artifact == "minecraftforge": overridden_name = forge_lib.name overridden_name.artifact = "forge" overridden_name.classifier = "universal" - overridden_name.version = "%s-%s" % (mc_version, overridden_name.version) + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) forge_lib.name = overridden_name v.libraries.append(forge_lib) @@ -167,23 +220,32 @@ def version_from_legacy(info: ForgeLegacyInfo, version: ForgeVersion) -> MetaVer v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] v.release_time = info.release_time v.order = 5 - if fml_libs_for_version(mc_version): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING + if fml_libs_for_version( + mc_version + ): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING v.additional_traits = ["legacyFML"] classifier = "client" if "universal" in version.url(): classifier = "universal" - main_mod = Library(name=GradleSpecifier("net.minecraftforge", "forge", version.long_version, classifier)) + main_mod = Library( + name=GradleSpecifier( + "net.minecraftforge", "forge", version.long_version, classifier + ) + ) main_mod.downloads = MojangLibraryDownloads() - main_mod.downloads.artifact = MojangArtifact(url=version.url(), sha1=info.sha1, size=info.size) + main_mod.downloads.artifact = MojangArtifact( + url=version.url(), sha1=info.sha1, size=info.size + ) main_mod.downloads.artifact.path = None v.jar_mods = [main_mod] return v -def version_from_build_system_installer(installer: MojangVersion, profile: ForgeInstallerProfileV2, - version: ForgeVersion) -> MetaVersion: +def version_from_build_system_installer( + installer: MojangVersion, profile: ForgeInstallerProfileV2, version: ForgeVersion +) -> MetaVersion: v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" @@ -193,14 +255,19 @@ def version_from_build_system_installer(installer: MojangVersion, profile: Forge # load the locally cached installer file info and use it to add the installer entry in the json info = InstallerInfo.parse_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json")) + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") + ) installer_lib = Library( - name=GradleSpecifier("net.minecraftforge", "forge", version.long_version, "installer")) + name=GradleSpecifier( + "net.minecraftforge", "forge", version.long_version, "installer" + ) + ) installer_lib.downloads = MojangLibraryDownloads() installer_lib.downloads.artifact = MojangArtifact( url="https://maven.minecraftforge.net/%s" % (installer_lib.name.path()), sha1=info.sha1hash, - size=info.size) + size=info.size, + ) v.maven_files.append(installer_lib) for upstream_lib in profile.libraries: @@ -208,18 +275,27 @@ def version_from_build_system_installer(installer: MojangVersion, profile: Forge if forge_lib.name.is_log4j(): continue - if forge_lib.name.group == "net.minecraftforge" and forge_lib.name.artifact == "forge" \ - and forge_lib.name.classifier == "universal": - forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + if ( + forge_lib.name.group == "net.minecraftforge" + and forge_lib.name.artifact == "forge" + and forge_lib.name.classifier == "universal" + ): + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + ) v.maven_files.append(forge_lib) v.libraries = [] - wrapper_lib = Library(name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2")) + wrapper_lib = Library( + name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2") + ) wrapper_lib.downloads = MojangLibraryDownloads() - wrapper_lib.downloads.artifact = MojangArtifact(url=FORGEWRAPPER_MAVEN % (wrapper_lib.name.path()), - sha1="4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", - size=34444) + wrapper_lib.downloads.artifact = MojangArtifact( + url=FORGEWRAPPER_MAVEN % (wrapper_lib.name.path()), + sha1="4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", + size=34444, + ) v.libraries.append(wrapper_lib) for upstream_lib in installer.libraries: @@ -231,15 +307,19 @@ def version_from_build_system_installer(installer: MojangVersion, profile: Forge if forge_lib.name.artifact == "forge": forge_lib.name.classifier = "launcher" forge_lib.downloads.artifact.path = forge_lib.name.path() - forge_lib.downloads.artifact.url = "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + ) forge_lib.name = forge_lib.name v.libraries.append(forge_lib) v.release_time = installer.release_time v.order = 5 - mc_args = "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " \ - "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " \ - "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + mc_args = ( + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " + "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " + "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + ) for arg in installer.arguments.game: mc_args += f" {arg}" v.minecraft_arguments = mc_args @@ -248,10 +328,14 @@ def version_from_build_system_installer(installer: MojangVersion, profile: Forge def main(): # load the locally cached version list - remote_versions = DerivedForgeIndex.parse_file(os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE)) + remote_versions = DerivedForgeIndex.parse_file( + os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) + ) recommended_versions = [] - legacy_info_list = ForgeLegacyInfoList.parse_file(os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE)) + legacy_info_list = ForgeLegacyInfoList.parse_file( + os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE) + ) legacy_versions = [ "1.1", "1.2.3", @@ -307,27 +391,41 @@ def main(): eprint("Skipping %s with no valid files" % key) continue eprint("Processing Forge %s" % version.rawVersion) - version_elements = version.rawVersion.split('.') + version_elements = version.rawVersion.split(".") if len(version_elements) < 1: eprint("Skipping version %s with not enough version elements" % key) continue major_version_str = version_elements[0] if not major_version_str.isnumeric(): - eprint("Skipping version %s with non-numeric major version %s" % (key, major_version_str)) + eprint( + "Skipping version %s with non-numeric major version %s" + % (key, major_version_str) + ) continue if entry.recommended: recommended_versions.append(version.rawVersion) # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile(os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json")): - eprint("Skipping %s with no corresponding Minecraft version %s" % (key, version.mc_version_sane)) + if not os.path.isfile( + os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" + ) + ): + eprint( + "Skipping %s with no corresponding Minecraft version %s" + % (key, version.mc_version_sane) + ) continue # Path for new-style build system based installers - installer_version_filepath = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json") - profile_filepath = os.path.join(UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json") + installer_version_filepath = os.path.join( + UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" + ) + profile_filepath = os.path.join( + UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" + ) eprint(installer_version_filepath) if os.path.isfile(installer_version_filepath): @@ -351,8 +449,13 @@ def main(): if version.mc_version_sane == "1.6.1": continue build = version.build - if not str(build).encode('utf-8').decode('utf8') in legacy_info_list.number: - eprint("Legacy build %d is missing in legacy info. Ignoring." % build) + if ( + str(build).encode("utf-8").decode("utf8") + not in legacy_info_list.number + ): + eprint( + "Legacy build %d is missing in legacy info. Ignoring." % build + ) continue v = version_from_legacy(legacy_info_list.number[str(build)], version) @@ -361,12 +464,16 @@ def main(): recommended_versions.sort() - print('Recommended versions:', recommended_versions) + print("Recommended versions:", recommended_versions) - package = MetaPackage(uid=FORGE_COMPONENT, name="Forge", project_url="https://www.minecraftforge.net/forum/") + package = MetaPackage( + uid=FORGE_COMPONENT, + name="Forge", + project_url="https://www.minecraftforge.net/forum/", + ) package.recommended = recommended_versions package.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, "package.json")) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/generateLiteloader.py b/generateLiteloader.py index 9f730da1c2..2fe95fcc42 100755 --- a/generateLiteloader.py +++ b/generateLiteloader.py @@ -14,14 +14,15 @@ UPSTREAM_DIR = upstream_path() ensure_component_dir(LITELOADER_COMPONENT) -def process_artefacts(mc_version: str, artefacts: Dict[str, LiteloaderArtefact], is_snapshot: bool) \ - -> Tuple[List[MetaVersion], Optional[MetaVersion]]: +def process_artefacts( + mc_version: str, artefacts: Dict[str, LiteloaderArtefact], is_snapshot: bool +) -> Tuple[List[MetaVersion], Optional[MetaVersion]]: versions: List[MetaVersion] = [] lookup: Dict[str, MetaVersion] = {} latest_version = None latest = None for x, artefact in artefacts.items(): - if x == 'latest': + if x == "latest": latest_version = artefact.version continue v = MetaVersion( @@ -34,7 +35,8 @@ def process_artefacts(mc_version: str, artefacts: Dict[str, LiteloaderArtefact], main_class="net.minecraft.launchwrapper.Launch", order=10, libraries=artefact.libraries, - type="release") + type="release", + ) if is_snapshot: v.type = "snapshot" @@ -48,7 +50,7 @@ def process_artefacts(mc_version: str, artefacts: Dict[str, LiteloaderArtefact], liteloader_lib = Library( name=GradleSpecifier("com.mumfrey", "liteloader", v.version), - url="http://dl.liteloader.com/versions/" + url="http://dl.liteloader.com/versions/", ) if is_snapshot: liteloader_lib.mmcHint = "always-stale" @@ -72,10 +74,14 @@ def process_versions(index: LiteloaderIndex) -> Tuple[List[MetaVersion], List[st latest_release = None if versionObject.artefacts: - versions, latest_release = process_artefacts(mcVersion, versionObject.artefacts.liteloader, False) + versions, latest_release = process_artefacts( + mcVersion, versionObject.artefacts.liteloader, False + ) all_versions.extend(versions) if versionObject.snapshots: - versions, latest_snapshot = process_artefacts(mcVersion, versionObject.snapshots.liteloader, True) + versions, latest_snapshot = process_artefacts( + mcVersion, versionObject.snapshots.liteloader, True + ) all_versions.extend(versions) if latest_release: @@ -93,16 +99,20 @@ def main(): all_versions, recommended = process_versions(index) for version in all_versions: - version.write(os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, f"{version.version}.json")) - - package = MetaPackage(uid=LITELOADER_COMPONENT, - name='LiteLoader', - description=index.meta.description, - project_url=index.meta.url, - authors=[index.meta.authors], - recommended=recommended) + version.write( + os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, f"{version.version}.json") + ) + + package = MetaPackage( + uid=LITELOADER_COMPONENT, + name="LiteLoader", + description=index.meta.description, + project_url=index.meta.url, + authors=[index.meta.authors], + recommended=recommended, + ) package.write(os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, "package.json")) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/generateMojang.py b/generateMojang.py index f5617e161b..4f100efb95 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -8,11 +8,32 @@ from packaging import version as pversion from typing import Optional, List from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path -from meta.common.mojang import VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, LWJGL_COMPONENT, \ - STATIC_OVERRIDES_FILE, VERSIONS_DIR, LIBRARY_PATCHES_FILE -from meta.model import MetaVersion, Library, GradleSpecifier, MojangLibraryDownloads, MojangArtifact, Dependency, \ - MetaPackage, MojangRules -from meta.model.mojang import MojangIndexWrap, MojangIndex, MojangVersion, LegacyOverrideIndex, LibraryPatches +from meta.common.mojang import ( + VERSION_MANIFEST_FILE, + MINECRAFT_COMPONENT, + LWJGL3_COMPONENT, + LWJGL_COMPONENT, + STATIC_OVERRIDES_FILE, + VERSIONS_DIR, + LIBRARY_PATCHES_FILE, +) +from meta.model import ( + MetaVersion, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + Dependency, + MetaPackage, + MojangRules, +) +from meta.model.mojang import ( + MojangIndexWrap, + MojangIndex, + MojangVersion, + LegacyOverrideIndex, + LibraryPatches, +) APPLY_SPLIT_NATIVES_WORKAROUND = True @@ -30,7 +51,10 @@ def map_log4j_artifact(version): if x <= pversion.parse("2.0"): return "2.0-beta9-fixed", "https://files.prismlauncher.org/maven/%s" if x <= pversion.parse("2.17.1"): - 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.17.1", + "https://repo1.maven.org/maven2/%s", + ) # This is the only version that's patched (as of 2022/02/19) return None, None @@ -38,27 +62,27 @@ LOG4J_HASHES = { "2.0-beta9-fixed": { "log4j-api": { "sha1": "b61eaf2e64d8b0277e188262a8b771bbfa1502b3", - "size": 107347 + "size": 107347, }, "log4j-core": { "sha1": "677991ea2d7426f76309a73739cecf609679492c", - "size": 677588 - } + "size": 677588, + }, }, "2.17.1": { "log4j-api": { "sha1": "d771af8e336e372fb5399c99edabe0919aeaf5b2", - "size": 301872 + "size": 301872, }, "log4j-core": { "sha1": "779f60f3844dadc3ef597976fcb1e5127b1f343d", - "size": 1790452 + "size": 1790452, }, "log4j-slf4j18-impl": { "sha1": "ca499d751f4ddd8afb016ef698c30be0da1d09f7", - "size": 21268 - } - } + "size": 21268, + }, + }, } # We want versions that contain natives for all platforms. If there are multiple, pick the latest one @@ -116,7 +140,7 @@ def sort_libs_by_name(library): return library.name -LWJGLEntry = namedtuple('LWJGLEntry', ('version', 'sha1')) +LWJGLEntry = namedtuple("LWJGLEntry", ("version", "sha1")) lwjglVersionVariants = defaultdict(list) @@ -154,19 +178,19 @@ def adapt_new_style_arguments(arguments): # grab the strings, log the complex stuff for arg in arguments.game: if isinstance(arg, str): - if arg == '--clientId': + if arg == "--clientId": continue - if arg == '${clientid}': + if arg == "${clientid}": continue - if arg == '--xuid': + if arg == "--xuid": continue - if arg == '${auth_xuid}': + if arg == "${auth_xuid}": continue foo.append(arg) else: print("!!! Unrecognized structure in Minecraft game arguments:") pprint(arg) - return ' '.join(foo) + return " ".join(foo) def is_macos_only(rules: Optional[MojangRules]): @@ -214,21 +238,23 @@ def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): new_libraries += patch_library(lib, patches) v.libraries += list(dict.fromkeys(new_libraries)) - if lwjgl_version[0] == '2': + if lwjgl_version[0] == "2": filename = os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") - v.name = 'LWJGL 2' + v.name = "LWJGL 2" v.uid = LWJGL_COMPONENT v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] - elif lwjgl_version[0] == '3': + elif lwjgl_version[0] == "3": filename = os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") - v.name = 'LWJGL 3' + v.name = "LWJGL 3" v.uid = LWJGL3_COMPONENT v.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 - filtered_libraries = list(filter(lambda l: l.name.artifact not in ["jutils", "jinput"], v.libraries)) + filtered_libraries = list( + filter(lambda l: l.name.artifact not in ["jutils", "jinput"], v.libraries) + ) v.libraries = filtered_libraries else: raise Exception("LWJGL version not recognized: %s" % v.version) @@ -240,7 +266,7 @@ def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): # skip libraries without natives or that we patched if not lib.natives or lib in new_libraries: continue - checked_dict = {'linux', 'windows', 'osx'} + checked_dict = {"linux", "windows", "osx"} if not checked_dict.issubset(lib.natives.keys()): print("Missing system classifier!", v.version, lib.name, lib.natives.keys()) good = False @@ -249,8 +275,13 @@ def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): for entry in checked_dict: baked_entry = lib.natives[entry] if baked_entry not in lib.downloads.classifiers: - print("Missing download for classifier!", v.version, lib.name, baked_entry, - lib.downloads.classifiers.keys()) + print( + "Missing download for classifier!", + v.version, + lib.name, + baked_entry, + lib.downloads.classifiers.keys(), + ) good = False break if good: @@ -274,8 +305,12 @@ def version_has_split_natives(v: MojangVersion) -> bool: def main(): # get the local version list - override_index = LegacyOverrideIndex.parse_file(os.path.join(STATIC_DIR, STATIC_OVERRIDES_FILE)) - library_patches = LibraryPatches.parse_file(os.path.join(STATIC_DIR, LIBRARY_PATCHES_FILE)) + override_index = LegacyOverrideIndex.parse_file( + os.path.join(STATIC_DIR, STATIC_OVERRIDES_FILE) + ) + library_patches = LibraryPatches.parse_file( + os.path.join(STATIC_DIR, LIBRARY_PATCHES_FILE) + ) found_any_lwjgl3 = False @@ -286,7 +321,9 @@ def main(): continue print("Processing", filename) mojang_version = MojangVersion.parse_file(input_file) - v = mojang_version.to_meta_version("Minecraft", MINECRAFT_COMPONENT, mojang_version.id) + v = mojang_version.to_meta_version( + "Minecraft", MINECRAFT_COMPONENT, mojang_version.id + ) libs_minecraft = [] new_libs_minecraft = [] @@ -321,10 +358,17 @@ def main(): rules = lib.rules lib.rules = None if is_macos_only(rules): - print("Candidate library ", specifier, " is only for macOS and is therefore ignored.") + print( + "Candidate library ", + specifier, + " is only for macOS and is therefore ignored.", + ) continue bucket = add_or_get_bucket(buckets, rules) - if specifier.group == "org.lwjgl.lwjgl" and specifier.artifact == "lwjgl": + if ( + specifier.group == "org.lwjgl.lwjgl" + and specifier.artifact == "lwjgl" + ): bucket.version = specifier.version if specifier.group == "org.lwjgl" and specifier.artifact == "lwjgl": is_lwjgl_3 = True @@ -340,22 +384,31 @@ def main(): if version_override and maven_override: if version_override not in LOG4J_HASHES: - raise Exception("ERROR: unhandled log4j version (overriden) %s!" % version_override) + raise Exception( + "ERROR: unhandled log4j version (overriden) %s!" + % version_override + ) if lib.name.artifact not in LOG4J_HASHES[version_override]: - raise Exception("ERROR: unhandled log4j artifact %s!" % lib.name.artifact) + raise Exception( + "ERROR: unhandled log4j artifact %s!" % lib.name.artifact + ) - replacement_name = GradleSpecifier("org.apache.logging.log4j", lib.name.artifact, version_override) + replacement_name = GradleSpecifier( + "org.apache.logging.log4j", lib.name.artifact, version_override + ) artifact = MojangArtifact( url=maven_override % (replacement_name.path()), sha1=LOG4J_HASHES[version_override][lib.name.artifact]["sha1"], - size=LOG4J_HASHES[version_override][lib.name.artifact]["size"] + size=LOG4J_HASHES[version_override][lib.name.artifact]["size"], ) - libs_minecraft.append(Library( - name=replacement_name, - downloads=MojangLibraryDownloads(artifact=artifact) - )) + libs_minecraft.append( + Library( + name=replacement_name, + downloads=MojangLibraryDownloads(artifact=artifact), + ) + ) else: libs_minecraft.append(lib) else: @@ -374,9 +427,12 @@ def main(): continue lwjgl = buckets[key] if None in buckets: - lwjgl.libraries = sorted(lwjgl.libraries + buckets[None].libraries, key=attrgetter("name")) + lwjgl.libraries = sorted( + lwjgl.libraries + buckets[None].libraries, + key=attrgetter("name"), + ) else: - lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter('name')) + lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) add_lwjgl_version(lwjglVersionVariants, lwjgl) print("Found candidate LWJGL", lwjgl.version, key) # remove the common bucket... @@ -393,9 +449,9 @@ def main(): if is_lwjgl_3: lwjgl_dependency.suggests = suggested_version else: - lwjgl_dependency.suggests = '2.9.4-nightly-20150209' + lwjgl_dependency.suggests = "2.9.4-nightly-20150209" else: - bad_versions = {'3.1.6', '3.2.1'} + bad_versions = {"3.1.6", "3.2.1"} our_versions = set() for lwjgl in iter(buckets.values()): @@ -403,10 +459,13 @@ def main(): if our_versions == bad_versions: print("Found broken 3.1.6/3.2.1 combo, forcing LWJGL to 3.2.1") - suggested_version = '3.2.1' + suggested_version = "3.2.1" lwjgl_dependency.suggests = suggested_version else: - raise Exception("ERROR: cannot determine single suggested LWJGL version in %s" % mojang_version.id) + raise Exception( + "ERROR: cannot determine single suggested LWJGL version in %s" + % mojang_version.id + ) # if it uses LWJGL 3, add the trait that enables starting on first thread on macOS if is_lwjgl_3: @@ -418,7 +477,9 @@ def main(): # process 1.13 arguments into previous version if not mojang_version.minecraft_arguments and mojang_version.arguments: v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) - out_filename = os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{v.version}.json") + out_filename = os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{v.version}.json" + ) if v.version in override_index.versions: override = override_index.versions[v.version] override.apply_onto_meta_version(v) @@ -428,7 +489,10 @@ def main(): decided_variant = None passed_variants = 0 unknown_variants = 0 - print("%d variant(s) for LWJGL %s:" % (len(lwjglVersionVariants[lwjglVersionVariant]), lwjglVersionVariant)) + print( + "%d variant(s) for LWJGL %s:" + % (len(lwjglVersionVariants[lwjglVersionVariant]), lwjglVersionVariant) + ) for variant in lwjglVersionVariants[lwjglVersionVariant]: if variant.sha1 in BAD_VARIANTS: @@ -440,32 +504,46 @@ def main(): passed_variants += 1 continue # print natives classifiers to decide which variant to use - n = [x.natives.keys() for x in variant.version.libraries if x.natives is not None] + n = [ + x.natives.keys() + for x in variant.version.libraries + if x.natives is not None + ] print(n) - print(f" \"{variant.sha1}\", # {lwjglVersionVariant} ({variant.version.release_time})") + print( + f' "{variant.sha1}", # {lwjglVersionVariant} ({variant.version.release_time})' + ) unknown_variants += 1 print("") if decided_variant and passed_variants == 1 and unknown_variants == 0: process_single_variant(decided_variant.version, library_patches) else: - raise Exception("No variant decided for version %s out of %d possible ones and %d unknown ones." % ( - lwjglVersionVariant, passed_variants, unknown_variants)) + raise Exception( + "No variant decided for version %s out of %d possible ones and %d unknown ones." + % (lwjglVersionVariant, passed_variants, unknown_variants) + ) - lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name='LWJGL 2') + lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name="LWJGL 2") lwjgl_package.write(os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, "package.json")) if found_any_lwjgl3: - lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name='LWJGL 3') - lwjgl_package.write(os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, "package.json")) + lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name="LWJGL 3") + lwjgl_package.write( + os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, "package.json") + ) - mojang_index = MojangIndexWrap(MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE))) + mojang_index = MojangIndexWrap( + MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE)) + ) - minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name='Minecraft') + minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name="Minecraft") minecraft_package.recommended = [mojang_index.latest.release] - minecraft_package.write(os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, "package.json")) + minecraft_package.write( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, "package.json") + ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/generateQuilt.py b/generateQuilt.py index e628dac944..b8a881ad8c 100755 --- a/generateQuilt.py +++ b/generateQuilt.py @@ -1,9 +1,20 @@ import json import os -from meta.common import ensure_component_dir, launcher_path, upstream_path, transform_maven_key -from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT, \ - USE_QUILT_MAPPINGS +from meta.common import ( + ensure_component_dir, + launcher_path, + upstream_path, + transform_maven_key, +) +from meta.common.quilt import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + INTERMEDIARY_COMPONENT, + LOADER_COMPONENT, + USE_QUILT_MAPPINGS, +) from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses @@ -15,15 +26,21 @@ ensure_component_dir(INTERMEDIARY_COMPONENT) def load_jar_info(artifact_key) -> FabricJarInfo: - return FabricJarInfo.parse_file(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json")) + return FabricJarInfo.parse_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") + ) def load_installer_info(version) -> FabricInstallerDataV1: - return FabricInstallerDataV1.parse_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json")) + return FabricInstallerDataV1.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") + ) def process_loader_version(entry) -> (MetaVersion, bool): - should_recommend = "-" not in entry["version"] # Don't recommend pre releases as per SemVer + should_recommend = ( + "-" not in entry["version"] + ) # Don't recommend pre releases as per SemVer jar_info = load_jar_info(transform_maven_key(entry["maven"])) installer_info = load_installer_info(entry["version"]) @@ -40,8 +57,10 @@ def process_loader_version(entry) -> (MetaVersion, bool): v.libraries = [] v.libraries.extend(installer_info.libraries.common) v.libraries.extend(installer_info.libraries.client) - loader_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), - url="https://maven.quiltmc.org/repository/release") + loader_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release", + ) v.libraries.append(loader_lib) return v, should_recommend @@ -49,15 +68,21 @@ def process_loader_version(entry) -> (MetaVersion, bool): def process_intermediary_version(entry) -> MetaVersion: jar_info = load_jar_info(transform_maven_key(entry["maven"])) - v = MetaVersion(name="Quilt Intermediary Mappings", uid=INTERMEDIARY_COMPONENT, version=entry["version"]) + v = MetaVersion( + name="Quilt Intermediary Mappings", + uid=INTERMEDIARY_COMPONENT, + version=entry["version"], + ) v.release_time = jar_info.release_time - v.requires = [Dependency(uid='net.minecraft', equals=entry["version"])] + v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] v.order = 11 v.type = "release" v.libraries = [] v.volatile = True - intermediary_lib = Library(name=GradleSpecifier.from_string(entry["maven"]), - url="https://maven.quiltmc.org/repository/release") + intermediary_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release", + ) v.libraries.append(intermediary_lib) return v @@ -66,7 +91,9 @@ def main(): recommended_loader_versions = [] recommended_intermediary_versions = [] - with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as f: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as f: loader_version_index = json.load(f) for entry in loader_version_index: version = entry["version"] @@ -74,13 +101,17 @@ def main(): v, should_recommend = process_loader_version(entry) - if not recommended_loader_versions and should_recommend: # newest stable loader is recommended + if ( + not recommended_loader_versions and should_recommend + ): # newest stable loader is recommended recommended_loader_versions.append(version) v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) if USE_QUILT_MAPPINGS: - with open(os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), 'r', encoding='utf-8') as f: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), "r", encoding="utf-8" + ) as f: intermediary_version_index = json.load(f) for entry in intermediary_version_index: version = entry["version"] @@ -88,11 +119,17 @@ def main(): v = process_intermediary_version(entry) - recommended_intermediary_versions.append(version) # all intermediaries are recommended + recommended_intermediary_versions.append( + version + ) # all intermediaries are recommended - v.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json")) + v.write( + os.path.join( + LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json" + ) + ) - package = MetaPackage(uid=LOADER_COMPONENT, name='Quilt Loader') + package = MetaPackage(uid=LOADER_COMPONENT, name="Quilt Loader") package.recommended = recommended_loader_versions package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." package.project_url = "https://quiltmc.org/" @@ -100,13 +137,17 @@ def main(): package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) if USE_QUILT_MAPPINGS: - package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Quilt Intermediary Mappings') + package = MetaPackage( + uid=INTERMEDIARY_COMPONENT, name="Quilt Intermediary Mappings" + ) package.recommended = recommended_intermediary_versions package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." package.project_url = "https://quiltmc.org/" package.authors = ["Quilt Project"] - package.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json")) + package.write( + os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json") + ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/index.py b/index.py index 00c7b54671..38687037f4 100755 --- a/index.py +++ b/index.py @@ -4,7 +4,12 @@ from operator import attrgetter from meta.common import launcher_path from meta.model import MetaVersion, MetaPackage -from meta.model.index import MetaPackageIndex, MetaVersionIndex, MetaVersionIndexEntry, MetaPackageIndexEntry +from meta.model.index import ( + MetaPackageIndex, + MetaVersionIndex, + MetaVersionIndexEntry, + MetaPackageIndexEntry, +) LAUNCHER_DIR = launcher_path() @@ -29,7 +34,9 @@ for package in sorted(os.listdir(LAUNCHER_DIR)): if package in ignore: continue - sharedData = MetaPackage.parse_file(os.path.join(LAUNCHER_DIR, package, "package.json")) + sharedData = MetaPackage.parse_file( + os.path.join(LAUNCHER_DIR, package, "package.json") + ) recommendedVersions = set() if sharedData.recommended: recommendedVersions = set(sharedData.recommended) @@ -48,12 +55,16 @@ for package in sorted(os.listdir(LAUNCHER_DIR)): versionFile = MetaVersion.parse_file(filepath) is_recommended = versionFile.version in recommendedVersions - versionEntry = MetaVersionIndexEntry.from_meta_version(versionFile, is_recommended, filehash) + versionEntry = MetaVersionIndexEntry.from_meta_version( + versionFile, is_recommended, filehash + ) versionList.versions.append(versionEntry) # sort the versions in descending order by time of release - versionList.versions = sorted(versionList.versions, key=attrgetter('release_time'), reverse=True) + versionList.versions = sorted( + versionList.versions, key=attrgetter("release_time"), reverse=True + ) # write the version index for the package outFilePath = LAUNCHER_DIR + "/%s/index.json" % package @@ -61,9 +72,7 @@ for package in sorted(os.listdir(LAUNCHER_DIR)): # insert entry into the package index packageEntry = MetaPackageIndexEntry( - uid=package, - name=sharedData.name, - sha256=hash_file(hashlib.sha256, outFilePath) + uid=package, name=sharedData.name, sha256=hash_file(hashlib.sha256, outFilePath) ) packages.packages.append(packageEntry) diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 10b35da50d..7a6514b2be 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -76,10 +76,9 @@ def merge_dict(base: dict, overlay: dict): def default_session(): - forever_cache = FileCache('caches/http_cache', forever=True) + forever_cache = FileCache("caches/http_cache", forever=True) sess = CacheControl(requests.Session(), forever_cache) sess.headers.update({"User-Agent": "PrismLauncherMeta/1.0"}) return sess - diff --git a/meta/common/http.py b/meta/common/http.py index c057e4b06f..20f9d0d135 100644 --- a/meta/common/http.py +++ b/meta/common/http.py @@ -1,5 +1,5 @@ def download_binary_file(sess, path, url): - with open(path, 'wb') as f: + with open(path, "wb") as f: r = sess.get(url) r.raise_for_status() for chunk in r.iter_content(chunk_size=128): diff --git a/meta/model/__init__.py b/meta/model/__init__.py index dc466c3b0b..0246cdb3d1 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -5,21 +5,32 @@ from typing import Optional, List, Dict, Any, Iterator import pydantic from pydantic import Field, validator -from ..common import serialize_datetime, replace_old_launchermeta_url, get_all_bases, merge_dict +from ..common import ( + serialize_datetime, + replace_old_launchermeta_url, + get_all_bases, + merge_dict, +) META_FORMAT_VERSION = 1 class GradleSpecifier: """ - A gradle specifier - a maven coordinate. Like one of these: - "org.lwjgl.lwjgl:lwjgl:2.9.0" - "net.java.jinput:jinput:2.0.5" - "net.minecraft:launchwrapper:1.5" + A gradle specifier - a maven coordinate. Like one of these: + "org.lwjgl.lwjgl:lwjgl:2.9.0" + "net.java.jinput:jinput:2.0.5" + "net.minecraft:launchwrapper:1.5" """ - def __init__(self, group: str, artifact: str, version: str, classifier: Optional[str] = None, - extension: Optional[str] = None): + def __init__( + self, + group: str, + artifact: str, + version: str, + classifier: Optional[str] = None, + extension: Optional[str] = None, + ): if extension is None: extension = "jar" self.group = group @@ -29,22 +40,33 @@ class GradleSpecifier: self.extension = extension def __str__(self): - ext = '' - if self.extension != 'jar': + ext = "" + if self.extension != "jar": ext = "@%s" % self.extension if self.classifier: - return "%s:%s:%s:%s%s" % (self.group, self.artifact, self.version, self.classifier, ext) + return "%s:%s:%s:%s%s" % ( + self.group, + self.artifact, + self.version, + self.classifier, + ext, + ) else: return "%s:%s:%s%s" % (self.group, self.artifact, self.version, ext) def filename(self): if self.classifier: - return "%s-%s-%s.%s" % (self.artifact, self.version, self.classifier, self.extension) + return "%s-%s-%s.%s" % ( + self.artifact, + self.version, + self.classifier, + self.extension, + ) else: return "%s-%s.%s" % (self.artifact, self.version, self.extension) def base(self): - return "%s/%s/%s/" % (self.group.replace('.', '/'), self.artifact, self.version) + return "%s/%s/%s/" % (self.group.replace(".", "/"), self.artifact, self.version) def path(self): return self.base() + self.filename() @@ -53,7 +75,12 @@ class GradleSpecifier: return f"GradleSpecifier('{self}')" def is_lwjgl(self): - return self.group in ("org.lwjgl", "org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils") + return self.group in ( + "org.lwjgl", + "org.lwjgl.lwjgl", + "net.java.jinput", + "net.java.jutils", + ) def is_log4j(self): return self.group == "org.apache.logging.log4j" @@ -76,9 +103,9 @@ class GradleSpecifier: @classmethod def from_string(cls, v: str): - ext_split = v.split('@') + ext_split = v.split("@") - components = ext_split[0].split(':') + components = ext_split[0].split(":") group = components[0] artifact = components[1] version = components[2] @@ -114,7 +141,9 @@ class MetaBase(pydantic.BaseModel): if k in kwargs: del kwargs[k] - return super(MetaBase, self).json(exclude_none=True, sort_keys=True, by_alias=True, indent=4, **kwargs) + return super(MetaBase, self).json( + exclude_none=True, sort_keys=True, by_alias=True, indent=4, **kwargs + ) def write(self, file_path): with open(file_path, "w") as f: @@ -157,10 +186,7 @@ class MetaBase(pydantic.BaseModel): class Config: allow_population_by_field_name = True - json_encoders = { - datetime: serialize_datetime, - GradleSpecifier: str - } + json_encoders = {datetime: serialize_datetime, GradleSpecifier: str} class Versioned(MetaBase): @@ -193,18 +219,19 @@ class MojangArtifact(MojangArtifactBase): class MojangLibraryExtractRules(MetaBase): """ - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx" - } - } - ] + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + } + ] """ + exclude: List[str] # TODO maybe drop this completely? @@ -216,7 +243,15 @@ class MojangLibraryDownloads(MetaBase): class OSRule(MetaBase): @validator("name") def name_must_be_os(cls, v): - assert v in ["osx", "linux", "windows", "windows-arm64", "osx-arm64", "linux-arm64", "linux-arm32"] + assert v in [ + "osx", + "linux", + "windows", + "windows-arm64", + "osx-arm64", + "linux-arm64", + "linux-arm32", + ] return v name: str diff --git a/meta/model/forge.py b/meta/model/forge.py index 6112023e15..937cc18cb5 100644 --- a/meta/model/forge.py +++ b/meta/model/forge.py @@ -17,7 +17,9 @@ class ForgeFile(MetaBase): def url(self, long_version): return "https://maven.minecraftforge.net/net/minecraftforge/forge/%s/%s" % ( - long_version, self.filename(long_version)) + long_version, + self.filename(long_version), + ) class ForgeEntry(MetaBase): @@ -42,7 +44,9 @@ class DerivedForgeIndex(MetaBase): by_mc_version: Dict[str, ForgeMCVersionInfo] = Field({}, alias="by_mcversion") -class FMLLib(MetaBase): # old ugly stuff. Maybe merge this with Library or MojangLibrary later +class FMLLib( + MetaBase +): # old ugly stuff. Maybe merge this with Library or MojangLibrary later filename: str checksum: str ours: bool @@ -74,6 +78,7 @@ class ForgeInstallerProfileInstallSection(MetaBase): "modList":"none" }, """ + profile_name: str = Field(alias="profileName") target: str path: GradleSpecifier @@ -116,6 +121,7 @@ class ForgeOptional(MetaBase): } ] """ + name: Optional[str] client: Optional[bool] server: Optional[bool] @@ -206,7 +212,9 @@ class ForgeVersion: if (classifier == "installer") and (extension == "jar"): self.installer_filename = filename self.installer_url = url - if (classifier == "universal" or classifier == "client") and (extension == "jar" or extension == "zip"): + if (classifier == "universal" or classifier == "client") and ( + extension == "jar" or extension == "zip" + ): self.universal_filename = filename self.universal_url = url if (classifier == "changelog") and (extension == "txt"): @@ -236,7 +244,7 @@ class ForgeVersion: if self.url() is None: return False - foo = self.rawVersion.split('.') + foo = self.rawVersion.split(".") if len(foo) < 1: return False @@ -252,55 +260,106 @@ class ForgeVersion: def fml_libs_for_version(mc_version: str) -> List[FMLLib]: - argo_2_25 = FMLLib(filename="argo-2.25.jar", - checksum="bb672829fde76cb163004752b86b0484bd0a7f4b", - ours=False) - argo_small_3_2 = FMLLib(filename="argo-small-3.2.jar", - checksum="58912ea2858d168c50781f956fa5b59f0f7c6b51", - ours=False) - guava_12_0_1 = FMLLib(filename="guava-12.0.1.jar", - checksum="b8e78b9af7bf45900e14c6f958486b6ca682195f", - ours=False) - guava_14_0_rc3 = FMLLib(filename="guava-14.0-rc3.jar", - checksum="931ae21fa8014c3ce686aaa621eae565fefb1a6a", - ours=False) - asm_all_4_0 = FMLLib(filename="asm-all-4.0.jar", - checksum="98308890597acb64047f7e896638e0d98753ae82", - ours=False) - asm_all_4_1 = FMLLib(filename="asm-all-4.1.jar", - checksum="054986e962b88d8660ae4566475658469595ef58", - ours=False) - bcprov_jdk15on_147 = FMLLib(filename="bcprov-jdk15on-147.jar", - checksum="b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", - ours=False) - bcprov_jdk15on_148 = FMLLib(filename="bcprov-jdk15on-148.jar", - checksum="960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", - ours=True) - scala_library = FMLLib(filename="scala-library.jar", - checksum="458d046151ad179c85429ed7420ffb1eaf6ddf85", - ours=True) - - deobfuscation_data_1_5 = FMLLib(filename="deobfuscation_data_1.5.zip", - checksum="5f7c142d53776f16304c0bbe10542014abad6af8", - ours=False) - - deobfuscation_data_1_5_1 = FMLLib(filename="deobfuscation_data_1.5.1.zip", - checksum="22e221a0d89516c1f721d6cab056a7e37471d0a6", - ours=False) - deobfuscation_data_1_5_2 = FMLLib(filename="deobfuscation_data_1.5.2.zip", - checksum="446e55cd986582c70fcf12cb27bc00114c5adfd9", - ours=False) + argo_2_25 = FMLLib( + filename="argo-2.25.jar", + checksum="bb672829fde76cb163004752b86b0484bd0a7f4b", + ours=False, + ) + argo_small_3_2 = FMLLib( + filename="argo-small-3.2.jar", + checksum="58912ea2858d168c50781f956fa5b59f0f7c6b51", + ours=False, + ) + guava_12_0_1 = FMLLib( + filename="guava-12.0.1.jar", + checksum="b8e78b9af7bf45900e14c6f958486b6ca682195f", + ours=False, + ) + guava_14_0_rc3 = FMLLib( + filename="guava-14.0-rc3.jar", + checksum="931ae21fa8014c3ce686aaa621eae565fefb1a6a", + ours=False, + ) + asm_all_4_0 = FMLLib( + filename="asm-all-4.0.jar", + checksum="98308890597acb64047f7e896638e0d98753ae82", + ours=False, + ) + asm_all_4_1 = FMLLib( + filename="asm-all-4.1.jar", + checksum="054986e962b88d8660ae4566475658469595ef58", + ours=False, + ) + bcprov_jdk15on_147 = FMLLib( + filename="bcprov-jdk15on-147.jar", + checksum="b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", + ours=False, + ) + bcprov_jdk15on_148 = FMLLib( + filename="bcprov-jdk15on-148.jar", + checksum="960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", + ours=True, + ) + scala_library = FMLLib( + filename="scala-library.jar", + checksum="458d046151ad179c85429ed7420ffb1eaf6ddf85", + ours=True, + ) + + deobfuscation_data_1_5 = FMLLib( + filename="deobfuscation_data_1.5.zip", + checksum="5f7c142d53776f16304c0bbe10542014abad6af8", + ours=False, + ) + + deobfuscation_data_1_5_1 = FMLLib( + filename="deobfuscation_data_1.5.1.zip", + checksum="22e221a0d89516c1f721d6cab056a7e37471d0a6", + ours=False, + ) + deobfuscation_data_1_5_2 = FMLLib( + filename="deobfuscation_data_1.5.2.zip", + checksum="446e55cd986582c70fcf12cb27bc00114c5adfd9", + ours=False, + ) if mc_version == "1.3.2": return [argo_2_25, guava_12_0_1, asm_all_4_0] - elif mc_version in ["1.4", "1.4.1", "1.4.2", "1.4.3", "1.4.4", "1.4.5", "1.4.6", "1.4.7"]: + elif mc_version in [ + "1.4", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "1.4.6", + "1.4.7", + ]: return [argo_2_25, guava_12_0_1, asm_all_4_0, bcprov_jdk15on_147] elif mc_version == "1.5": - return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5, - scala_library] + return [ + argo_small_3_2, + guava_14_0_rc3, + asm_all_4_1, + bcprov_jdk15on_148, + deobfuscation_data_1_5, + scala_library, + ] elif mc_version == "1.5.1": - return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_1, - scala_library] + return [ + argo_small_3_2, + guava_14_0_rc3, + asm_all_4_1, + bcprov_jdk15on_148, + deobfuscation_data_1_5_1, + scala_library, + ] elif mc_version == "1.5.2": - return [argo_small_3_2, guava_14_0_rc3, asm_all_4_1, bcprov_jdk15on_148, deobfuscation_data_1_5_2, - scala_library] + return [ + argo_small_3_2, + guava_14_0_rc3, + asm_all_4_1, + bcprov_jdk15on_148, + deobfuscation_data_1_5_2, + scala_library, + ] return [] diff --git a/meta/model/index.py b/meta/model/index.py index f7cdc36e0f..c6d82e1aff 100644 --- a/meta/model/index.py +++ b/meta/model/index.py @@ -26,7 +26,7 @@ class MetaVersionIndexEntry(MetaBase): conflicts=v.conflicts, recommended=recommended, volatile=v.volatile, - sha256=sha256 + sha256=sha256, ) diff --git a/meta/model/liteloader.py b/meta/model/liteloader.py index 0bd6794773..64cdaadd7e 100644 --- a/meta/model/liteloader.py +++ b/meta/model/liteloader.py @@ -14,13 +14,14 @@ class LiteloaderDev(MetaBase): class LiteloaderRepo(MetaBase): """ - "repo":{ - "stream":"RELEASE", - "type":"m2", - "url":"http://dl.liteloader.com/repo/", - "classifier":"" - }, + "repo":{ + "stream":"RELEASE", + "type":"m2", + "url":"http://dl.liteloader.com/repo/", + "classifier":"" + }, """ + stream: str type: str url: str @@ -29,26 +30,27 @@ class LiteloaderRepo(MetaBase): class LiteloaderArtefact(MetaBase): """ - "53639d52340479ccf206a04f5e16606f":{ - "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", - "libraries":[ - { - "name":"net.minecraft:launchwrapper:1.5" - }, - { - "name":"net.sf.jopt-simple:jopt-simple:4.5" - }, - { - "name":"org.ow2.asm:asm-all:4.1" - } - ], - "stream":"RELEASE", - "file":"liteloader-1.5.2_01.jar", - "version":"1.5.2_01", - "md5":"53639d52340479ccf206a04f5e16606f", - "timestamp":"1367366420" - }, + "53639d52340479ccf206a04f5e16606f":{ + "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", + "libraries":[ + { + "name":"net.minecraft:launchwrapper:1.5" + }, + { + "name":"net.sf.jopt-simple:jopt-simple:4.5" + }, + { + "name":"org.ow2.asm:asm-all:4.1" + } + ], + "stream":"RELEASE", + "file":"liteloader-1.5.2_01.jar", + "version":"1.5.2_01", + "md5":"53639d52340479ccf206a04f5e16606f", + "timestamp":"1367366420" + }, """ + tweakClass: str libraries: List[Library] stream: str @@ -69,17 +71,18 @@ class LiteloaderArtefacts(MetaBase): class LiteloaderEntry(MetaBase): """ - "1.10.2":{ - "dev": { ... }, - "repo":{ ... }, - "artefacts":{ - "com.mumfrey:liteloader":{ }, - ... - }, - "snapshots":{ - ... - } + "1.10.2":{ + "dev": { ... }, + "repo":{ ... }, + "artefacts":{ + "com.mumfrey:liteloader":{ }, + ... + }, + "snapshots":{ + ... + } """ + dev: Optional[LiteloaderDev] repo: LiteloaderRepo artefacts: Optional[LiteloaderArtefacts] @@ -88,14 +91,15 @@ class LiteloaderEntry(MetaBase): class LiteloaderMeta(MetaBase): """ - "meta":{ - "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", - "authors":"Mumfrey", - "url":"http://dl.liteloader.com", - "updated":"2017-02-22T11:34:07+00:00", - "updatedTime":1487763247 - }, + "meta":{ + "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", + "authors":"Mumfrey", + "url":"http://dl.liteloader.com", + "updated":"2017-02-22T11:34:07+00:00", + "updatedTime":1487763247 + }, """ + description: str authors: str url: str diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 9f9a29c01a..2e35634008 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -3,17 +3,24 @@ from typing import Optional, List, Dict, Any, Iterator from pydantic import validator, Field -from . import MetaBase, MojangArtifactBase, MojangAssets, MojangLibrary, MojangArtifact, MojangLibraryDownloads, \ - Library, MetaVersion, GradleSpecifier +from . import ( + MetaBase, + MojangArtifactBase, + MojangAssets, + MojangLibrary, + MojangArtifact, + MojangLibraryDownloads, + Library, + MetaVersion, + GradleSpecifier, +) SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 DEFAULT_JAVA_MAJOR = 8 # By default, we should recommend Java 8 if we don't know better -COMPATIBLE_JAVA_MAPPINGS = { - 16: [17] -} +COMPATIBLE_JAVA_MAPPINGS = {16: [17]} -''' +""" Mojang index files look like this: { "latest": { @@ -32,7 +39,7 @@ Mojang index files look like this: ... ] } -''' +""" class MojangLatestVersion(MetaBase): @@ -75,7 +82,9 @@ class ExperimentIndex(MetaBase): 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) + self.versions: Dict[str, ExperimentEntry] = dict( + (x.id, x) for x in index.experiments + ) class OldSnapshotEntry(MetaBase): @@ -94,7 +103,9 @@ class OldSnapshotIndex(MetaBase): class OldSnapshotIndexWrap: def __init__(self, index: OldSnapshotIndex): self.index: OldSnapshotIndex = index - self.versions: Dict[str, OldSnapshotEntry] = dict((x.id, x) for x in index.old_snapshots) + self.versions: Dict[str, OldSnapshotEntry] = dict( + (x.id, x) for x in index.old_snapshots + ) class LegacyOverrideEntry(MetaBase): @@ -200,8 +211,7 @@ class MojangVersion(MetaBase): applet_class: Optional[str] = Field(alias="appletClass") processArguments: Optional[str] minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") - minimum_launcher_version: Optional[int] = Field( - alias="minimumLauncherVersion") + minimum_launcher_version: Optional[int] = Field(alias="minimumLauncherVersion") release_time: Optional[datetime] = Field(alias="releaseTime") time: Optional[datetime] type: Optional[str] @@ -216,10 +226,17 @@ class MojangVersion(MetaBase): 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) + 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", self.id, "client"), downloads=downloads) + main_jar = Library( + name=GradleSpecifier("com.mojang", "minecraft", self.id, "client"), + downloads=downloads, + ) if not self.compliance_level: # both == 0 and is None pass @@ -231,11 +248,15 @@ class MojangVersion(MetaBase): raise Exception(f"Unsupported compliance level {self.compliance_level}") major = DEFAULT_JAVA_MAJOR - if self.javaVersion is not None: # some versions don't have this. TODO: maybe maintain manual overrides + 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 in COMPATIBLE_JAVA_MAPPINGS: # add more compatible Java versions, e.g. 16 and 17 both work for MC 1.17 + if ( + major in COMPATIBLE_JAVA_MAPPINGS + ): # add more compatible Java versions, e.g. 16 and 17 both work for MC 1.17 compatible_java_majors += COMPATIBLE_JAVA_MAPPINGS[major] if new_type == "pending": # experiments from upstream are type=pending @@ -253,4 +274,5 @@ class MojangVersion(MetaBase): type=new_type, compatible_java_majors=compatible_java_majors, additional_traits=addn_traits, - main_jar=main_jar) + main_jar=main_jar, + ) diff --git a/updateFabric.py b/updateFabric.py index 1656e16057..9bb3dac48e 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -3,8 +3,18 @@ import os import zipfile from datetime import datetime -from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key, default_session -from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, DATETIME_FORMAT_HTTP +from meta.common import ( + upstream_path, + ensure_upstream_dir, + transform_maven_key, + default_session, +) +from meta.common.fabric import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + DATETIME_FORMAT_HTTP, +) from meta.model.fabric import FabricJarInfo UPSTREAM_DIR = upstream_path() @@ -26,13 +36,15 @@ def filehash(filename, hashtype, blocksize=65536): def get_maven_url(maven_key, server, ext): parts = maven_key.split(":", 3) - maven_ver_url = server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + maven_ver_url = ( + server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + ) maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext return maven_url def get_json_file(path, url): - with open(path, 'w', encoding='utf-8') as f: + with open(path, "w", encoding="utf-8") as f: r = sess.get(url) r.raise_for_status() version_json = r.json() @@ -47,7 +59,7 @@ def head_file(url): def get_binary_file(path, url): - with open(path, 'wb') as f: + with open(path, "wb") as f: r = sess.get(url) r.raise_for_status() for chunk in r.iter_content(chunk_size=128): @@ -82,21 +94,35 @@ def compute_jar_file(path, url): def main(): # get the version list for each component we are interested in for component in ["intermediary", "loader"]: - index = get_json_file(os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), - "https://meta.fabricmc.net/v2/versions/" + component) + index = get_json_file( + os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.fabricmc.net/v2/versions/" + component, + ) for it in index: print(f"Processing {component} {it['version']} ") - jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") - compute_jar_file(os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), jar_maven_url) + jar_maven_url = get_maven_url( + it["maven"], "https://maven.fabricmc.net/", ".jar" + ) + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) # for each loader, download installer JSON file from maven - with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) for it in loader_version_index: print(f"Downloading JAR info for loader {it['version']} ") - maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") - get_json_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), maven_url) + maven_url = get_maven_url( + it["maven"], "https://maven.fabricmc.net/", ".json" + ) + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/updateForge.py b/updateForge.py index 64ccb6a0c6..8bae3768be 100755 --- a/updateForge.py +++ b/updateForge.py @@ -16,11 +16,27 @@ from pprint import pprint from pydantic import ValidationError from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session -from meta.common.forge import JARS_DIR, INSTALLER_INFO_DIR, INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, \ - FILE_MANIFEST_DIR, BAD_VERSIONS, STATIC_LEGACYINFO_FILE -from meta.model.forge import ForgeFile, ForgeEntry, ForgeMCVersionInfo, ForgeLegacyInfoList, DerivedForgeIndex, \ - ForgeVersion, ForgeInstallerProfile, ForgeInstallerProfileV2, InstallerInfo, \ - ForgeLegacyInfo +from meta.common.forge import ( + JARS_DIR, + INSTALLER_INFO_DIR, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + FILE_MANIFEST_DIR, + BAD_VERSIONS, + STATIC_LEGACYINFO_FILE, +) +from meta.model.forge import ( + ForgeFile, + ForgeEntry, + ForgeMCVersionInfo, + ForgeLegacyInfoList, + DerivedForgeIndex, + ForgeVersion, + ForgeInstallerProfile, + ForgeInstallerProfileV2, + InstallerInfo, + ForgeLegacyInfo, +) from meta.model.mojang import MojangVersion UPSTREAM_DIR = upstream_path() @@ -55,18 +71,21 @@ def get_single_forge_files_manifest(longversion): files_manifest_file = Path(path_thing) from_file = False if files_manifest_file.is_file(): - with open(path_thing, 'r') as f: + with open(path_thing, "r") as f: files_json = json.load(f) from_file = True else: - file_url = 'https://files.minecraftforge.net/net/minecraftforge/forge/%s/meta.json' % longversion + file_url = ( + "https://files.minecraftforge.net/net/minecraftforge/forge/%s/meta.json" + % longversion + ) r = sess.get(file_url) r.raise_for_status() files_json = r.json() ret_dict = dict() - for classifier, extensionObj in files_json.get('classifiers').items(): + for classifier, extensionObj in files_json.get("classifiers").items(): assert type(classifier) == str assert type(extensionObj) == dict @@ -82,33 +101,40 @@ def get_single_forge_files_manifest(longversion): if not type(hashtype) == str: pprint(classifier) pprint(extensionObj) - print('%s: Skipping missing hash for extension %s:' % (longversion, extension)) + print( + "%s: Skipping missing hash for extension %s:" + % (longversion, extension) + ) index += 1 continue assert type(classifier) == str processed_hash = re.sub(r"\W", "", hashtype) if not len(processed_hash) == 32: - print('%s: Skipping invalid hash for extension %s:' % (longversion, extension)) + print( + "%s: Skipping invalid hash for extension %s:" + % (longversion, extension) + ) pprint(extensionObj) index += 1 continue file_obj = ForgeFile( - classifier=classifier, - hash=processed_hash, - extension=extension + classifier=classifier, hash=processed_hash, extension=extension ) if count == 0: ret_dict[classifier] = file_obj index += 1 count += 1 else: - print('%s: Multiple objects detected for classifier %s:' % (longversion, classifier)) + print( + "%s: Multiple objects detected for classifier %s:" + % (longversion, classifier) + ) pprint(extensionObj) assert False if not from_file: - with open(path_thing, 'w', encoding='utf-8') as f: + with open(path_thing, "w", encoding="utf-8") as f: json.dump(files_json, f, sort_keys=True, indent=4) return ret_dict @@ -116,18 +142,23 @@ def get_single_forge_files_manifest(longversion): def main(): # get the remote version list fragments - r = sess.get('https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json') + r = sess.get( + "https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json" + ) r.raise_for_status() main_json = r.json() assert type(main_json) == dict - r = sess.get('https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json') + r = sess.get( + "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json" + ) r.raise_for_status() promotions_json = r.json() assert type(promotions_json) == dict promoted_key_expression = re.compile( - "(?P[^-]+)-(?P(latest)|(recommended))(-(?P[a-zA-Z0-9\\.]+))?") + "(?P[^-]+)-(?P(latest)|(recommended))(-(?P[a-zA-Z0-9\\.]+))?" + ) recommended_set = set() @@ -140,28 +171,31 @@ def main(): # Therefore we only use the short version part for later identification and filter out the branch-specific # promotions (among other errors). print("Processing promotions:") - for promoKey, shortversion in promotions_json.get('promos').items(): + for promoKey, shortversion in promotions_json.get("promos").items(): match = promoted_key_expression.match(promoKey) if not match: - print('Skipping promotion %s, the key did not parse:' % promoKey) + print("Skipping promotion %s, the key did not parse:" % promoKey) pprint(promoKey) assert match - if not match.group('mc'): - print('Skipping promotion %s, because it has no Minecraft version.' % promoKey) + if not match.group("mc"): + print( + "Skipping promotion %s, because it has no Minecraft version." % promoKey + ) continue - if match.group('branch'): - print('Skipping promotion %s, because it on a branch only.' % promoKey) + if match.group("branch"): + print("Skipping promotion %s, because it on a branch only." % promoKey) continue - elif match.group('promotion') == 'recommended': + elif match.group("promotion") == "recommended": recommended_set.add(shortversion) - print('%s added to recommended set' % shortversion) - elif match.group('promotion') == 'latest': + print("%s added to recommended set" % shortversion) + elif match.group("promotion") == "latest": pass else: assert False version_expression = re.compile( - "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$") + "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$" + ) print("") print("Processing versions:") @@ -174,15 +208,15 @@ def main(): if not match: pprint(long_version) assert match - assert match.group('mc') == mc_version + assert match.group("mc") == mc_version files = get_single_forge_files_manifest(long_version) - build = int(match.group('build')) - version = match.group('ver') - branch = match.group('branch') + build = int(match.group("build")) + version = match.group("ver") + branch = match.group("branch") - is_recommended = (version in recommended_set) + is_recommended = version in recommended_set entry = ForgeEntry( long_version=long_version, @@ -193,7 +227,7 @@ def main(): # NOTE: we add this later after the fact. The forge promotions file lies about these. latest=False, recommended=is_recommended, - files=files + files=files, ) new_index.versions[long_version] = entry if not new_index.by_mc_version: @@ -218,10 +252,10 @@ def main(): print("") print("Dumping index files...") - with open(UPSTREAM_DIR + "/forge/maven-metadata.json", 'w', encoding='utf-8') as f: + with open(UPSTREAM_DIR + "/forge/maven-metadata.json", "w", encoding="utf-8") as f: json.dump(main_json, f, sort_keys=True, indent=4) - with open(UPSTREAM_DIR + "/forge/promotions_slim.json", 'w', encoding='utf-8') as f: + with open(UPSTREAM_DIR + "/forge/promotions_slim.json", "w", encoding="utf-8") as f: json.dump(promotions_json, f, sort_keys=True, indent=4) new_index.write(UPSTREAM_DIR + "/forge/derived_index.json") @@ -247,11 +281,20 @@ def main(): jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) if version.uses_installer(): - installer_info_path = UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version - profile_path = UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.long_version - version_file_path = UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version + installer_info_path = ( + UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + + "/forge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version + ) - installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile(installer_info_path) + installer_refresh_required = not os.path.isfile( + profile_path + ) or not os.path.isfile(installer_info_path) if installer_refresh_required: # grab the installer if it's not there @@ -259,7 +302,7 @@ def main(): eprint("Downloading %s" % version.url()) rfile = sess.get(version.url(), stream=True) rfile.raise_for_status() - with open(jar_path, 'wb') as f: + with open(jar_path, "wb") as f: for chunk in rfile.iter_content(chunk_size=128): f.write(chunk) @@ -269,17 +312,17 @@ def main(): print(jar_path) with zipfile.ZipFile(jar_path) as jar: with suppress(KeyError): - with jar.open('version.json') as profile_zip_entry: + with jar.open("version.json") as profile_zip_entry: version_data = profile_zip_entry.read() # Process: does it parse? MojangVersion.parse_raw(version_data) - with open(version_file_path, 'wb') as versionJsonFile: + with open(version_file_path, "wb") as versionJsonFile: versionJsonFile.write(version_data) versionJsonFile.close() - with jar.open('install_profile.json') as profile_zip_entry: + with jar.open("install_profile.json") as profile_zip_entry: install_profile_data = profile_zip_entry.read() # Process: does it parse? @@ -301,9 +344,11 @@ def main(): raise exception else: eprint( - "Version %s is not supported and won't be generated later." % version.long_version) + "Version %s is not supported and won't be generated later." + % version.long_version + ) - with open(profile_path, 'wb') as profileFile: + with open(profile_path, "wb") as profileFile: profileFile.write(install_profile_data) profileFile.close() @@ -326,7 +371,7 @@ def main(): if not os.path.isfile(jar_path): rfile = sess.get(version.url(), stream=True) rfile.raise_for_status() - with open(jar_path, 'wb') as f: + with open(jar_path, "wb") as f: for chunk in rfile.iter_content(chunk_size=128): f.write(chunk) # find the latest timestamp in the zip file @@ -348,5 +393,5 @@ def main(): legacy_info_list.write(LEGACYINFO_PATH) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/updateLiteloader.py b/updateLiteloader.py index ebdfaefa24..383644754d 100755 --- a/updateLiteloader.py +++ b/updateLiteloader.py @@ -14,7 +14,7 @@ sess = default_session() def main(): # get the remote version list - r = sess.get('http://dl.liteloader.com/versions/versions.json') + r = sess.get("http://dl.liteloader.com/versions/versions.json") r.raise_for_status() # make sure it's JSON @@ -33,5 +33,5 @@ def main(): remote_versions.write(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/updateMojang.py b/updateMojang.py index 315cac395d..8d3a2296e0 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -4,10 +4,22 @@ import zipfile from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session from meta.common.http import download_binary_file -from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR, STATIC_EXPERIMENTS_FILE, \ - STATIC_OLD_SNAPSHOTS_FILE -from meta.model.mojang import MojangIndexWrap, MojangIndex, ExperimentIndex, ExperimentIndexWrap, OldSnapshotIndexWrap, \ - OldSnapshotIndex +from meta.common.mojang import ( + BASE_DIR, + VERSION_MANIFEST_FILE, + VERSIONS_DIR, + ASSETS_DIR, + STATIC_EXPERIMENTS_FILE, + STATIC_OLD_SNAPSHOTS_FILE, +) +from meta.model.mojang import ( + MojangIndexWrap, + MojangIndex, + ExperimentIndex, + ExperimentIndexWrap, + OldSnapshotIndexWrap, + OldSnapshotIndex, +) UPSTREAM_DIR = upstream_path() STATIC_DIR = static_path() @@ -31,7 +43,7 @@ def fetch_zipped_version(path, url): assert version_json - with open(path, 'w', encoding='utf-8') as f: + with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) return version_json @@ -45,16 +57,14 @@ def fetch_modified_version(path, version): version_json["releaseTime"] = version_json["releaseTime"] + "T00:00:00+02:00" version_json["time"] = version_json["releaseTime"] - downloads = {"client": {"url": version.jar, - "sha1": version.sha1, - "size": version.size - } - } + downloads = { + "client": {"url": version.jar, "sha1": version.sha1, "size": version.size} + } version_json["downloads"] = downloads version_json["type"] = "old_snapshot" - with open(path, 'w', encoding='utf-8') as f: + with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) return version_json @@ -65,7 +75,7 @@ def fetch_version(path, url): r.raise_for_status() version_json = r.json() - with open(path, 'w', encoding='utf-8') as f: + with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) return version_json @@ -73,7 +83,7 @@ def fetch_version(path, url): def main(): # get the remote version list - r = sess.get('https://piston-meta.mojang.com/mc/game/version_manifest_v2.json') + r = sess.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json") r.raise_for_status() remote_versions = MojangIndexWrap(MojangIndex(**r.json())) @@ -83,7 +93,9 @@ def main(): if os.path.exists(version_manifest_path): # get the local version list - current_versions = MojangIndexWrap(MojangIndex.parse_file(version_manifest_path)) + current_versions = MojangIndexWrap( + MojangIndex.parse_file(version_manifest_path) + ) local_ids = set(current_versions.versions.keys()) # versions not present locally but present remotely are new @@ -99,13 +111,22 @@ def main(): for x in pending_ids: version = remote_versions.versions[x] - 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) + 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) if os.path.exists(static_experiments_path): - experiments = ExperimentIndexWrap(ExperimentIndex.parse_file(static_experiments_path)) + experiments = ExperimentIndexWrap( + ExperimentIndex.parse_file(static_experiments_path) + ) experiment_ids = set(experiments.versions.keys()) for x in experiment_ids: @@ -122,7 +143,9 @@ def main(): # deal with old snapshots if os.path.exists(static_old_snapshots_path): - old_snapshots = OldSnapshotIndexWrap(OldSnapshotIndex.parse_file(static_old_snapshots_path)) + old_snapshots = OldSnapshotIndexWrap( + OldSnapshotIndex.parse_file(static_old_snapshots_path) + ) old_snapshots_ids = set(old_snapshots.versions.keys()) for x in old_snapshots_ids: @@ -138,5 +161,5 @@ def main(): remote_versions.index.write(version_manifest_path) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/updateQuilt.py b/updateQuilt.py index 244d0b0d78..71d7f63f69 100755 --- a/updateQuilt.py +++ b/updateQuilt.py @@ -5,7 +5,12 @@ from datetime import datetime import requests -from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key, default_session +from meta.common import ( + upstream_path, + ensure_upstream_dir, + transform_maven_key, + default_session, +) from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, USE_QUILT_MAPPINGS from meta.common.fabric import DATETIME_FORMAT_HTTP from meta.model.fabric import FabricJarInfo @@ -29,13 +34,15 @@ def filehash(filename, hashtype, blocksize=65536): def get_maven_url(maven_key, server, ext): parts = maven_key.split(":", 3) - maven_ver_url = server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + maven_ver_url = ( + server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + ) maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext return maven_url def get_json_file(path, url): - with open(path, 'w', encoding='utf-8') as f: + with open(path, "w", encoding="utf-8") as f: r = sess.get(url) r.raise_for_status() version_json = r.json() @@ -50,7 +57,7 @@ def head_file(url): def get_binary_file(path, url): - with open(path, 'wb') as f: + with open(path, "wb") as f: r = sess.get(url) r.raise_for_status() for chunk in r.iter_content(chunk_size=128): @@ -88,21 +95,35 @@ def main(): if USE_QUILT_MAPPINGS: components.append("hashed") for component in components: - index = get_json_file(os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), - "https://meta.quiltmc.org/v3/versions/" + component) + index = get_json_file( + os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.quiltmc.org/v3/versions/" + component, + ) for it in index: print(f"Processing {component} {it['version']} ") - jar_maven_url = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar") - compute_jar_file(os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), jar_maven_url) + jar_maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar" + ) + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) # for each loader, download installer JSON file from maven - with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) for it in loader_version_index: print(f"Downloading JAR info for loader {it['version']} ") - maven_url = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".json") - get_json_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), maven_url) + maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".json" + ) + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) -if __name__ == '__main__': +if __name__ == "__main__": main() -- cgit 0.0.5-2-1-g0f52 From ac5171ea4411803c731ad6e5ea3d7cc8d0f49208 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 10 May 2023 02:38:16 -0700 Subject: feat: fetch java metadata Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- meta/common/java.py | 10 ++ meta/common/mojang.py | 2 + meta/model/__init__.py | 4 +- meta/model/java.py | 439 +++++++++++++++++++++++++++++++++++++++++++++++++ meta/model/mojang.py | 42 +++++ updateJava.py | 157 ++++++++++++++++++ updateMojang.py | 17 ++ 7 files changed, 669 insertions(+), 2 deletions(-) create mode 100644 meta/common/java.py create mode 100644 meta/model/java.py create mode 100644 updateJava.py (limited to 'meta') diff --git a/meta/common/java.py b/meta/common/java.py new file mode 100644 index 0000000000..8de3c47c4e --- /dev/null +++ b/meta/common/java.py @@ -0,0 +1,10 @@ +from os.path import join + +BASE_DIR = "java_runtime" + +RELEASE_FILE = join(BASE_DIR, "releases.json") +ADOPTIUM_DIR = join(BASE_DIR, "adoptium") +AZUL_DIR = join(BASE_DIR, "azul") + +ADOPTIUM_VERSIONS_DIR = join(ADOPTIUM_DIR, "versions") +AZUL_VERSIONS_DIR = join(AZUL_DIR, "versions") \ No newline at end of file diff --git a/meta/common/mojang.py b/meta/common/mojang.py index dc80f44412..562ae594d7 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -14,3 +14,5 @@ LIBRARY_PATCHES_FILE = join(BASE_DIR, "library-patches.json") MINECRAFT_COMPONENT = "net.minecraft" LWJGL_COMPONENT = "org.lwjgl" LWJGL3_COMPONENT = "org.lwjgl3" + +JAVA_MANIFEST_FILE = join(BASE_DIR, "java_all.json") \ No newline at end of file diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 0246cdb3d1..0428b7f1fb 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -129,7 +129,7 @@ class GradleSpecifier: class MetaBase(pydantic.BaseModel): - def dict(self, **kwargs) -> Dict[str, Any]: + def dict(self, **kwargs: Any) -> Dict[str, Any]: for k in ["by_alias"]: if k in kwargs: del kwargs[k] @@ -145,7 +145,7 @@ class MetaBase(pydantic.BaseModel): exclude_none=True, sort_keys=True, by_alias=True, indent=4, **kwargs ) - def write(self, file_path): + def write(self, file_path: str): with open(file_path, "w") as f: f.write(self.json()) diff --git a/meta/model/java.py b/meta/model/java.py new file mode 100644 index 0000000000..d4d2e00cb9 --- /dev/null +++ b/meta/model/java.py @@ -0,0 +1,439 @@ +from . import ( + MetaBase, +) +from pydantic import Field +from datetime import datetime +from enum import Enum +from typing import Optional, List, Dict, Any, Iterator, Iterable, NamedTuple +from collections import namedtuple +from urllib.parse import urljoin, urlencode, urlparse, urlunparse + +# namedtuple to match the internal signature of urlunparse + + +class URLComponents(NamedTuple): + scheme: str + netloc: str + url: str + path: str + query: str + fragment: str + + +class APIQuery(MetaBase): + + def to_query(self): + set_parts: dict[str, Any] = {} + for key, value in self.dict().items(): + if value is not None: + if isinstance(value, Enum): + set_parts[key] = value.value + elif isinstance(value, list): + if len(value) > 0: + set_parts[key] = value + elif isinstance(value, datetime): + set_parts[key] = value.isoformat() + else: + set_parts[key] = value + return urlencode(set_parts, doseq=True) + + +class AdoptiumJvmImpl(Enum): + Hostspot = "hotspot" + + +class AdoptiumVendor(Enum): + Eclipse = "eclipse" + + +class AdoptiumArchitecture(Enum): + X64 = "x64" + X86 = "x86" + X32 = "x32" + Ppc64 = "ppc64" + Ppc64le = "ppc64le" + S390x = "s390x" + Aarch64 = "aarch64" + Arm = "arm" + Sparcv9 = "sparcv9" + Riscv64 = "riscv64" + + +class AdoptiumReleaseType(Enum): + GenralAccess = "ga" + EarlyAccess = "ea" + + +class AdoptiumSortMethod(Enum): + Default = "DEFAULT" + Date = "DATE" + + +class AdoptiumSortOrder(Enum): + Asc = "ASC" + Desc = "DESC" + + +class AdoptiumImageType(Enum): + Jdk = "jdk" + Jre = "jre" + Testimage = "testimage" + Debugimage = "debugimage" + Staticlibs = "staticlibs" + Sources = "sources" + Sbom = "sbom" + + +class AdoptiumHeapSize(Enum): + Normal = "normal" + Large = "large" + + +class AdoptiumProject(Enum): + Jdk = "jdk" + Valhalla = "valhalla" + Metropolis = "metropolis" + Jfr = "jfr" + Shenandoah = "shenandoah" + + +class AdoptiumCLib(Enum): + Musl = "musl" + Glibc = "Glibc" + + +class AdoptiumOs(Enum): + Linux = "linux" + Windows = "windows" + Mac = "mac" + Solaris = "solaris" + Aix = "aix" + AlpineLinux = "alpine-linux" + + +ADOPTIUM_API_BASE = " https://api.adoptium.net" +ADOPTIUM_API_FEATURE_RELEASES = f"{ADOPTIUM_API_BASE}/v3/assets/feature_releases/{{feature_version}}/{{release_type}}" +# ?image_type={{image_type}}&heap_size={{heap_size}}&project={{project}}&vender={{vender}}&page_size={{page_size}}&page={{page}}&sort_method={{sort_method}}&sort_order={{sort_order}} +ADOPTIUM_API_AVAILABLE_RELEASES = f"{ADOPTIUM_API_BASE}/v3/info/available_releases" + + +class AdoptiumAPIFeatureReleasesQuery(APIQuery): + architecture: Optional[AdoptiumArchitecture] = None + before: Optional[datetime] = None + c_lib: Optional[AdoptiumCLib] = None + heap_size: Optional[AdoptiumHeapSize] = AdoptiumHeapSize.Normal + image_type: Optional[AdoptiumImageType] = None + jvm_impl: Optional[AdoptiumJvmImpl] = None + os: Optional[AdoptiumOs] = None + page_size: int = 10 + page: int = 0 + project: Optional[AdoptiumProject] = AdoptiumProject.Jdk + sort_method: Optional[AdoptiumSortMethod] = AdoptiumSortMethod.Default + sort_order: Optional[AdoptiumSortOrder] = AdoptiumSortOrder.Desc + vender: Optional[AdoptiumVendor] = AdoptiumVendor.Eclipse + + +def adoptiumAPIFeatureReleases( + feature: int, + release_type: AdoptiumReleaseType = AdoptiumReleaseType.GenralAccess, + query: AdoptiumAPIFeatureReleasesQuery = AdoptiumAPIFeatureReleasesQuery() +): + url = urlparse(ADOPTIUM_API_FEATURE_RELEASES.format( + feature_version=feature, + release_type=release_type.value, + )) + return urlunparse(url._replace(query=query.to_query())) + + +class AdoptiumAvailableReleases(MetaBase): + available_releases: list[int] + available_lts_releases: list[int] + most_recent_lts: Optional[int] + most_recent_feature_release: Optional[int] + most_recent_feature_version: Optional[int] + tip_version: Optional[int] + + +class AdoptiumFile(MetaBase): + name: str + link: str + size: Optional[int] + + +class AdoptiumPackage(AdoptiumFile): + checksum: Optional[str] + checksum_link: Optional[str] + signature_link: Optional[str] + download_count: Optional[int] + metadata_link: Optional[str] + + +class AdoptiumBinary(MetaBase): + os: str + architecture: AdoptiumArchitecture + image_type: AdoptiumImageType + c_lib: Optional[AdoptiumCLib] + jvm_impl: AdoptiumJvmImpl + package: Optional[AdoptiumPackage] + installer: Optional[AdoptiumPackage] + heap_size: AdoptiumHeapSize + download_count: Optional[int] + updated_at: datetime + scm_ref: Optional[str] + project: AdoptiumProject + + +class AdoptiumVersion(MetaBase): + major: Optional[int] + minor: Optional[int] + security: Optional[int] + patch: Optional[int] + pre: Optional[str] + adopt_build_number: Optional[int] + semver: str + openjdk_version: str + build: Optional[int] + optional: Optional[str] + + +class AdoptiumRelease(MetaBase): + release_id: str = Field(alias="id") + release_link: str + release_name: str + timestamp: datetime + updated_at: datetime + binaries: list[AdoptiumBinary] + download_count: Optional[int] + release_type: str + vendor: AdoptiumVendor + version_data: AdoptiumVersion + source: Optional[AdoptiumFile] + release_notes: Optional[AdoptiumFile] + + +class AdoptiumReleasesWrap(MetaBase): + releases: list[AdoptiumRelease] + + +class AzulProduct(Enum): + Zulu = "zulu" + + +class AzulAvailabilityType(Enum): + SA = "SA" + CA = "CA" + NV = "NV" + _LA = "LA" + + +class AzulJavaPackageType(Enum): + Jdk = "jdk" + Jre = "jre" + + +class AzulReleaseType(Enum): + CPU = "CPU" + PSU = "PSU" + LU = "LU" + + +class AzulOs(Enum): + Linux = "linux" + Macos = "macos" + Qnx = "qnx" + Windows = "windows" + Solaris = "solaris" + + +class AzulLibCType(Enum): + Glibc = "glibc" + Uclibc = "uclibc" + Musl = "musl" + + +class AzulCPUGen(Enum): + V5 = "v5" + V6kV6kz = "v6k_v6kz" + V6t2 = "v6t2" + V7 = "v7" + V8 = "v8" + + +class AzulArch(Enum): + Arm = "arm" + X86 = "x86" + Mips = "mips" + Ppc = "ppc" + Sparcv9 = "sparcv9" + Sparc = "sparc" + + +class AzulHwBitness(Enum): + X32 = 32 + X64 = 64 + + +class AzulAbi(Enum): + HardFloat = "hard_float" + SoftFloat = "soft_float" + Spe = "spe" + Any = "any" + + +class AzulArchiveType(Enum): + Deb = "deb" + Rpm = "rpm" + Dmg = "dmg" + Targz = "tar.gz" + Zip = "zip" + Cab = "cab" + Msi = "msi" + + +class AzulReleaseStatus(Enum): + Eval = "eval" + Ea = "ea" + Ga = "ga" + Both = "both" + + +class AzulSupportTerm(Enum): + Sts = "sts" + Mts = "mts" + Lts = "lts" + + +class AzulCertifications(Enum): + Tck = "tck" + _Aqavit = "aqavit" + none = "none" + + +class AzulSignatureType(Enum): + Openpgp = "openpgp" + + +class AzulOsQueryParam(Enum): + Macos = "macos" + Windows = "windows" + Linux = "linux" + LinuxMusl = "linux-musl" + LinuxGlibc = "linux-glibc" + Qnx = "qnx" + Solaris = "solaris" + + +class AzulArchQueryParam(Enum): + X86 = "x86" + X64 = "x64" + Amd64 = "amd64" + I686 = "i686" + Arm = "arm" + Aarch64 = "aarch64" + Aarch32 = "aarch32" + Aarch32sf = "aarch32sf" + Aarch32hf = "aarch32hf" + Ppc = "ppc" + Ppc64 = "ppc64" + Ppc64hf = "ppc64hf" + Ppc32 = "ppc32" + Ppc32spe = "ppc32spe" + Ppc32hf = "ppc32hf" + Sparc = "sparc" + Sparc32 = "sparc32" + Sparcv9 = "sparcv9" + Sparcv9_64 = "sparcv9-64" + + +AZUL_API_BASE = "https://api.azul.com/metadata/v1" +AZUL_API_PACKAGES = f"{AZUL_API_BASE}/zulu/packages/" +AZUL_API_PACKAGE_DETAIL = f"{AZUL_API_BASE}/zulu/packages/{{package_uuid}}" + + +class AzulApiPackagesQuery(APIQuery): + java_version: Optional[str] = None + os: Optional[AzulOsQueryParam] = None + arch: Optional[AzulArchQueryParam] = None + archive_type: Optional[AzulArchiveType] = None + java_package_type: Optional[AzulJavaPackageType] = None + javafx_bundled: Optional[bool] = None + crac_supported: Optional[bool] = None + support_term: Optional[AzulSupportTerm] = None + release_type: Optional[AzulReleaseType] = None + latest: Optional[bool] = None + distro_version: Optional[str] = None + java_package_features: list[str] = [] + release_status: Optional[AzulReleaseStatus] = None + availability_types: list[AzulAvailabilityType] = None + certifications: list[AzulCertifications] = None + include_fields: list[str] = [] + page: int = 0 + page_size: int = 100 + + +def azulApiPackages(query: AzulApiPackagesQuery = AzulApiPackagesQuery()): + url = urlparse(AZUL_API_PACKAGES) + return urlunparse(url._replace(query=query.to_query())) + + +def azulApiPackageDetail(package_uuid: str): + return AZUL_API_PACKAGE_DETAIL.format(package_uuid=package_uuid) + + +class ZuluSignatureDetail(MetaBase): + type: AzulSignatureType + url: str + details: dict[str, Any] + signature_index: int + signature: str + + +class ZuluPackageDetail(MetaBase): + package_uuid: str + name: Optional[str] + md5_hash: Optional[str] + sha256_hash: Optional[str] + build_date: datetime + last_modified: datetime + download_url: str + product: AzulProduct + availability_type: AzulAvailabilityType + java_version: list[int] + openjdk_build_number: Optional[int] + java_package_type: AzulJavaPackageType + javafx_bundled: bool + release_type: AzulReleaseType + os: AzulOs + lib_c_type: Optional[AzulLibCType] + cpu_gen: Optional[list[AzulCPUGen]] + arch: AzulArch + hw_bitness: AzulHwBitness + abi: AzulAbi + archive_type: AzulArchiveType + release_status: AzulReleaseStatus + support_term: AzulSupportTerm + certifications: Optional[list[AzulCertifications]] + latest: Optional[bool] + size: int + distro_version: list[int] + signatures: list[ZuluSignatureDetail] + + +class ZuluPackageList(MetaBase): + package_uuid: str + name: Optional[str] + java_version: list[int] + openjdk_build_number: Optional[int] + latest: Optional[bool] + download_url: str + product: Optional[AzulProduct] + distro_version: list[int] + availability_type: Optional[AzulAvailabilityType] + + +class ZuluPackagesListWrap(MetaBase): + packages: list[ZuluPackageList] + + +class ZuluPackagesDetailListWrap(MetaBase): + packages: list[ZuluPackageDetail] diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 2e35634008..ce178efe2e 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -190,6 +190,48 @@ class JavaVersion(MetaBase): major_version: int = Field(8, alias="majorVersion") +class JavaIndexAvailability(MetaBase): + group: int + progress: int + + +class JavaIndexManifest(MetaBase): + sha1: str + size: int + url: str + + +class JavaIndexVersion(MetaBase): + name: str + released: datetime + + +class JavaRuntime(MetaBase): + availability: JavaIndexAvailability + manifest: JavaIndexManifest + version: JavaIndexVersion + + +class JavaIndexEntry(MetaBase): + java_runtime_alpha: list[JavaRuntime] = Field(alias="java-runtime-alpha") + java_runtime_beta: list[JavaRuntime] = Field(alias="java-runtime-beta") + java_runtime_gamma: list[JavaRuntime] = Field(alias="java-runtime-gamma") + jre_legacy: list[JavaRuntime] = Field(alias="jre-legacy") + minecraft_java_exe: list[JavaRuntime] = Field(alias="minecraft-java-exe") + + +class JavaIndex(MetaBase): + gamecore: JavaIndexEntry + linux: JavaIndexEntry + linux_i386: JavaIndexEntry = Field(alias="linux-i386") + mac_os: JavaIndexEntry = Field(alias="mac-os") + mac_os_arm64: JavaIndexEntry = Field(alias="mac-os-arm64") + windows_arm64: JavaIndexEntry = Field(alias="windows-arm64") + windows_x64: JavaIndexEntry = Field(alias="windows-x64") + windows_x86: JavaIndexEntry = Field(alias="windows-x86") + + + class MojangVersion(MetaBase): @validator("minimum_launcher_version") def validate_minimum_launcher_version(cls, v): diff --git a/updateJava.py b/updateJava.py new file mode 100644 index 0000000000..4eb6ffc486 --- /dev/null +++ b/updateJava.py @@ -0,0 +1,157 @@ +import json +import os +import zipfile + +from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session +from meta.common.java import ( + BASE_DIR, + ADOPTIUM_DIR, + AZUL_DIR, + ADOPTIUM_VERSIONS_DIR, + AZUL_VERSIONS_DIR, +) +from meta.model.java import ( + ADOPTIUM_API_AVAILABLE_RELEASES, + adoptiumAPIFeatureReleases, + AdoptiumImageType, + AdoptiumAPIFeatureReleasesQuery, + AdoptiumAvailableReleases, + AdoptiumRelease, + AdoptiumReleasesWrap, + azulApiPackages, + AzulApiPackagesQuery, + ZuluPackageList, + ZuluPackagesListWrap, + AzulArchiveType, + AzulReleaseStatus, + AzulAvailabilityType, + AzulJavaPackageType, + azulApiPackageDetail, + ZuluPackageDetail, + ZuluPackagesDetailListWrap, +) + +UPSTREAM_DIR = upstream_path() +STATIC_DIR = static_path() + +ensure_upstream_dir(BASE_DIR) +ensure_upstream_dir(ADOPTIUM_DIR) +ensure_upstream_dir(AZUL_DIR) +ensure_upstream_dir(ADOPTIUM_VERSIONS_DIR) +ensure_upstream_dir(AZUL_VERSIONS_DIR) + + +sess = default_session() + + +def main(): + print("Getting Adoptium Release Manifests ") + r = sess.get(ADOPTIUM_API_AVAILABLE_RELEASES) + r.raise_for_status() + + available = AdoptiumAvailableReleases(**r.json()) + + available_releases_file = os.path.join( + UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") + available.write(available_releases_file) + + for feature in available.available_releases: + print("Getting Manifests for Adoptium feature release:", feature) + page = 0 + page_size = 10 + + releases_for_feature: list[AdoptiumRelease] = [] + + while True: + query = AdoptiumAPIFeatureReleasesQuery( + image_type=AdoptiumImageType.Jre, page_size=page_size, page=page) + api_call = adoptiumAPIFeatureReleases(feature, query=query) + print("Fetching Page:", page, api_call) + r_rls = sess.get(api_call) + if r_rls.status_code == 404: + break + else: + r_rls.raise_for_status() + + releases = list(AdoptiumRelease(**rls) for rls in r_rls.json()) + releases_for_feature.extend(releases) + + if len(r_rls.json()) < page_size: + break + page += 1 + + print("Total Adoptium releases for feature:", len(releases_for_feature)) + releases = AdoptiumReleasesWrap(releases=releases_for_feature) + feature_file = os.path.join( + UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, "{}.json".format(feature)) + releases.write(feature_file) + + print("Getting Azul Release Manifests") + zulu_packages: list[ZuluPackageList] = [] + page = 1 + page_size = 100 + while True: + + query = AzulApiPackagesQuery( + archive_type=AzulArchiveType.Zip, + release_status=AzulReleaseStatus.Ga, + availability_types=[AzulAvailabilityType.CA], + java_package_type=AzulJavaPackageType.Jre, + javafx_bundled=False, + page=page, + page_size=page_size) + api_call = azulApiPackages(query=query) + + print("Processing Page:", page, api_call) + + r = sess.get(api_call) + if r.status_code == 404: + break + else: + r.raise_for_status() + + packages = list(ZuluPackageList(**pkg) for pkg in r.json()) + zulu_packages.extend(packages) + if len(packages) < page_size: + break + page += 1 + + print("Total Azul Packages:", len(zulu_packages)) + packages = ZuluPackagesListWrap(packages=zulu_packages) + azul_manifest_file = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") + packages.write(azul_manifest_file) + + azul_major_versions: dict[int, ZuluPackagesListWrap] = {} + + for pkg in packages.packages: + + major_version = pkg.java_version[0] + if major_version not in azul_major_versions: + azul_major_versions[major_version] = ZuluPackagesListWrap( + packages=[]) + + azul_major_versions[major_version].packages.append(pkg) + + pkg_file = os.path.join( + UPSTREAM_DIR, AZUL_VERSIONS_DIR, "{}.json".format(pkg.package_uuid)) + if os.path.exists(pkg_file) and os.path.isfile(pkg_file): + pass + else: + + api_call = azulApiPackageDetail(pkg.package_uuid) + print("Fetching Azul package manifest:", pkg.package_uuid) + r_pkg = sess.get(api_call) + r_pkg.raise_for_status() + + pkg_detail = ZuluPackageDetail(**r_pkg.json()) + pkg_detail.write(pkg_file) + + for major in azul_major_versions: + major_file = os.path.join( + UPSTREAM_DIR, AZUL_VERSIONS_DIR, "{}.json".format(major)) + azul_major_versions[major].write(major_file) + + +if __name__ == "__main__": + main() + # diff --git a/updateMojang.py b/updateMojang.py index 8d3a2296e0..91ca558cc9 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -11,6 +11,7 @@ from meta.common.mojang import ( ASSETS_DIR, STATIC_EXPERIMENTS_FILE, STATIC_OLD_SNAPSHOTS_FILE, + JAVA_MANIFEST_FILE, ) from meta.model.mojang import ( MojangIndexWrap, @@ -19,6 +20,7 @@ from meta.model.mojang import ( ExperimentIndexWrap, OldSnapshotIndexWrap, OldSnapshotIndex, + JavaIndex, ) UPSTREAM_DIR = upstream_path() @@ -81,6 +83,19 @@ def fetch_version(path, url): return version_json +MOJANG_JAVA_URL = "https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json" + +def update_javas(): + r = sess.get(MOJANG_JAVA_URL) + r.raise_for_status() + + remote_javas = JavaIndex(**r.json()) + + java_manifest_path = os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) + + remote_javas.write(java_manifest_path) + + def main(): # get the remote version list r = sess.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json") @@ -160,6 +175,8 @@ def main(): remote_versions.index.write(version_manifest_path) + print("Getting Mojang Java runtime manfest") + update_javas() if __name__ == "__main__": main() -- cgit 0.0.5-2-1-g0f52 From 651ff8356ce125c6ee41da5edd9e981492fa7d1a Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 10 May 2023 20:55:45 -0700 Subject: feat: generate java componate Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- generateJava.py | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++ meta/common/java.py | 4 +- meta/model/enum.py | 32 ++++++ meta/model/java.py | 207 ++++++++++++++++++++++++++++---------- meta/model/mojang.py | 64 ++++++++---- updateJava.py | 41 ++++---- updateMojang.py | 2 +- 7 files changed, 533 insertions(+), 94 deletions(-) create mode 100644 generateJava.py create mode 100644 meta/model/enum.py (limited to 'meta') diff --git a/generateJava.py b/generateJava.py new file mode 100644 index 0000000000..11a449ae9f --- /dev/null +++ b/generateJava.py @@ -0,0 +1,277 @@ +import copy +import hashlib +import os +from collections import defaultdict, namedtuple +from operator import attrgetter +from pprint import pprint +from packaging import version as pversion +from typing import Optional, List + +from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path + +from meta.common.java import ( + JAVA_COMPONENT, + ADOPTIUM_DIR, + ADOPTIUM_VERSIONS_DIR, + AZUL_DIR, + AZUL_VERSIONS_DIR +) +from meta.model.java import ( + JavaRuntimeOS, + JavaRuntimeMap, + JavaRuntimeMeta, + JavaVersionMeta, + JavaChecksumMeta, + JavaChecksumType, + JavaRuntimeDownloadType, + AdoptiumAvailableReleases, + AdoptiumReleases, + AdoptiumRelease, + AdoptiumBinary, + ZuluPackages, + ZuluPackageDetail, + AzulArch, +) + +from meta.common.mojang import ( + + JAVA_MANIFEST_FILE, +) + +from meta.model.mojang import ( + JavaIndex, + MojangJavaComponent, + MojangJavaOsName, + MojangJavaRuntime, +) + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() +STATIC_DIR = static_path() + +ensure_component_dir(JAVA_COMPONENT) + +MOJANG_JAVA_OS_NAMES = [ + "gamecore", + "linux", + "linux-i386", + "mac-os", + "mac-os-arm64", + "windows-arm64", + "windows-x64", + "windows-x86", +] + +MOJANG_OS_ARCHITECTURES = [ + "x64", + "x86", + "arm64", + "arm32", +] + +MOJANG_OS_ARCHITECTURE_TRANSLATIONS = { + 64: "x64", + 32: "x86", + "x32": "x86", + "i386": "x86", + "aarch64": "arm64", + "x86_64": "x64", + "arm": "arm32" +} + + +def translate_arch(arch: str | int): + if isinstance(arch, str): + arch = arch.lower() + if arch in MOJANG_OS_ARCHITECTURES: + return arch + elif arch in MOJANG_OS_ARCHITECTURE_TRANSLATIONS: + return MOJANG_OS_ARCHITECTURE_TRANSLATIONS[arch] + else: + return None + +MOJANG_OS_NAMES = [ + "mac-os", + "linux", + "windows", +] + +MOJANG_OS_TRANSLATIONS = { + "osx": "mac-os", + "mac": "mac-os", + "macos": "mac-os", +} + +def translate_os(os: str): + os = os.lower() + if os in MOJANG_OS_NAMES: + return os + elif os in MOJANG_OS_TRANSLATIONS: + return MOJANG_OS_TRANSLATIONS[os] + else: + return None + + +def mojang_os_to_java_os(mojang_os: MojangJavaOsName) -> JavaRuntimeOS: + if mojang_os == MojangJavaOsName.Linux: + return JavaRuntimeOS.LinuxX64 + elif mojang_os == MojangJavaOsName.Linuxi386: + return JavaRuntimeOS.LinuxX86 + elif mojang_os == MojangJavaOsName.MacOs: + return JavaRuntimeOS.MacOsX64 + elif mojang_os == MojangJavaOsName.MacOSArm64: + return JavaRuntimeOS.MacOsArm64 + elif mojang_os == MojangJavaOsName.WindowsArm64: + return JavaRuntimeOS.WindowsArm64 + elif mojang_os == MojangJavaOsName.WindowsX64: + return JavaRuntimeOS.WindowsX64 + elif mojang_os == MojangJavaOsName.WindowsX86: + return JavaRuntimeOS.WindowsX86 + else: + return JavaRuntimeOS.Unknown + + +def mojang_runtime_to_java_runtime(mojang_runtime: MojangJavaRuntime) -> JavaRuntimeMeta: + return JavaRuntimeMeta( + name=f"mojang_jre_{mojang_runtime.version.name}", + vender="mojang", + url=mojang_runtime.manifest.url, + release_time=mojang_runtime.version.released, + checksum=JavaChecksumMeta( + type=JavaChecksumType.Sha1, + hash=mojang_runtime.manifest.sha1), + recomended=True, + download_type=JavaRuntimeDownloadType.Manifest) + +def adoptium_release_binary_to_java_runtime(rls: AdoptiumRelease, binary: AdoptiumBinary) -> JavaRuntimeMeta: + version = JavaVersionMeta( + major=rls.version_data.major, + minor=rls.version_data.minor, + security=rls.version_data.security, + build=rls.version_data.build + ) + rls_name = f"{rls.vendor}_temurin_{binary.image_type}{version}" + return JavaRuntimeMeta( + name=rls_name, + vender=rls.vendor, + url=binary.package.link, + release_time=rls.timestamp, + checksum=JavaChecksumMeta( + type=JavaChecksumType.Sha256, + hash=binary.package.checksum), + recomended=False, + download_type=JavaRuntimeDownloadType.Archive + ) + +def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: + version_parts = copy.copy(pkg.java_version) + while len(version_parts) < 4: + version_parts.append(None) + + version = JavaVersionMeta( + major=version_parts[0], + minor=version_parts[1], + security=version_parts[2], + build=version_parts[3] + ) + + rls_name = f"azul_{pkg.product}_{pkg.java_package_type}{version}" + + return JavaRuntimeMeta( + name=rls_name, + vender="azul", + url=pkg.download_url, + release_time=pkg.build_date, + checksum=JavaChecksumMeta( + type=JavaChecksumType.Sha256, + hash=pkg.sha256_hash), + recomended=False, + download_type=JavaRuntimeDownloadType.Archive + ) + +def main(): + + javas: dict[int, JavaRuntimeMap] = {} + + def ensure_javamap(major: int): + if major not in javas: + javas[major] = JavaRuntimeMap() + + def add_java_runtime(runtime: JavaRuntimeMeta, major: int, java_os: JavaRuntimeOS): + ensure_javamap(major) + print(f"Regestering runtime: {runtime.name} for Java {major} {java_os}") + javas[major][java_os].append(runtime) + + print("Processing Mojang Javas") + mojang_java_manifest = JavaIndex.parse_file( + os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) + ) + for mojang_os_name in mojang_java_manifest: + if mojang_os_name == MojangJavaOsName.Gamecore: + continue + java_os = mojang_os_to_java_os(mojang_os_name) + for comp in mojang_java_manifest[mojang_os_name]: + mojang_runtimes = mojang_java_manifest[mojang_os_name][comp] + for mojang_runtime in mojang_runtimes: + if comp == MojangJavaComponent.JreLegacy: + major = 8 + else: + major = int(mojang_runtime.version.name.partition('.')[0]) + runtime = mojang_runtime_to_java_runtime(mojang_runtime) + add_java_runtime(runtime, major, java_os) + + print("Processing Adoptium Releases") + adoptium_available_releases = AdoptiumAvailableReleases.parse_file( + os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") + ) + for major in adoptium_available_releases.available_releases: + adoptium_releases = AdoptiumReleases.parse_file( + os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{major}.json") + ) + for rls in adoptium_releases: + for binary in rls.binaries: + if binary.package is None: + continue + binary_arch = translate_arch(str(binary.architecture)) + binary_os = translate_os(str(binary.os)) + if binary_arch is None or binary_os is None: + print(f"Ignoring release for {binary.os} {binary.architecture}") + continue + + java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") + runtime = adoptium_release_binary_to_java_runtime(rls, binary) + add_java_runtime(runtime, major, java_os) + + print("Processing Azul Packages") + azul_packages = ZuluPackages.parse_file( + os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") + ) + for pkg in azul_packages: + pkg_detail = ZuluPackageDetail.parse_file( + os.path.join(UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json") + ) + major = pkg_detail.java_version[0] + pkg_os = translate_os(str(pkg_detail.os)) + if pkg_detail.arch == AzulArch.Arm: + pkg_arch = translate_arch(f"{pkg_detail.arch}{pkg_detail.hw_bitness}") + elif pkg_detail.arch == AzulArch.X86: + pkg_arch = translate_arch(int(pkg_detail.hw_bitness)) + else: + pkg_arch = None + if pkg_arch is None or pkg_os is None: + print(f"Ignoring release for {pkg_detail.os} {pkg_detail.arch}_{pkg_detail.hw_bitness}") + continue + + java_os = JavaRuntimeOS(f"{pkg_os}-{pkg_arch}") + runtime = azul_package_to_java_runtime(pkg_detail) + add_java_runtime(runtime, major, java_os) + + for major, runtimes in javas.items(): + for java_os in runtimes: + print(f"Total runtimes for Java {major} {java_os}:", len(runtimes[java_os])) + runtimes_file = os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") + runtimes.write(runtimes_file) + + +if __name__ == "__main__": + main() diff --git a/meta/common/java.py b/meta/common/java.py index 8de3c47c4e..541d2fb374 100644 --- a/meta/common/java.py +++ b/meta/common/java.py @@ -7,4 +7,6 @@ ADOPTIUM_DIR = join(BASE_DIR, "adoptium") AZUL_DIR = join(BASE_DIR, "azul") ADOPTIUM_VERSIONS_DIR = join(ADOPTIUM_DIR, "versions") -AZUL_VERSIONS_DIR = join(AZUL_DIR, "versions") \ No newline at end of file +AZUL_VERSIONS_DIR = join(AZUL_DIR, "versions") + +JAVA_COMPONENT = "net.minecraft.java" \ No newline at end of file diff --git a/meta/model/enum.py b/meta/model/enum.py new file mode 100644 index 0000000000..08dda4bf4a --- /dev/null +++ b/meta/model/enum.py @@ -0,0 +1,32 @@ +import enum + + +class StrEnum(str, enum.Enum): + """ + StrEnum is a Python ``enum.Enum`` that inherits from ``str``. The default + ``auto()`` behavior uses the member name as its value. + + Example usage:: + + class Example(StrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "UPPER_CASE" + assert Example.lower_case == "lower_case" + assert Example.MixedCase == "MixedCase" + """ + + def __new__(cls, value, *args, **kwargs): + if not isinstance(value, (str, enum.auto)): + raise TypeError( + f"Values of StrEnums must be strings: {value!r} is a {type(value)}" + ) + return super().__new__(cls, value, *args, **kwargs) + + def __str__(self): + return str(self.value) + + def _generate_next_value_(name, *_): + return name diff --git a/meta/model/java.py b/meta/model/java.py index d4d2e00cb9..a7907d90d2 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -3,7 +3,8 @@ from . import ( ) from pydantic import Field from datetime import datetime -from enum import Enum +from enum import IntEnum, Enum +from .enum import StrEnum from typing import Optional, List, Dict, Any, Iterator, Iterable, NamedTuple from collections import namedtuple from urllib.parse import urljoin, urlencode, urlparse, urlunparse @@ -11,6 +12,75 @@ from urllib.parse import urljoin, urlencode, urlparse, urlunparse # namedtuple to match the internal signature of urlunparse +class JavaRuntimeOS(StrEnum): + MacOsX64 = "mac-os-x64" + MacOsX86 = "mac-os-x86" # rare + MacOsArm64 = "mac-os-arm64" + # MacOsArm32 = "mac-os-arm32" # doesn't exsist + LinuxX64 = "linux-x64" + LinuxX86 = "linux-x86" + LinuxArm64 = "linux-arm64" + LinuxArm32 = "linux-arm32" + WindowsX64 = "windows-x64" + WindowsX86 = "windows-x86" + WindowsArm64 = "windows-arm64" + WindowsArm32 = "windows-arm32" + Unknown = "unknown" + + +class JavaRuntimeDownloadType(StrEnum): + Manifest = "manifest" + Archive = "archive" + + +class JavaVersionMeta(MetaBase): + major: int + minor: int + security: int + build: Optional[int] + + def __str__(self): + ver = f"{self.major}.{self.minor}.{self.security}" + if self.build is not None: + ver = f"{ver}+{self.build}" + return ver + + +class JavaChecksumType(StrEnum): + Sha1 = "sha1" + Sha256 = "sha256" + + +class JavaChecksumMeta(MetaBase): + type: JavaChecksumType + hash: str + + +class JavaRuntimeMeta(MetaBase): + name: str + vender: str + url: str + release_time: datetime = Field(alias="releaseTime") + checksum: Optional[JavaChecksumMeta] + recomended: bool + download_type: JavaRuntimeDownloadType = Field(alias="downloadType") + + +class JavaRuntimeMap(MetaBase): + __root__: dict[JavaRuntimeOS, list[JavaRuntimeMeta]] = { + os: [] for os in JavaRuntimeOS if os != JavaRuntimeOS.Unknown + } + + def __iter__(self) -> Iterator[JavaRuntimeOS]: + return iter(self.__root__) + + def __getitem__(self, item) -> list[JavaRuntimeMeta]: + return self.__root__[item] + + def __len__(self): + return len(self.__root__) + + class URLComponents(NamedTuple): scheme: str netloc: str @@ -21,7 +91,6 @@ class URLComponents(NamedTuple): class APIQuery(MetaBase): - def to_query(self): set_parts: dict[str, Any] = {} for key, value in self.dict().items(): @@ -38,15 +107,15 @@ class APIQuery(MetaBase): return urlencode(set_parts, doseq=True) -class AdoptiumJvmImpl(Enum): +class AdoptiumJvmImpl(StrEnum): Hostspot = "hotspot" -class AdoptiumVendor(Enum): +class AdoptiumVendor(StrEnum): Eclipse = "eclipse" -class AdoptiumArchitecture(Enum): +class AdoptiumArchitecture(StrEnum): X64 = "x64" X86 = "x86" X32 = "x32" @@ -59,22 +128,22 @@ class AdoptiumArchitecture(Enum): Riscv64 = "riscv64" -class AdoptiumReleaseType(Enum): +class AdoptiumReleaseType(StrEnum): GenralAccess = "ga" EarlyAccess = "ea" -class AdoptiumSortMethod(Enum): +class AdoptiumSortMethod(StrEnum): Default = "DEFAULT" Date = "DATE" -class AdoptiumSortOrder(Enum): +class AdoptiumSortOrder(StrEnum): Asc = "ASC" Desc = "DESC" -class AdoptiumImageType(Enum): +class AdoptiumImageType(StrEnum): Jdk = "jdk" Jre = "jre" Testimage = "testimage" @@ -84,12 +153,12 @@ class AdoptiumImageType(Enum): Sbom = "sbom" -class AdoptiumHeapSize(Enum): +class AdoptiumHeapSize(StrEnum): Normal = "normal" Large = "large" -class AdoptiumProject(Enum): +class AdoptiumProject(StrEnum): Jdk = "jdk" Valhalla = "valhalla" Metropolis = "metropolis" @@ -97,12 +166,12 @@ class AdoptiumProject(Enum): Shenandoah = "shenandoah" -class AdoptiumCLib(Enum): +class AdoptiumCLib(StrEnum): Musl = "musl" - Glibc = "Glibc" + Glibc = "glibc" -class AdoptiumOs(Enum): +class AdoptiumOs(StrEnum): Linux = "linux" Windows = "windows" Mac = "mac" @@ -128,20 +197,22 @@ class AdoptiumAPIFeatureReleasesQuery(APIQuery): page_size: int = 10 page: int = 0 project: Optional[AdoptiumProject] = AdoptiumProject.Jdk - sort_method: Optional[AdoptiumSortMethod] = AdoptiumSortMethod.Default - sort_order: Optional[AdoptiumSortOrder] = AdoptiumSortOrder.Desc - vender: Optional[AdoptiumVendor] = AdoptiumVendor.Eclipse + sort_method: Optional[AdoptiumSortMethod] = AdoptiumSortMethod.Default + sort_order: Optional[AdoptiumSortOrder] = AdoptiumSortOrder.Desc + vender: Optional[AdoptiumVendor] = AdoptiumVendor.Eclipse -def adoptiumAPIFeatureReleases( - feature: int, - release_type: AdoptiumReleaseType = AdoptiumReleaseType.GenralAccess, - query: AdoptiumAPIFeatureReleasesQuery = AdoptiumAPIFeatureReleasesQuery() +def adoptiumAPIFeatureReleasesUrl( + feature: int, + release_type: AdoptiumReleaseType = AdoptiumReleaseType.GenralAccess, + query: AdoptiumAPIFeatureReleasesQuery = AdoptiumAPIFeatureReleasesQuery(), ): - url = urlparse(ADOPTIUM_API_FEATURE_RELEASES.format( - feature_version=feature, - release_type=release_type.value, - )) + url = urlparse( + ADOPTIUM_API_FEATURE_RELEASES.format( + feature_version=feature, + release_type=release_type.value, + ) + ) return urlunparse(url._replace(query=query.to_query())) @@ -211,33 +282,42 @@ class AdoptiumRelease(MetaBase): release_notes: Optional[AdoptiumFile] -class AdoptiumReleasesWrap(MetaBase): - releases: list[AdoptiumRelease] +class AdoptiumReleases(MetaBase): + __root__: list[AdoptiumRelease] + def __iter__(self) -> Iterator[AdoptiumRelease]: + return iter(self.__root__) -class AzulProduct(Enum): + def __getitem__(self, item) -> AdoptiumRelease: + return self.__root__[item] + + def append(self, rls: AdoptiumRelease): + self.__root__.append(rls) + + +class AzulProduct(StrEnum): Zulu = "zulu" -class AzulAvailabilityType(Enum): +class AzulAvailabilityType(StrEnum): SA = "SA" CA = "CA" NV = "NV" _LA = "LA" -class AzulJavaPackageType(Enum): +class AzulJavaPackageType(StrEnum): Jdk = "jdk" Jre = "jre" -class AzulReleaseType(Enum): +class AzulReleaseType(StrEnum): CPU = "CPU" PSU = "PSU" LU = "LU" -class AzulOs(Enum): +class AzulOs(StrEnum): Linux = "linux" Macos = "macos" Qnx = "qnx" @@ -245,13 +325,13 @@ class AzulOs(Enum): Solaris = "solaris" -class AzulLibCType(Enum): +class AzulLibCType(StrEnum): Glibc = "glibc" Uclibc = "uclibc" Musl = "musl" -class AzulCPUGen(Enum): +class AzulCPUGen(StrEnum): V5 = "v5" V6kV6kz = "v6k_v6kz" V6t2 = "v6t2" @@ -259,7 +339,7 @@ class AzulCPUGen(Enum): V8 = "v8" -class AzulArch(Enum): +class AzulArch(StrEnum): Arm = "arm" X86 = "x86" Mips = "mips" @@ -268,19 +348,19 @@ class AzulArch(Enum): Sparc = "sparc" -class AzulHwBitness(Enum): +class AzulHwBitness(IntEnum): X32 = 32 X64 = 64 -class AzulAbi(Enum): +class AzulAbi(StrEnum): HardFloat = "hard_float" SoftFloat = "soft_float" Spe = "spe" Any = "any" -class AzulArchiveType(Enum): +class AzulArchiveType(StrEnum): Deb = "deb" Rpm = "rpm" Dmg = "dmg" @@ -290,30 +370,30 @@ class AzulArchiveType(Enum): Msi = "msi" -class AzulReleaseStatus(Enum): +class AzulReleaseStatus(StrEnum): Eval = "eval" Ea = "ea" Ga = "ga" Both = "both" -class AzulSupportTerm(Enum): +class AzulSupportTerm(StrEnum): Sts = "sts" Mts = "mts" Lts = "lts" -class AzulCertifications(Enum): +class AzulCertifications(StrEnum): Tck = "tck" _Aqavit = "aqavit" none = "none" -class AzulSignatureType(Enum): +class AzulSignatureType(StrEnum): Openpgp = "openpgp" -class AzulOsQueryParam(Enum): +class AzulOsQueryParam(StrEnum): Macos = "macos" Windows = "windows" Linux = "linux" @@ -323,7 +403,7 @@ class AzulOsQueryParam(Enum): Solaris = "solaris" -class AzulArchQueryParam(Enum): +class AzulArchQueryParam(StrEnum): X86 = "x86" X64 = "x64" Amd64 = "amd64" @@ -371,12 +451,12 @@ class AzulApiPackagesQuery(APIQuery): page_size: int = 100 -def azulApiPackages(query: AzulApiPackagesQuery = AzulApiPackagesQuery()): +def azulApiPackagesUrl(query: AzulApiPackagesQuery = AzulApiPackagesQuery()): url = urlparse(AZUL_API_PACKAGES) return urlunparse(url._replace(query=query.to_query())) -def azulApiPackageDetail(package_uuid: str): +def azulApiPackageDetailUrl(package_uuid: str): return AZUL_API_PACKAGE_DETAIL.format(package_uuid=package_uuid) @@ -431,9 +511,36 @@ class ZuluPackageList(MetaBase): availability_type: Optional[AzulAvailabilityType] -class ZuluPackagesListWrap(MetaBase): - packages: list[ZuluPackageList] +class ZuluPackages(MetaBase): + __root__: list[ZuluPackageList] + + def __iter__(self) -> Iterator[ZuluPackageList]: + return iter(self.__root__) + + def __getitem__(self, item) -> ZuluPackageList: + return self.__root__[item] + + def append(self, pkg: ZuluPackageList): + self.__root__.append(pkg) + + +class ZuluPackagesDetail(MetaBase): + __root__: list[ZuluPackageDetail] + + def __iter__(self) -> Iterator[ZuluPackageDetail]: + return iter(self.__root__) + + def __getitem__(self, item) -> ZuluPackageDetail: + return self.__root__[item] + + def append(self, pkg: ZuluPackageDetail): + self.__root__.append(pkg) + +MOJANG_OS_NAMES = ["mac-os", "linux", "windows"] -class ZuluPackagesDetailListWrap(MetaBase): - packages: list[ZuluPackageDetail] +MOJANG_OS_ARCHITECTURES = [ + "x64" "x86", + "arm64", + "arm32", +] diff --git a/meta/model/mojang.py b/meta/model/mojang.py index ce178efe2e..2e43899751 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -1,5 +1,6 @@ from datetime import datetime from typing import Optional, List, Dict, Any, Iterator +from .enum import StrEnum from pydantic import validator, Field @@ -185,51 +186,70 @@ class MojangLogging(MetaBase): type: str +class MojangJavaComponent(StrEnum): + JreLegacy = "jre-legacy" + Alpha = "java-runtime-alpha" + Beta = "java-runtime-beta" + Gamma = "java-runtime-gamma" + Exe = "minecraft-java-exe" + + class JavaVersion(MetaBase): - component: str = "jre-legacy" + component: MojangJavaComponent = MojangJavaComponent.JreLegacy major_version: int = Field(8, alias="majorVersion") -class JavaIndexAvailability(MetaBase): +class MojangJavaIndexAvailability(MetaBase): group: int progress: int -class JavaIndexManifest(MetaBase): +class MojangJavaIndexManifest(MetaBase): sha1: str size: int url: str -class JavaIndexVersion(MetaBase): +class MojangJavaIndexVersion(MetaBase): name: str released: datetime -class JavaRuntime(MetaBase): - availability: JavaIndexAvailability - manifest: JavaIndexManifest - version: JavaIndexVersion +class MojangJavaRuntime(MetaBase): + availability: MojangJavaIndexAvailability + manifest: MojangJavaIndexManifest + version: MojangJavaIndexVersion + +class MojangJavaIndexEntry(MetaBase): + __root__: dict[MojangJavaComponent, list[MojangJavaRuntime]] -class JavaIndexEntry(MetaBase): - java_runtime_alpha: list[JavaRuntime] = Field(alias="java-runtime-alpha") - java_runtime_beta: list[JavaRuntime] = Field(alias="java-runtime-beta") - java_runtime_gamma: list[JavaRuntime] = Field(alias="java-runtime-gamma") - jre_legacy: list[JavaRuntime] = Field(alias="jre-legacy") - minecraft_java_exe: list[JavaRuntime] = Field(alias="minecraft-java-exe") + def __iter__(self) -> Iterator[MojangJavaComponent]: + return iter(self.__root__) + + def __getitem__(self, item) -> list[MojangJavaRuntime]: + return self.__root__[item] + + +class MojangJavaOsName(StrEnum): + Gamecore = "gamecore" + Linux = "linux" + Linuxi386 = "linux-i386" + MacOs = "mac-os" + MacOSArm64 = "mac-os-arm64" + WindowsArm64 = "windows-arm64" + WindowsX64 = "windows-x64" + WindowsX86 = "windows-x86" class JavaIndex(MetaBase): - gamecore: JavaIndexEntry - linux: JavaIndexEntry - linux_i386: JavaIndexEntry = Field(alias="linux-i386") - mac_os: JavaIndexEntry = Field(alias="mac-os") - mac_os_arm64: JavaIndexEntry = Field(alias="mac-os-arm64") - windows_arm64: JavaIndexEntry = Field(alias="windows-arm64") - windows_x64: JavaIndexEntry = Field(alias="windows-x64") - windows_x86: JavaIndexEntry = Field(alias="windows-x86") + __root__: dict[MojangJavaOsName, MojangJavaIndexEntry] + def __iter__(self) -> Iterator[MojangJavaOsName]: + return iter(self.__root__) + + def __getitem__(self, item) -> MojangJavaIndexEntry: + return self.__root__[item] class MojangVersion(MetaBase): diff --git a/updateJava.py b/updateJava.py index 4eb6ffc486..ece97690be 100644 --- a/updateJava.py +++ b/updateJava.py @@ -12,23 +12,23 @@ from meta.common.java import ( ) from meta.model.java import ( ADOPTIUM_API_AVAILABLE_RELEASES, - adoptiumAPIFeatureReleases, + adoptiumAPIFeatureReleasesUrl, AdoptiumImageType, AdoptiumAPIFeatureReleasesQuery, AdoptiumAvailableReleases, AdoptiumRelease, - AdoptiumReleasesWrap, - azulApiPackages, + AdoptiumReleases, + azulApiPackagesUrl, AzulApiPackagesQuery, ZuluPackageList, - ZuluPackagesListWrap, + ZuluPackages, AzulArchiveType, AzulReleaseStatus, AzulAvailabilityType, AzulJavaPackageType, - azulApiPackageDetail, + azulApiPackageDetailUrl, ZuluPackageDetail, - ZuluPackagesDetailListWrap, + ZuluPackagesDetail, ) UPSTREAM_DIR = upstream_path() @@ -65,7 +65,7 @@ def main(): while True: query = AdoptiumAPIFeatureReleasesQuery( image_type=AdoptiumImageType.Jre, page_size=page_size, page=page) - api_call = adoptiumAPIFeatureReleases(feature, query=query) + api_call = adoptiumAPIFeatureReleasesUrl(feature, query=query) print("Fetching Page:", page, api_call) r_rls = sess.get(api_call) if r_rls.status_code == 404: @@ -81,9 +81,9 @@ def main(): page += 1 print("Total Adoptium releases for feature:", len(releases_for_feature)) - releases = AdoptiumReleasesWrap(releases=releases_for_feature) + releases = AdoptiumReleases(__root__=releases_for_feature) feature_file = os.path.join( - UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, "{}.json".format(feature)) + UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{feature}.json") releases.write(feature_file) print("Getting Azul Release Manifests") @@ -100,7 +100,7 @@ def main(): javafx_bundled=False, page=page, page_size=page_size) - api_call = azulApiPackages(query=query) + api_call = azulApiPackagesUrl(query=query) print("Processing Page:", page, api_call) @@ -117,38 +117,39 @@ def main(): page += 1 print("Total Azul Packages:", len(zulu_packages)) - packages = ZuluPackagesListWrap(packages=zulu_packages) + packages = ZuluPackages(__root__=zulu_packages) azul_manifest_file = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") packages.write(azul_manifest_file) - azul_major_versions: dict[int, ZuluPackagesListWrap] = {} + azul_major_versions: dict[int, ZuluPackages] = {} - for pkg in packages.packages: + for pkg in packages: major_version = pkg.java_version[0] if major_version not in azul_major_versions: - azul_major_versions[major_version] = ZuluPackagesListWrap( - packages=[]) + azul_major_versions[major_version] = ZuluPackagesDetail(__root__=[]) - azul_major_versions[major_version].packages.append(pkg) + pkg_file = os.path.join( - UPSTREAM_DIR, AZUL_VERSIONS_DIR, "{}.json".format(pkg.package_uuid)) + UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json") if os.path.exists(pkg_file) and os.path.isfile(pkg_file): - pass + pkg_detail = ZuluPackageDetail.parse_file(pkg_file) + azul_major_versions[major_version].append(pkg_detail) else: - api_call = azulApiPackageDetail(pkg.package_uuid) + api_call = azulApiPackageDetailUrl(pkg.package_uuid) print("Fetching Azul package manifest:", pkg.package_uuid) r_pkg = sess.get(api_call) r_pkg.raise_for_status() pkg_detail = ZuluPackageDetail(**r_pkg.json()) pkg_detail.write(pkg_file) + azul_major_versions[major_version].append(pkg_detail) for major in azul_major_versions: major_file = os.path.join( - UPSTREAM_DIR, AZUL_VERSIONS_DIR, "{}.json".format(major)) + UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"java{major}.json") azul_major_versions[major].write(major_file) diff --git a/updateMojang.py b/updateMojang.py index 91ca558cc9..03a77df19c 100755 --- a/updateMojang.py +++ b/updateMojang.py @@ -89,7 +89,7 @@ def update_javas(): r = sess.get(MOJANG_JAVA_URL) r.raise_for_status() - remote_javas = JavaIndex(**r.json()) + remote_javas = JavaIndex(__root__=r.json()) java_manifest_path = os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) -- cgit 0.0.5-2-1-g0f52 From 1b8d9d408c71453ccd5afc130f7b1da8df254dbc Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 11 May 2023 02:10:12 -0700 Subject: fix: ensure there is a recomended version Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- generateJava.py | 166 +++++++++++++++++++++++++++++++++++++++++------------ meta/model/java.py | 20 ++++++- 2 files changed, 146 insertions(+), 40 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index 11a449ae9f..85041bc777 100644 --- a/generateJava.py +++ b/generateJava.py @@ -14,7 +14,7 @@ from meta.common.java import ( ADOPTIUM_DIR, ADOPTIUM_VERSIONS_DIR, AZUL_DIR, - AZUL_VERSIONS_DIR + AZUL_VERSIONS_DIR, ) from meta.model.java import ( JavaRuntimeOS, @@ -34,7 +34,6 @@ from meta.model.java import ( ) from meta.common.mojang import ( - JAVA_MANIFEST_FILE, ) @@ -64,7 +63,7 @@ MOJANG_JAVA_OS_NAMES = [ MOJANG_OS_ARCHITECTURES = [ "x64", - "x86", + "x86", "arm64", "arm32", ] @@ -76,7 +75,7 @@ MOJANG_OS_ARCHITECTURE_TRANSLATIONS = { "i386": "x86", "aarch64": "arm64", "x86_64": "x64", - "arm": "arm32" + "arm": "arm32", } @@ -90,6 +89,7 @@ def translate_arch(arch: str | int): else: return None + MOJANG_OS_NAMES = [ "mac-os", "linux", @@ -102,6 +102,7 @@ MOJANG_OS_TRANSLATIONS = { "macos": "mac-os", } + def translate_os(os: str): os = os.lower() if os in MOJANG_OS_NAMES: @@ -131,24 +132,49 @@ def mojang_os_to_java_os(mojang_os: MojangJavaOsName) -> JavaRuntimeOS: return JavaRuntimeOS.Unknown -def mojang_runtime_to_java_runtime(mojang_runtime: MojangJavaRuntime) -> JavaRuntimeMeta: +def mojang_runtime_to_java_runtime( + mojang_runtime: MojangJavaRuntime, +) -> JavaRuntimeMeta: + major, _, security = mojang_runtime.version.name.partition("u") + if major and security: + version_parts = [int(major), 0, int(security)] + else: + version_parts = [int(part) for part in mojang_runtime.version.name.split(".")] + + while len(version_parts) < 3: + version_parts.append(0) + if len(version_parts) < 4: + version_parts.append(None) + + version = JavaVersionMeta( + major=version_parts[0], + minor=version_parts[1], + security=version_parts[2], + build=version_parts[3], + name=mojang_runtime.version.name, + ) return JavaRuntimeMeta( name=f"mojang_jre_{mojang_runtime.version.name}", vender="mojang", url=mojang_runtime.manifest.url, release_time=mojang_runtime.version.released, checksum=JavaChecksumMeta( - type=JavaChecksumType.Sha1, - hash=mojang_runtime.manifest.sha1), + type=JavaChecksumType.Sha1, hash=mojang_runtime.manifest.sha1 + ), recomended=True, - download_type=JavaRuntimeDownloadType.Manifest) + download_type=JavaRuntimeDownloadType.Manifest, + version=version, + ) + -def adoptium_release_binary_to_java_runtime(rls: AdoptiumRelease, binary: AdoptiumBinary) -> JavaRuntimeMeta: +def adoptium_release_binary_to_java_runtime( + rls: AdoptiumRelease, binary: AdoptiumBinary +) -> JavaRuntimeMeta: version = JavaVersionMeta( major=rls.version_data.major, minor=rls.version_data.minor, security=rls.version_data.security, - build=rls.version_data.build + build=rls.version_data.build, ) rls_name = f"{rls.vendor}_temurin_{binary.image_type}{version}" return JavaRuntimeMeta( @@ -157,69 +183,131 @@ def adoptium_release_binary_to_java_runtime(rls: AdoptiumRelease, binary: Adopti url=binary.package.link, release_time=rls.timestamp, checksum=JavaChecksumMeta( - type=JavaChecksumType.Sha256, - hash=binary.package.checksum), + type=JavaChecksumType.Sha256, hash=binary.package.checksum + ), recomended=False, - download_type=JavaRuntimeDownloadType.Archive + download_type=JavaRuntimeDownloadType.Archive, + version=version, ) + def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: version_parts = copy.copy(pkg.java_version) while len(version_parts) < 4: version_parts.append(None) - + version = JavaVersionMeta( major=version_parts[0], minor=version_parts[1], security=version_parts[2], - build=version_parts[3] + build=version_parts[3], ) - + rls_name = f"azul_{pkg.product}_{pkg.java_package_type}{version}" - + return JavaRuntimeMeta( name=rls_name, vender="azul", url=pkg.download_url, release_time=pkg.build_date, - checksum=JavaChecksumMeta( - type=JavaChecksumType.Sha256, - hash=pkg.sha256_hash), + checksum=JavaChecksumMeta(type=JavaChecksumType.Sha256, hash=pkg.sha256_hash), recomended=False, - download_type=JavaRuntimeDownloadType.Archive + download_type=JavaRuntimeDownloadType.Archive, + version=version, ) + +PREFERED_VENDER_ORDER = ["mojang", "eclipse", "azul"] + +__PREFERED_VENDER_ORDER = list(reversed(PREFERED_VENDER_ORDER)) + + +def vender_priority(vender: str) -> int: + """Get a numeric priority for a given vendor + + Args: + vendor (str): the vender to check + + Returns: + int: how preferable the vender is, the higher the better + """ + if vender not in PREFERED_VENDER_ORDER: + return -1 + return __PREFERED_VENDER_ORDER.index(vender) + + +def ensure_one_recomended(runtimes: list[JavaRuntimeMeta]): + if len(runtimes) < 1: + return # can't do anything + + recomended: Optional[JavaRuntimeMeta] = None + found_first = False + need_resort = False + for runtime in runtimes: + if runtime.recomended: + if not found_first: + recomended = runtime + else: + runtime.recomended = False + need_resort = True + + if recomended and not need_resort: + print("Recomending", recomended.name) + return # we have one recomended already + + if recomended is None: + recomended = runtimes[0] + + def better_java_runtime(runtime: JavaRuntimeMeta): + if vender_priority(runtime.vender) < vender_priority(recomended.vender): + return False + if runtime.version < recomended.version: + return False + if runtime.release_time < recomended.release_time: + return False + return True + + for runtime in runtimes: + if better_java_runtime(runtime): + recomended.recomended = False + recomended = runtime + recomended.recomended = True + + print("Recomending", recomended.name) + + def main(): - javas: dict[int, JavaRuntimeMap] = {} - + def ensure_javamap(major: int): if major not in javas: javas[major] = JavaRuntimeMap() - + def add_java_runtime(runtime: JavaRuntimeMeta, major: int, java_os: JavaRuntimeOS): ensure_javamap(major) print(f"Regestering runtime: {runtime.name} for Java {major} {java_os}") javas[major][java_os].append(runtime) - + print("Processing Mojang Javas") mojang_java_manifest = JavaIndex.parse_file( os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) ) for mojang_os_name in mojang_java_manifest: if mojang_os_name == MojangJavaOsName.Gamecore: - continue + continue # empty java_os = mojang_os_to_java_os(mojang_os_name) for comp in mojang_java_manifest[mojang_os_name]: + if comp == MojangJavaComponent.Exe: + continue # doesn't appear to be used and not marked with a full verison so I don't trust it mojang_runtimes = mojang_java_manifest[mojang_os_name][comp] for mojang_runtime in mojang_runtimes: if comp == MojangJavaComponent.JreLegacy: major = 8 else: - major = int(mojang_runtime.version.name.partition('.')[0]) + major = int(mojang_runtime.version.name.partition(".")[0]) runtime = mojang_runtime_to_java_runtime(mojang_runtime) add_java_runtime(runtime, major, java_os) - + print("Processing Adoptium Releases") adoptium_available_releases = AdoptiumAvailableReleases.parse_file( os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") @@ -237,11 +325,11 @@ def main(): if binary_arch is None or binary_os is None: print(f"Ignoring release for {binary.os} {binary.architecture}") continue - + java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") runtime = adoptium_release_binary_to_java_runtime(rls, binary) add_java_runtime(runtime, major, java_os) - + print("Processing Azul Packages") azul_packages = ZuluPackages.parse_file( os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") @@ -250,28 +338,32 @@ def main(): pkg_detail = ZuluPackageDetail.parse_file( os.path.join(UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json") ) - major = pkg_detail.java_version[0] + major = pkg_detail.java_version[0] pkg_os = translate_os(str(pkg_detail.os)) - if pkg_detail.arch == AzulArch.Arm: + if pkg_detail.arch == AzulArch.Arm: pkg_arch = translate_arch(f"{pkg_detail.arch}{pkg_detail.hw_bitness}") - elif pkg_detail.arch == AzulArch.X86: + elif pkg_detail.arch == AzulArch.X86: pkg_arch = translate_arch(int(pkg_detail.hw_bitness)) else: pkg_arch = None if pkg_arch is None or pkg_os is None: - print(f"Ignoring release for {pkg_detail.os} {pkg_detail.arch}_{pkg_detail.hw_bitness}") + print( + f"Ignoring release for {pkg_detail.os} {pkg_detail.arch}_{pkg_detail.hw_bitness}" + ) continue - + java_os = JavaRuntimeOS(f"{pkg_os}-{pkg_arch}") runtime = azul_package_to_java_runtime(pkg_detail) add_java_runtime(runtime, major, java_os) - + for major, runtimes in javas.items(): for java_os in runtimes: print(f"Total runtimes for Java {major} {java_os}:", len(runtimes[java_os])) + ensure_one_recomended(runtimes[java_os]) + runtimes_file = os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") runtimes.write(runtimes_file) - + if __name__ == "__main__": main() diff --git a/meta/model/java.py b/meta/model/java.py index a7907d90d2..ca45085ea3 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -8,7 +8,7 @@ from .enum import StrEnum from typing import Optional, List, Dict, Any, Iterator, Iterable, NamedTuple from collections import namedtuple from urllib.parse import urljoin, urlencode, urlparse, urlunparse - +from functools import total_ordering # namedtuple to match the internal signature of urlunparse @@ -32,18 +32,31 @@ class JavaRuntimeDownloadType(StrEnum): Manifest = "manifest" Archive = "archive" - +@total_ordering class JavaVersionMeta(MetaBase): major: int minor: int security: int - build: Optional[int] + build: Optional[int] = None + name: Optional[str] = None def __str__(self): ver = f"{self.major}.{self.minor}.{self.security}" if self.build is not None: ver = f"{ver}+{self.build}" return ver + + def to_tuple(self): + build = 0 + if self.build is not None: + build = self.build + return (self.major, self.minor, self.security, build) + + def __eq__(self, other: 'JavaVersionMeta'): + return (self.to_tuple() == other.to_tuple()) + + def __lt__(self, other: 'JavaVersionMeta'): + return (self.to_tuple() < other.to_tuple()) class JavaChecksumType(StrEnum): @@ -64,6 +77,7 @@ class JavaRuntimeMeta(MetaBase): checksum: Optional[JavaChecksumMeta] recomended: bool download_type: JavaRuntimeDownloadType = Field(alias="downloadType") + version: JavaVersionMeta class JavaRuntimeMap(MetaBase): -- cgit 0.0.5-2-1-g0f52 From c911fbd7748aaae30242543cf43e9008400c8798 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Thu, 11 May 2023 02:20:57 -0700 Subject: fix: spelling Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- generateJava.py | 62 +++++++++++++++++++++++++++--------------------------- meta/model/java.py | 8 +++---- 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index 85041bc777..ac9b7b97f0 100644 --- a/generateJava.py +++ b/generateJava.py @@ -155,13 +155,13 @@ def mojang_runtime_to_java_runtime( ) return JavaRuntimeMeta( name=f"mojang_jre_{mojang_runtime.version.name}", - vender="mojang", + vendor="mojang", url=mojang_runtime.manifest.url, release_time=mojang_runtime.version.released, checksum=JavaChecksumMeta( type=JavaChecksumType.Sha1, hash=mojang_runtime.manifest.sha1 ), - recomended=True, + recommended=True, download_type=JavaRuntimeDownloadType.Manifest, version=version, ) @@ -179,13 +179,13 @@ def adoptium_release_binary_to_java_runtime( rls_name = f"{rls.vendor}_temurin_{binary.image_type}{version}" return JavaRuntimeMeta( name=rls_name, - vender=rls.vendor, + vendor=rls.vendor, url=binary.package.link, release_time=rls.timestamp, checksum=JavaChecksumMeta( type=JavaChecksumType.Sha256, hash=binary.package.checksum ), - recomended=False, + recommended=False, download_type=JavaRuntimeDownloadType.Archive, version=version, ) @@ -207,73 +207,73 @@ def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: return JavaRuntimeMeta( name=rls_name, - vender="azul", + vendor="azul", url=pkg.download_url, release_time=pkg.build_date, checksum=JavaChecksumMeta(type=JavaChecksumType.Sha256, hash=pkg.sha256_hash), - recomended=False, + recommended=False, download_type=JavaRuntimeDownloadType.Archive, version=version, ) -PREFERED_VENDER_ORDER = ["mojang", "eclipse", "azul"] +PREFERED_vendor_ORDER = ["mojang", "eclipse", "azul"] -__PREFERED_VENDER_ORDER = list(reversed(PREFERED_VENDER_ORDER)) +__PREFERED_vendor_ORDER = list(reversed(PREFERED_vendor_ORDER)) -def vender_priority(vender: str) -> int: +def vendor_priority(vendor: str) -> int: """Get a numeric priority for a given vendor Args: - vendor (str): the vender to check + vendor (str): the vendor to check Returns: - int: how preferable the vender is, the higher the better + int: how preferable the vendor is, the higher the better """ - if vender not in PREFERED_VENDER_ORDER: + if vendor not in PREFERED_vendor_ORDER: return -1 - return __PREFERED_VENDER_ORDER.index(vender) + return __PREFERED_vendor_ORDER.index(vendor) -def ensure_one_recomended(runtimes: list[JavaRuntimeMeta]): +def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]): if len(runtimes) < 1: return # can't do anything - recomended: Optional[JavaRuntimeMeta] = None + recommended: Optional[JavaRuntimeMeta] = None found_first = False need_resort = False for runtime in runtimes: - if runtime.recomended: + if runtime.recommended: if not found_first: - recomended = runtime + recommended = runtime else: - runtime.recomended = False + runtime.recommended = False need_resort = True - if recomended and not need_resort: - print("Recomending", recomended.name) - return # we have one recomended already + if recommended and not need_resort: + print("Recommending", recommended.name) + return # we have one recommended already - if recomended is None: - recomended = runtimes[0] + if recommended is None: + recommended = runtimes[0] def better_java_runtime(runtime: JavaRuntimeMeta): - if vender_priority(runtime.vender) < vender_priority(recomended.vender): + if vendor_priority(runtime.vendor) < vendor_priority(recommended.vendor): return False - if runtime.version < recomended.version: + if runtime.version < recommended.version: return False - if runtime.release_time < recomended.release_time: + if runtime.release_time < recommended.release_time: return False return True for runtime in runtimes: if better_java_runtime(runtime): - recomended.recomended = False - recomended = runtime - recomended.recomended = True + recommended.recommended = False + recommended = runtime + recommended.recommended = True - print("Recomending", recomended.name) + print("Recommending", recommended.name) def main(): @@ -359,7 +359,7 @@ def main(): for major, runtimes in javas.items(): for java_os in runtimes: print(f"Total runtimes for Java {major} {java_os}:", len(runtimes[java_os])) - ensure_one_recomended(runtimes[java_os]) + ensure_one_recommended(runtimes[java_os]) runtimes_file = os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") runtimes.write(runtimes_file) diff --git a/meta/model/java.py b/meta/model/java.py index ca45085ea3..7c5da18cdc 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -71,11 +71,11 @@ class JavaChecksumMeta(MetaBase): class JavaRuntimeMeta(MetaBase): name: str - vender: str + vendor: str url: str release_time: datetime = Field(alias="releaseTime") checksum: Optional[JavaChecksumMeta] - recomended: bool + recommended: bool download_type: JavaRuntimeDownloadType = Field(alias="downloadType") version: JavaVersionMeta @@ -196,7 +196,7 @@ class AdoptiumOs(StrEnum): ADOPTIUM_API_BASE = " https://api.adoptium.net" ADOPTIUM_API_FEATURE_RELEASES = f"{ADOPTIUM_API_BASE}/v3/assets/feature_releases/{{feature_version}}/{{release_type}}" -# ?image_type={{image_type}}&heap_size={{heap_size}}&project={{project}}&vender={{vender}}&page_size={{page_size}}&page={{page}}&sort_method={{sort_method}}&sort_order={{sort_order}} +# ?image_type={{image_type}}&heap_size={{heap_size}}&project={{project}}&vendor={{vendor}}&page_size={{page_size}}&page={{page}}&sort_method={{sort_method}}&sort_order={{sort_order}} ADOPTIUM_API_AVAILABLE_RELEASES = f"{ADOPTIUM_API_BASE}/v3/info/available_releases" @@ -213,7 +213,7 @@ class AdoptiumAPIFeatureReleasesQuery(APIQuery): project: Optional[AdoptiumProject] = AdoptiumProject.Jdk sort_method: Optional[AdoptiumSortMethod] = AdoptiumSortMethod.Default sort_order: Optional[AdoptiumSortOrder] = AdoptiumSortOrder.Desc - vender: Optional[AdoptiumVendor] = AdoptiumVendor.Eclipse + vendor: Optional[AdoptiumVendor] = AdoptiumVendor.Eclipse def adoptiumAPIFeatureReleasesUrl( -- cgit 0.0.5-2-1-g0f52 From acc6a4cd95d06327d93ca44578a998f5dac89c17 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 13 May 2023 16:20:50 -0700 Subject: fix: ensure JDK options are included (some platform vendor combos don't offer jre) Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- generateJava.py | 105 ++++++++++++++++++++++++++++++++---------------- meta/common/__init__.py | 6 +-- meta/model/java.py | 41 ++++++++++--------- updateJava.py | 33 ++++++++++----- 4 files changed, 120 insertions(+), 65 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index 982895725f..5e3420bfb4 100644 --- a/generateJava.py +++ b/generateJava.py @@ -1,11 +1,6 @@ import copy -import hashlib import os -from collections import defaultdict, namedtuple -from operator import attrgetter -from pprint import pprint -from packaging import version as pversion -from typing import Optional, List +from typing import Optional from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path @@ -21,6 +16,7 @@ from meta.model.java import ( JavaRuntimeMap, JavaRuntimeMeta, JavaVersionMeta, + JavaPackageType, JavaChecksumMeta, JavaChecksumType, JavaRuntimeDownloadType, @@ -143,26 +139,29 @@ def mojang_runtime_to_java_runtime( while len(version_parts) < 3: version_parts.append(0) - if len(version_parts) < 4: - version_parts.append(None) + + build = None + if len(version_parts) >= 4: + build = version_parts[3] version = JavaVersionMeta( major=version_parts[0], minor=version_parts[1], security=version_parts[2], - build=version_parts[3], + build=build, name=mojang_runtime.version.name, ) return JavaRuntimeMeta( name=f"mojang_jre_{mojang_runtime.version.name}", vendor="mojang", url=mojang_runtime.manifest.url, - release_time=mojang_runtime.version.released, + releaseTime=mojang_runtime.version.released, checksum=JavaChecksumMeta( type=JavaChecksumType.Sha1, hash=mojang_runtime.manifest.sha1 ), recommended=True, - download_type=JavaRuntimeDownloadType.Manifest, + downloadType=JavaRuntimeDownloadType.Manifest, + packageType=JavaPackageType.Jre, version=version, ) @@ -170,10 +169,20 @@ def mojang_runtime_to_java_runtime( def adoptium_release_binary_to_java_runtime( rls: AdoptiumRelease, binary: AdoptiumBinary ) -> JavaRuntimeMeta: + assert binary.package is not None + + checksum = None + if binary.package.checksum is not None: + checksum = JavaChecksumMeta( + type=JavaChecksumType.Sha256, hash=binary.package.checksum + ) + + pkg_type = JavaPackageType(str(binary.image_type)) + version = JavaVersionMeta( - major=rls.version_data.major, - minor=rls.version_data.minor, - security=rls.version_data.security, + major=rls.version_data.major if rls.version_data.major is not None else 0, + minor=rls.version_data.minor if rls.version_data.minor is not None else 0, + security=rls.version_data.security if rls.version_data.security is not None else 0, build=rls.version_data.build, ) rls_name = f"{rls.vendor}_temurin_{binary.image_type}{version}" @@ -181,38 +190,51 @@ def adoptium_release_binary_to_java_runtime( name=rls_name, vendor=rls.vendor, url=binary.package.link, - release_time=rls.timestamp, - checksum=JavaChecksumMeta( - type=JavaChecksumType.Sha256, hash=binary.package.checksum - ), + releaseTime=rls.timestamp, + checksum=checksum, recommended=False, - download_type=JavaRuntimeDownloadType.Archive, + downloadType=JavaRuntimeDownloadType.Archive, + packageType=pkg_type, version=version, ) def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: version_parts = copy.copy(pkg.java_version) - while len(version_parts) < 4: - version_parts.append(None) + + build = None + while len(version_parts) < 3: + version_parts.append(0) + + if len(version_parts) >= 4: + build = version_parts[3] version = JavaVersionMeta( major=version_parts[0], minor=version_parts[1], security=version_parts[2], - build=version_parts[3], + build=build, ) + pkg_type = JavaPackageType(str(pkg.java_package_type)) + rls_name = f"azul_{pkg.product}_{pkg.java_package_type}{version}" + checksum = None + if pkg.sha256_hash is not None: + checksum = JavaChecksumMeta( + type=JavaChecksumType.Sha256, hash=pkg.sha256_hash + ) + return JavaRuntimeMeta( name=rls_name, vendor="azul", url=pkg.download_url, - release_time=pkg.build_date, - checksum=JavaChecksumMeta(type=JavaChecksumType.Sha256, hash=pkg.sha256_hash), + releaseTime=pkg.build_date, + checksum=checksum, recommended=False, - download_type=JavaRuntimeDownloadType.Archive, + downloadType=JavaRuntimeDownloadType.Archive, + packageType=pkg_type, version=version, ) @@ -236,9 +258,17 @@ def vendor_priority(vendor: str) -> int: return __PREFERED_VENDOR_ORDER.index(vendor) -def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]): +def pkg_type_priority(pkg_type: JavaPackageType) -> int: + if pkg_type == JavaPackageType.Jre: + return 2 + elif pkg_type == JavaPackageType.Jdk: + return 1 + else: + return -1 + +def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]) -> Optional[JavaRuntimeMeta]: if len(runtimes) < 1: - return # can't do anything + return None# can't do anything recommended: Optional[JavaRuntimeMeta] = None found_first = False @@ -252,15 +282,18 @@ def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]): need_resort = True if recommended and not need_resort: - print("Recommending", recommended.name) - return # we have one recommended already + return recommended # we have one recommended already if recommended is None: recommended = runtimes[0] + def better_java_runtime(runtime: JavaRuntimeMeta): + assert recommended is not None if vendor_priority(runtime.vendor) < vendor_priority(recommended.vendor): return False + if pkg_type_priority(runtime.package_type) < pkg_type_priority(recommended.package_type): + return False if runtime.version < recommended.version: return False if runtime.release_time < recommended.release_time: @@ -273,7 +306,7 @@ def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]): recommended = runtime recommended.recommended = True - print("Recommending", recommended.name) + return recommended def main(): @@ -316,7 +349,7 @@ def main(): adoptium_releases = AdoptiumReleases.parse_file( os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{major}.json") ) - for rls in adoptium_releases: + for _, rls in adoptium_releases: for binary in rls.binaries: if binary.package is None: continue @@ -334,7 +367,7 @@ def main(): azul_packages = ZuluPackages.parse_file( os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") ) - for pkg in azul_packages: + for _, pkg in azul_packages: pkg_detail = ZuluPackageDetail.parse_file( os.path.join(UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json") ) @@ -357,9 +390,11 @@ def main(): add_java_runtime(runtime, major, java_os) for major, runtimes in javas.items(): - for java_os in runtimes: - print(f"Total runtimes for Java {major} {java_os}:", len(runtimes[java_os])) - ensure_one_recommended(runtimes[java_os]) + for java_os, runtime_list in runtimes: + print(f"Total runtimes for Java {major} {java_os}:", len(runtime_list)) + rec = ensure_one_recommended(runtime_list) + if rec is not None: + print(f"Recomending {rec.name} for Java {major} {java_os}") runtimes_file = os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") runtimes.write(runtimes_file) diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 7a6514b2be..f799cea500 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -32,13 +32,13 @@ def static_path(): return "static" -def ensure_upstream_dir(path): +def ensure_upstream_dir(path: str): path = os.path.join(upstream_path(), path) if not os.path.exists(path): os.makedirs(path) -def ensure_component_dir(component_id): +def ensure_component_dir(component_id: str): path = os.path.join(launcher_path(), component_id) if not os.path.exists(path): os.makedirs(path) @@ -48,7 +48,7 @@ def transform_maven_key(maven_key: str): return maven_key.replace(":", ".") -def replace_old_launchermeta_url(url): +def replace_old_launchermeta_url(url: str): o = urlparse(url) if o.netloc == "launchermeta.mojang.com": return o._replace(netloc="piston-meta.mojang.com").geturl() diff --git a/meta/model/java.py b/meta/model/java.py index 7c5da18cdc..d234b6cf59 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -5,9 +5,8 @@ from pydantic import Field from datetime import datetime from enum import IntEnum, Enum from .enum import StrEnum -from typing import Optional, List, Dict, Any, Iterator, Iterable, NamedTuple -from collections import namedtuple -from urllib.parse import urljoin, urlencode, urlparse, urlunparse +from typing import Optional, Any, NamedTuple, Generator +from urllib.parse import urlencode, urlparse, urlunparse from functools import total_ordering # namedtuple to match the internal signature of urlunparse @@ -52,7 +51,7 @@ class JavaVersionMeta(MetaBase): build = self.build return (self.major, self.minor, self.security, build) - def __eq__(self, other: 'JavaVersionMeta'): + def __eq__(self, other: Any): return (self.to_tuple() == other.to_tuple()) def __lt__(self, other: 'JavaVersionMeta'): @@ -69,6 +68,10 @@ class JavaChecksumMeta(MetaBase): hash: str +class JavaPackageType(StrEnum): + Jre = "jre" + Jdk = "jdk" + class JavaRuntimeMeta(MetaBase): name: str vendor: str @@ -77,6 +80,7 @@ class JavaRuntimeMeta(MetaBase): checksum: Optional[JavaChecksumMeta] recommended: bool download_type: JavaRuntimeDownloadType = Field(alias="downloadType") + package_type: JavaPackageType = Field(alias="packageType") version: JavaVersionMeta @@ -85,10 +89,10 @@ class JavaRuntimeMap(MetaBase): os: [] for os in JavaRuntimeOS if os != JavaRuntimeOS.Unknown } - def __iter__(self) -> Iterator[JavaRuntimeOS]: - return iter(self.__root__) + def __iter__(self) -> Generator[tuple[str, list[JavaRuntimeMeta]], None, None]: + yield from ((str(os), runtime) for os, runtime in self.__root__.items()) - def __getitem__(self, item) -> list[JavaRuntimeMeta]: + def __getitem__(self, item:JavaRuntimeOS) -> list[JavaRuntimeMeta]: return self.__root__[item] def __len__(self): @@ -299,10 +303,11 @@ class AdoptiumRelease(MetaBase): class AdoptiumReleases(MetaBase): __root__: list[AdoptiumRelease] - def __iter__(self) -> Iterator[AdoptiumRelease]: - return iter(self.__root__) + def __iter__(self) -> Generator[tuple[str, AdoptiumRelease], None, None]: + yield from ((str(i), val) for i, val in enumerate(self.__root__)) + - def __getitem__(self, item) -> AdoptiumRelease: + def __getitem__(self, item: int) -> AdoptiumRelease: return self.__root__[item] def append(self, rls: AdoptiumRelease): @@ -458,8 +463,8 @@ class AzulApiPackagesQuery(APIQuery): distro_version: Optional[str] = None java_package_features: list[str] = [] release_status: Optional[AzulReleaseStatus] = None - availability_types: list[AzulAvailabilityType] = None - certifications: list[AzulCertifications] = None + availability_types: list[AzulAvailabilityType] = [] + certifications: list[AzulCertifications] = [] include_fields: list[str] = [] page: int = 0 page_size: int = 100 @@ -528,10 +533,10 @@ class ZuluPackageList(MetaBase): class ZuluPackages(MetaBase): __root__: list[ZuluPackageList] - def __iter__(self) -> Iterator[ZuluPackageList]: - return iter(self.__root__) + def __iter__(self) -> Generator[tuple[str, ZuluPackageList], None, None]: + yield from ((str(i), val) for i, val in enumerate(self.__root__)) - def __getitem__(self, item) -> ZuluPackageList: + def __getitem__(self, item: int) -> ZuluPackageList: return self.__root__[item] def append(self, pkg: ZuluPackageList): @@ -541,10 +546,10 @@ class ZuluPackages(MetaBase): class ZuluPackagesDetail(MetaBase): __root__: list[ZuluPackageDetail] - def __iter__(self) -> Iterator[ZuluPackageDetail]: - return iter(self.__root__) + def __iter__(self) -> Generator[tuple[str, ZuluPackageDetail], None, None]: + yield from ((str(i), val) for i, val in enumerate(self.__root__)) - def __getitem__(self, item) -> ZuluPackageDetail: + def __getitem__(self, item: int) -> ZuluPackageDetail: return self.__root__[item] def append(self, pkg: ZuluPackageDetail): diff --git a/updateJava.py b/updateJava.py index ece97690be..4d174c9d5d 100644 --- a/updateJava.py +++ b/updateJava.py @@ -1,6 +1,4 @@ -import json import os -import zipfile from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session from meta.common.java import ( @@ -25,7 +23,6 @@ from meta.model.java import ( AzulArchiveType, AzulReleaseStatus, AzulAvailabilityType, - AzulJavaPackageType, azulApiPackageDetailUrl, ZuluPackageDetail, ZuluPackagesDetail, @@ -57,16 +54,35 @@ def main(): for feature in available.available_releases: print("Getting Manifests for Adoptium feature release:", feature) - page = 0 + page_size = 10 releases_for_feature: list[AdoptiumRelease] = [] - + page = 0 while True: query = AdoptiumAPIFeatureReleasesQuery( image_type=AdoptiumImageType.Jre, page_size=page_size, page=page) api_call = adoptiumAPIFeatureReleasesUrl(feature, query=query) - print("Fetching Page:", page, api_call) + print("Fetching JRE Page:", page, api_call) + r_rls = sess.get(api_call) + if r_rls.status_code == 404: + break + else: + r_rls.raise_for_status() + + releases = list(AdoptiumRelease(**rls) for rls in r_rls.json()) + releases_for_feature.extend(releases) + + if len(r_rls.json()) < page_size: + break + page += 1 + + page = 0 + while True: + query = AdoptiumAPIFeatureReleasesQuery( + image_type=AdoptiumImageType.Jdk, page_size=page_size, page=page) + api_call = adoptiumAPIFeatureReleasesUrl(feature, query=query) + print("Fetching JDK Page:", page, api_call) r_rls = sess.get(api_call) if r_rls.status_code == 404: break @@ -96,7 +112,6 @@ def main(): archive_type=AzulArchiveType.Zip, release_status=AzulReleaseStatus.Ga, availability_types=[AzulAvailabilityType.CA], - java_package_type=AzulJavaPackageType.Jre, javafx_bundled=False, page=page, page_size=page_size) @@ -121,9 +136,9 @@ def main(): azul_manifest_file = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") packages.write(azul_manifest_file) - azul_major_versions: dict[int, ZuluPackages] = {} + azul_major_versions: dict[int, ZuluPackagesDetail] = {} - for pkg in packages: + for _, pkg in packages: major_version = pkg.java_version[0] if major_version not in azul_major_versions: -- cgit 0.0.5-2-1-g0f52 From 19b046d235d7599ae4f75c3a7ed5715ecf51d02f Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 13 May 2023 20:06:22 -0700 Subject: don't track azul java verisons older than java 8 Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- generateJava.py | 43 +++++++++++++++++++++++++++---------------- meta/model/java.py | 29 +++++++++++++++-------------- updateJava.py | 17 ++++++++--------- 3 files changed, 50 insertions(+), 39 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index 5e3420bfb4..b32b786847 100644 --- a/generateJava.py +++ b/generateJava.py @@ -24,7 +24,7 @@ from meta.model.java import ( AdoptiumReleases, AdoptiumRelease, AdoptiumBinary, - ZuluPackages, + ZuluPackageList, ZuluPackageDetail, AzulArch, ) @@ -135,7 +135,8 @@ def mojang_runtime_to_java_runtime( if major and security: version_parts = [int(major), 0, int(security)] else: - version_parts = [int(part) for part in mojang_runtime.version.name.split(".")] + version_parts = [int(part) + for part in mojang_runtime.version.name.split(".")] while len(version_parts) < 3: version_parts.append(0) @@ -170,7 +171,7 @@ def adoptium_release_binary_to_java_runtime( rls: AdoptiumRelease, binary: AdoptiumBinary ) -> JavaRuntimeMeta: assert binary.package is not None - + checksum = None if binary.package.checksum is not None: checksum = JavaChecksumMeta( @@ -178,7 +179,7 @@ def adoptium_release_binary_to_java_runtime( ) pkg_type = JavaPackageType(str(binary.image_type)) - + version = JavaVersionMeta( major=rls.version_data.major if rls.version_data.major is not None else 0, minor=rls.version_data.minor if rls.version_data.minor is not None else 0, @@ -205,7 +206,7 @@ def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: build = None while len(version_parts) < 3: version_parts.append(0) - + if len(version_parts) >= 4: build = version_parts[3] @@ -266,9 +267,10 @@ def pkg_type_priority(pkg_type: JavaPackageType) -> int: else: return -1 + def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]) -> Optional[JavaRuntimeMeta]: if len(runtimes) < 1: - return None# can't do anything + return None # can't do anything recommended: Optional[JavaRuntimeMeta] = None found_first = False @@ -282,12 +284,11 @@ def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]) -> Optional[JavaRunt need_resort = True if recommended and not need_resort: - return recommended # we have one recommended already + return recommended # we have one recommended already if recommended is None: recommended = runtimes[0] - def better_java_runtime(runtime: JavaRuntimeMeta): assert recommended is not None if vendor_priority(runtime.vendor) < vendor_priority(recommended.vendor): @@ -318,7 +319,8 @@ def main(): def add_java_runtime(runtime: JavaRuntimeMeta, major: int, java_os: JavaRuntimeOS): ensure_javamap(major) - print(f"Regestering runtime: {runtime.name} for Java {major} {java_os}") + print( + f"Regestering runtime: {runtime.name} for Java {major} {java_os}") javas[major][java_os].append(runtime) print("Processing Mojang Javas") @@ -347,7 +349,8 @@ def main(): ) for major in adoptium_available_releases.available_releases: adoptium_releases = AdoptiumReleases.parse_file( - os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{major}.json") + os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, + f"java{major}.json") ) for _, rls in adoptium_releases: for binary in rls.binaries: @@ -356,7 +359,8 @@ def main(): binary_arch = translate_arch(str(binary.architecture)) binary_os = translate_os(str(binary.os)) if binary_arch is None or binary_os is None: - print(f"Ignoring release for {binary.os} {binary.architecture}") + print( + f"Ignoring release for {binary.os} {binary.architecture}") continue java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") @@ -364,17 +368,22 @@ def main(): add_java_runtime(runtime, major, java_os) print("Processing Azul Packages") - azul_packages = ZuluPackages.parse_file( + azul_packages = ZuluPackageList.parse_file( os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") ) for _, pkg in azul_packages: pkg_detail = ZuluPackageDetail.parse_file( - os.path.join(UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json") + os.path.join(UPSTREAM_DIR, AZUL_VERSIONS_DIR, + f"{pkg.package_uuid}.json") ) major = pkg_detail.java_version[0] + if major < 8: + continue # we will never need java versions less than 8 + pkg_os = translate_os(str(pkg_detail.os)) if pkg_detail.arch == AzulArch.Arm: - pkg_arch = translate_arch(f"{pkg_detail.arch}{pkg_detail.hw_bitness}") + pkg_arch = translate_arch( + f"{pkg_detail.arch}{pkg_detail.hw_bitness}") elif pkg_detail.arch == AzulArch.X86: pkg_arch = translate_arch(int(pkg_detail.hw_bitness)) else: @@ -391,12 +400,14 @@ def main(): for major, runtimes in javas.items(): for java_os, runtime_list in runtimes: - print(f"Total runtimes for Java {major} {java_os}:", len(runtime_list)) + print(f"Total runtimes for Java {major} {java_os}:", len( + runtime_list)) rec = ensure_one_recommended(runtime_list) if rec is not None: print(f"Recomending {rec.name} for Java {major} {java_os}") - runtimes_file = os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") + runtimes_file = os.path.join( + LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") runtimes.write(runtimes_file) diff --git a/meta/model/java.py b/meta/model/java.py index d234b6cf59..ac224fe16c 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -13,7 +13,7 @@ from functools import total_ordering class JavaRuntimeOS(StrEnum): MacOsX64 = "mac-os-x64" - MacOsX86 = "mac-os-x86" # rare + MacOsX86 = "mac-os-x86" # rare MacOsArm64 = "mac-os-arm64" # MacOsArm32 = "mac-os-arm32" # doesn't exsist LinuxX64 = "linux-x64" @@ -31,6 +31,7 @@ class JavaRuntimeDownloadType(StrEnum): Manifest = "manifest" Archive = "archive" + @total_ordering class JavaVersionMeta(MetaBase): major: int @@ -44,16 +45,16 @@ class JavaVersionMeta(MetaBase): if self.build is not None: ver = f"{ver}+{self.build}" return ver - + def to_tuple(self): build = 0 if self.build is not None: build = self.build return (self.major, self.minor, self.security, build) - + def __eq__(self, other: Any): return (self.to_tuple() == other.to_tuple()) - + def __lt__(self, other: 'JavaVersionMeta'): return (self.to_tuple() < other.to_tuple()) @@ -72,6 +73,7 @@ class JavaPackageType(StrEnum): Jre = "jre" Jdk = "jdk" + class JavaRuntimeMeta(MetaBase): name: str vendor: str @@ -92,7 +94,7 @@ class JavaRuntimeMap(MetaBase): def __iter__(self) -> Generator[tuple[str, list[JavaRuntimeMeta]], None, None]: yield from ((str(os), runtime) for os, runtime in self.__root__.items()) - def __getitem__(self, item:JavaRuntimeOS) -> list[JavaRuntimeMeta]: + def __getitem__(self, item: JavaRuntimeOS) -> list[JavaRuntimeMeta]: return self.__root__[item] def __len__(self): @@ -303,9 +305,8 @@ class AdoptiumRelease(MetaBase): class AdoptiumReleases(MetaBase): __root__: list[AdoptiumRelease] - def __iter__(self) -> Generator[tuple[str, AdoptiumRelease], None, None]: + def __iter__(self) -> Generator[tuple[str, AdoptiumRelease], None, None]: yield from ((str(i), val) for i, val in enumerate(self.__root__)) - def __getitem__(self, item: int) -> AdoptiumRelease: return self.__root__[item] @@ -518,7 +519,7 @@ class ZuluPackageDetail(MetaBase): signatures: list[ZuluSignatureDetail] -class ZuluPackageList(MetaBase): +class ZuluPackage(MetaBase): package_uuid: str name: Optional[str] java_version: list[int] @@ -530,23 +531,23 @@ class ZuluPackageList(MetaBase): availability_type: Optional[AzulAvailabilityType] -class ZuluPackages(MetaBase): - __root__: list[ZuluPackageList] +class ZuluPackageList(MetaBase): + __root__: list[ZuluPackage] - def __iter__(self) -> Generator[tuple[str, ZuluPackageList], None, None]: + def __iter__(self) -> Generator[tuple[str, ZuluPackage], None, None]: yield from ((str(i), val) for i, val in enumerate(self.__root__)) - def __getitem__(self, item: int) -> ZuluPackageList: + def __getitem__(self, item: int) -> ZuluPackage: return self.__root__[item] - def append(self, pkg: ZuluPackageList): + def append(self, pkg: ZuluPackage): self.__root__.append(pkg) class ZuluPackagesDetail(MetaBase): __root__: list[ZuluPackageDetail] - def __iter__(self) -> Generator[tuple[str, ZuluPackageDetail], None, None]: + def __iter__(self) -> Generator[tuple[str, ZuluPackageDetail], None, None]: yield from ((str(i), val) for i, val in enumerate(self.__root__)) def __getitem__(self, item: int) -> ZuluPackageDetail: diff --git a/updateJava.py b/updateJava.py index 4d174c9d5d..70862b9f55 100644 --- a/updateJava.py +++ b/updateJava.py @@ -18,8 +18,8 @@ from meta.model.java import ( AdoptiumReleases, azulApiPackagesUrl, AzulApiPackagesQuery, + ZuluPackage, ZuluPackageList, - ZuluPackages, AzulArchiveType, AzulReleaseStatus, AzulAvailabilityType, @@ -54,7 +54,7 @@ def main(): for feature in available.available_releases: print("Getting Manifests for Adoptium feature release:", feature) - + page_size = 10 releases_for_feature: list[AdoptiumRelease] = [] @@ -76,7 +76,7 @@ def main(): if len(r_rls.json()) < page_size: break page += 1 - + page = 0 while True: query = AdoptiumAPIFeatureReleasesQuery( @@ -103,7 +103,7 @@ def main(): releases.write(feature_file) print("Getting Azul Release Manifests") - zulu_packages: list[ZuluPackageList] = [] + zulu_packages: list[ZuluPackage] = [] page = 1 page_size = 100 while True: @@ -125,14 +125,14 @@ def main(): else: r.raise_for_status() - packages = list(ZuluPackageList(**pkg) for pkg in r.json()) + packages = list(ZuluPackage(**pkg) for pkg in r.json()) zulu_packages.extend(packages) if len(packages) < page_size: break page += 1 print("Total Azul Packages:", len(zulu_packages)) - packages = ZuluPackages(__root__=zulu_packages) + packages = ZuluPackageList(__root__=zulu_packages) azul_manifest_file = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") packages.write(azul_manifest_file) @@ -142,9 +142,8 @@ def main(): major_version = pkg.java_version[0] if major_version not in azul_major_versions: - azul_major_versions[major_version] = ZuluPackagesDetail(__root__=[]) - - + azul_major_versions[major_version] = ZuluPackagesDetail( + __root__=[]) pkg_file = os.path.join( UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json") -- cgit 0.0.5-2-1-g0f52 From 95223b83cbb6c726e5422b8803befc771afe36fa Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sat, 13 May 2023 20:44:26 -0700 Subject: cleanup: types Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- generateJava.py | 56 ++++++++++++++++++++----------------------------- meta/common/__init__.py | 11 +++++----- meta/model/__init__.py | 33 ++++++++++++++++------------- meta/model/java.py | 2 +- 4 files changed, 48 insertions(+), 54 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index b32b786847..b5f0934a10 100644 --- a/generateJava.py +++ b/generateJava.py @@ -46,17 +46,6 @@ STATIC_DIR = static_path() ensure_component_dir(JAVA_COMPONENT) -MOJANG_JAVA_OS_NAMES = [ - "gamecore", - "linux", - "linux-i386", - "mac-os", - "mac-os-arm64", - "windows-arm64", - "windows-x64", - "windows-x86", -] - MOJANG_OS_ARCHITECTURES = [ "x64", "x86", @@ -110,22 +99,23 @@ def translate_os(os: str): def mojang_os_to_java_os(mojang_os: MojangJavaOsName) -> JavaRuntimeOS: - if mojang_os == MojangJavaOsName.Linux: - return JavaRuntimeOS.LinuxX64 - elif mojang_os == MojangJavaOsName.Linuxi386: - return JavaRuntimeOS.LinuxX86 - elif mojang_os == MojangJavaOsName.MacOs: - return JavaRuntimeOS.MacOsX64 - elif mojang_os == MojangJavaOsName.MacOSArm64: - return JavaRuntimeOS.MacOsArm64 - elif mojang_os == MojangJavaOsName.WindowsArm64: - return JavaRuntimeOS.WindowsArm64 - elif mojang_os == MojangJavaOsName.WindowsX64: - return JavaRuntimeOS.WindowsX64 - elif mojang_os == MojangJavaOsName.WindowsX86: - return JavaRuntimeOS.WindowsX86 - else: - return JavaRuntimeOS.Unknown + match mojang_os: + case MojangJavaOsName.Linux: + return JavaRuntimeOS.LinuxX64 + case MojangJavaOsName.Linuxi386: + return JavaRuntimeOS.LinuxX86 + case MojangJavaOsName.MacOs: + return JavaRuntimeOS.MacOsX64 + case MojangJavaOsName.MacOSArm64: + return JavaRuntimeOS.MacOsArm64 + case MojangJavaOsName.WindowsArm64: + return JavaRuntimeOS.WindowsArm64 + case MojangJavaOsName.WindowsX64: + return JavaRuntimeOS.WindowsX64 + case MojangJavaOsName.WindowsX86: + return JavaRuntimeOS.WindowsX86 + case _: + return JavaRuntimeOS.Unknown def mojang_runtime_to_java_runtime( @@ -260,12 +250,12 @@ def vendor_priority(vendor: str) -> int: def pkg_type_priority(pkg_type: JavaPackageType) -> int: - if pkg_type == JavaPackageType.Jre: - return 2 - elif pkg_type == JavaPackageType.Jdk: - return 1 - else: - return -1 + match pkg_type: + case JavaPackageType.Jre: + return 2 + case JavaPackageType.Jdk: + return 1 + return -1 def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]) -> Optional[JavaRuntimeMeta]: diff --git a/meta/common/__init__.py b/meta/common/__init__.py index f799cea500..8f6a829f17 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -1,10 +1,11 @@ import os import datetime from urllib.parse import urlparse +from typing import Any, Optional import requests -from cachecontrol import CacheControl -from cachecontrol.caches import FileCache +from cachecontrol import CacheControl # type: ignore +from cachecontrol.caches import FileCache # type: ignore def serialize_datetime(dt: datetime.datetime): @@ -56,7 +57,7 @@ def replace_old_launchermeta_url(url: str): return url -def get_all_bases(cls, bases=None): +def get_all_bases(cls: type, bases: Optional[list[type]] = None): bases = bases or [] bases.append(cls) for c in cls.__bases__: @@ -64,10 +65,10 @@ def get_all_bases(cls, bases=None): return tuple(bases) -def merge_dict(base: dict, overlay: dict): +def merge_dict(base: dict[Any, Any], overlay: dict[Any, Any]): for k, v in base.items(): if isinstance(v, dict): - merge_dict(v, overlay.setdefault(k, {})) + merge_dict(v, overlay.setdefault(k, {})) # type: ignore else: if k not in overlay: overlay[k] = v diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 0428b7f1fb..efb6adf6d5 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -3,7 +3,7 @@ from datetime import datetime from typing import Optional, List, Dict, Any, Iterator import pydantic -from pydantic import Field, validator +from pydantic import Field, validator # type: ignore from ..common import ( serialize_datetime, @@ -85,13 +85,16 @@ class GradleSpecifier: def is_log4j(self): return self.group == "org.apache.logging.log4j" - def __eq__(self, other): - return str(self) == str(other) + def __eq__(self, other: Any): + if isinstance(other, GradleSpecifier): + return str(self) == str(other) + else: + return False - def __lt__(self, other): + def __lt__(self, other: 'GradleSpecifier'): return str(self) < str(other) - def __gt__(self, other): + def __gt__(self, other: 'GradleSpecifier'): return str(self) > str(other) def __hash__(self): @@ -120,7 +123,7 @@ class GradleSpecifier: return cls(group, artifact, version, classifier, extension) @classmethod - def validate(cls, v): + def validate(cls, v: 'str | GradleSpecifier'): if isinstance(v, cls): return v if isinstance(v, str): @@ -149,7 +152,7 @@ class MetaBase(pydantic.BaseModel): with open(file_path, "w") as f: f.write(self.json()) - def merge(self, other): + def merge(self, other: 'MetaBase'): """ Merge other object with self. - Concatenates lists @@ -173,14 +176,14 @@ class MetaBase(pydantic.BaseModel): elif isinstance(ours, set): ours |= theirs elif isinstance(ours, dict): - result = merge_dict(ours, copy.deepcopy(theirs)) + result = merge_dict(ours, copy.deepcopy(theirs)) # type: ignore setattr(self, key, result) elif MetaBase in get_all_bases(field.type_): ours.merge(theirs) else: setattr(self, key, theirs) - def __hash__(self): + def __hash__(self): #type: ignore return hash(self.json()) class Config: @@ -191,7 +194,7 @@ class MetaBase(pydantic.BaseModel): class Versioned(MetaBase): @validator("format_version") - def format_version_must_be_supported(cls, v): + def format_version_must_be_supported(cls, v: int): assert v <= META_FORMAT_VERSION return v @@ -206,7 +209,7 @@ class MojangArtifactBase(MetaBase): class MojangAssets(MojangArtifactBase): @validator("url") - def validate_url(cls, v): + def validate_url(cls, v: str): return replace_old_launchermeta_url(v) id: str @@ -242,7 +245,7 @@ class MojangLibraryDownloads(MetaBase): class OSRule(MetaBase): @validator("name") - def name_must_be_os(cls, v): + def name_must_be_os(cls, v: str): assert v in [ "osx", "linux", @@ -260,7 +263,7 @@ class OSRule(MetaBase): class MojangRule(MetaBase): @validator("action") - def action_must_be_allow_disallow(cls, v): + def action_must_be_allow_disallow(cls, v: str): assert v in ["allow", "disallow"] return v @@ -271,10 +274,10 @@ class MojangRule(MetaBase): class MojangRules(MetaBase): __root__: List[MojangRule] - def __iter__(self) -> Iterator[MojangRule]: + def __iter__(self) -> Iterator[MojangRule]: #type: ignore return iter(self.__root__) - def __getitem__(self, item) -> MojangRule: + def __getitem__(self, item: int) -> MojangRule: return self.__root__[item] diff --git a/meta/model/java.py b/meta/model/java.py index ac224fe16c..6a335df454 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -118,7 +118,7 @@ class APIQuery(MetaBase): if isinstance(value, Enum): set_parts[key] = value.value elif isinstance(value, list): - if len(value) > 0: + if len(value) > 0: #type: ignore set_parts[key] = value elif isinstance(value, datetime): set_parts[key] = value.isoformat() -- cgit 0.0.5-2-1-g0f52 From cc881a82d894c92be6809b453c6d7d2ccf28d512 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 16 Jun 2023 21:14:58 -0700 Subject: write java `package.json` Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- generateJava.py | 14 ++++++++++++-- meta/model/java.py | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index b5f0934a10..470146eaa6 100644 --- a/generateJava.py +++ b/generateJava.py @@ -11,9 +11,11 @@ from meta.common.java import ( AZUL_DIR, AZUL_VERSIONS_DIR, ) +from meta.model import MetaPackage from meta.model.java import ( JavaRuntimeOS, JavaRuntimeMap, + JavaRuntimeVersion, JavaRuntimeMeta, JavaVersionMeta, JavaPackageType, @@ -396,9 +398,17 @@ def main(): if rec is not None: print(f"Recomending {rec.name} for Java {major} {java_os}") - runtimes_file = os.path.join( + version_file = os.path.join( LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") - runtimes.write(runtimes_file) + java_version = JavaRuntimeVersion(name = f"Java {major}", uid = JAVA_COMPONENT, version = f"java{major}", runtimes = runtimes) + java_version.write(version_file) + + package = MetaPackage( + uid = JAVA_COMPONENT, + name = "Java Runtimes", + recommended = ["java8", "java17"] + ) + package.write(os.path.josn(LAUNCHER_DIR, JAVA_COMPONENT, "package.json")) if __name__ == "__main__": diff --git a/meta/model/java.py b/meta/model/java.py index 6a335df454..d232196706 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -1,5 +1,7 @@ from . import ( MetaBase, + MetaVersion, + Versioned, ) from pydantic import Field from datetime import datetime @@ -100,6 +102,8 @@ class JavaRuntimeMap(MetaBase): def __len__(self): return len(self.__root__) +class JavaRuntimeVersion(MetaVersion): + runtimes: JavaRuntimeMap class URLComponents(NamedTuple): scheme: str -- cgit 0.0.5-2-1-g0f52 From c06bc0cdaf2540bce9633e6d65fe68bb7fa62fe5 Mon Sep 17 00:00:00 2001 From: Stuart Pomeroy Date: Sun, 6 Aug 2023 12:15:18 +0100 Subject: Add support for automatically generating NeoForge metadata --- generateNeoForge.py | 424 ++++++++++++++++++++++++++++++++++++++++++++++++ index.py | 3 +- meta/common/neoforge.py | 17 ++ meta/model/__init__.py | 2 + meta/model/neoforge.py | 264 ++++++++++++++++++++++++++++++ testNeo.sh | 52 ++++++ update.sh | 2 + updateNeoForge.py | 338 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 1100 insertions(+), 2 deletions(-) create mode 100644 generateNeoForge.py create mode 100644 meta/common/neoforge.py create mode 100644 meta/model/neoforge.py create mode 100644 testNeo.sh create mode 100644 updateNeoForge.py (limited to 'meta') diff --git a/generateNeoForge.py b/generateNeoForge.py new file mode 100644 index 0000000000..2826c037b6 --- /dev/null +++ b/generateNeoForge.py @@ -0,0 +1,424 @@ +import os +import re +import sys +from distutils.version import LooseVersion +from operator import attrgetter +from typing import Collection + +from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path +from meta.common.neoforge import ( + NEOFORGE_COMPONENT, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + DERIVED_INDEX_FILE, + STATIC_LEGACYINFO_FILE, + INSTALLER_INFO_DIR, + BAD_VERSIONS, + FORGEWRAPPER_MAVEN, +) +from meta.common.forge import (FORGE_COMPONENT) +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import ( + MetaVersion, + Dependency, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + MetaPackage, +) +from meta.model.neoforge import ( + NeoForgeVersion, + NeoForgeInstallerProfile, + NeoForgeLegacyInfo, + fml_libs_for_version, + NeoForgeInstallerProfileV2, + InstallerInfo, + DerivedNeoForgeIndex, + NeoForgeLegacyInfoList, +) +from meta.model.mojang import MojangVersion + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() +STATIC_DIR = static_path() + +ensure_component_dir(NEOFORGE_COMPONENT) + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +# Construct a set of libraries out of a Minecraft version file, for filtering. +mc_version_cache = {} + + +def load_mc_version_filter(version: str): + if version in mc_version_cache: + return mc_version_cache[version] + v = MetaVersion.parse_file( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json") + ) + libs = set(map(attrgetter("name"), v.libraries)) + mc_version_cache[version] = libs + return libs + + +""" +Match a library coordinate to a set of library coordinates. + * Block those that pass completely. + * For others, block those with lower versions than in the set. +""" + + +def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpecifier): + for ver in libs: + if ( + ver.group == match.group + and ver.artifact == match.artifact + and ver.classifier == match.classifier + ): + if ver.version == match.version: + # Everything is matched perfectly - this one will be ignored + return True + elif LooseVersion(ver.version) > LooseVersion(match.version): + return True + else: + # Otherwise it did not match - new version is higher and this is an upgrade + return False + # No match found in the set - we need to keep this + return False + + +def version_from_profile( + profile: NeoForgeInstallerProfile, version: NeoForgeVersion +) -> MetaVersion: + v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) + mc_version = profile.install.minecraft + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = profile.version_info.main_class + v.release_time = profile.version_info.time + + args = profile.version_info.minecraft_arguments + tweakers = [] + expression = re.compile(r"--tweakClass ([a-zA-Z0-9.]+)") + match = expression.search(args) + while match is not None: + tweakers.append(match.group(1)) + args = args[: match.start()] + args[match.end() :] + match = expression.search(args) + if len(tweakers) > 0: + args = args.strip() + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + mc_filter = load_mc_version_filter(mc_version) + for forge_lib in profile.version_info.libraries: + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): + continue + + overridden_name = forge_lib.name + if overridden_name.group == "net.minecraftforge": + if overridden_name.artifact == "minecraftforge": + overridden_name.artifact = "forge" + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) + + overridden_name.classifier = "universal" + elif overridden_name.artifact == "forge": + overridden_name.classifier = "universal" + + overridden_lib = Library(name=overridden_name) + if forge_lib.url == "http://maven.minecraftforge.net/": + overridden_lib.url = "https://maven.minecraftforge.net/" + else: + overridden_lib.url = forge_lib.url + # if forge_lib.checksums and len(forge_lib.checksums) == 2: + # overridden_lib.mmcHint = "forge-pack-xz" + v.libraries.append(overridden_lib) + + v.order = 5 + return v + + +def version_from_modernized_installer( + installer: MojangVersion, version: NeoForgeVersion +) -> MetaVersion: + v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) + mc_version = version.mc_version + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = installer.main_class + v.release_time = installer.release_time + + args = installer.minecraft_arguments + tweakers = [] + expression = re.compile("--tweakClass ([a-zA-Z0-9.]+)") + match = expression.search(args) + while match is not None: + tweakers.append(match.group(1)) + args = args[: match.start()] + args[match.end() :] + match = expression.search(args) + if len(tweakers) > 0: + args = args.strip() + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + + mc_filter = load_mc_version_filter(mc_version) + for upstream_lib in installer.libraries: + forge_lib = Library.parse_obj( + upstream_lib.dict() + ) # "cast" MojangLibrary to Library + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): + continue + + if forge_lib.name.group == "net.minecraftforge": + if forge_lib.name.artifact == "forge": + overridden_name = forge_lib.name + overridden_name.classifier = "universal" + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) + forge_lib.name = overridden_name + + elif forge_lib.name.artifact == "minecraftforge": + overridden_name = forge_lib.name + overridden_name.artifact = "forge" + overridden_name.classifier = "universal" + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) + forge_lib.name = overridden_name + + v.libraries.append(forge_lib) + + v.order = 5 + return v + + +def version_from_legacy(info: NeoForgeLegacyInfo, version: NeoForgeVersion) -> MetaVersion: + v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) + mc_version = version.mc_version_sane + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.release_time = info.release_time + v.order = 5 + if fml_libs_for_version( + mc_version + ): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING + v.additional_traits = ["legacyFML"] + + classifier = "client" + if "universal" in version.url(): + classifier = "universal" + + main_mod = Library( + name=GradleSpecifier( + "net.minecraftforge", "forge", version.long_version, classifier + ) + ) + main_mod.downloads = MojangLibraryDownloads() + main_mod.downloads.artifact = MojangArtifact( + url=version.url(), sha1=info.sha1, size=info.size + ) + main_mod.downloads.artifact.path = None + v.jar_mods = [main_mod] + return v + + +def version_from_build_system_installer( + installer: MojangVersion, profile: NeoForgeInstallerProfileV2, version: NeoForgeVersion +) -> MetaVersion: + v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] + v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" + + # FIXME: Add the size and hash here + v.maven_files = [] + + # load the locally cached installer file info and use it to add the installer entry in the json + info = InstallerInfo.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") + ) + installer_lib = Library( + name=GradleSpecifier( + "net.neoforged", "forge", version.long_version, "installer" + ) + ) + installer_lib.downloads = MojangLibraryDownloads() + installer_lib.downloads.artifact = MojangArtifact( + url="https://maven.neoforged.net/%s" % (installer_lib.name.path()), + sha1=info.sha1hash, + size=info.size, + ) + v.maven_files.append(installer_lib) + + for upstream_lib in profile.libraries: + forge_lib = Library.parse_obj(upstream_lib.dict()) + if forge_lib.name.is_log4j(): + continue + + if ( + forge_lib.name.group == "net.neoforged" + and forge_lib.name.artifact == "forge" + and forge_lib.name.classifier == "universal" + ): + forge_lib.downloads.artifact.url = ( + "https://maven.neoforged.net/%s" % forge_lib.name.path() + ) + v.maven_files.append(forge_lib) + + v.libraries = [] + + wrapper_lib = Library( + name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6")) + wrapper_lib.downloads = MojangLibraryDownloads() + wrapper_lib.downloads.artifact = MojangArtifact( + url=FORGEWRAPPER_MAVEN, + sha1="b38d28e8b7fde13b1bc0db946a2da6760fecf98d", + size=34715, + ) + v.libraries.append(wrapper_lib) + + for upstream_lib in installer.libraries: + forge_lib = Library.parse_obj(upstream_lib.dict()) + if forge_lib.name.is_log4j(): + continue + + if forge_lib.name.group == "net.neoforged": + if forge_lib.name.artifact == "forge": + forge_lib.name.classifier = "launcher" + forge_lib.downloads.artifact.path = forge_lib.name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.neoforged.net/%s" % forge_lib.name.path() + ) + forge_lib.name = forge_lib.name + v.libraries.append(forge_lib) + + v.release_time = installer.release_time + v.order = 5 + mc_args = ( + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " + "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " + "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + ) + for arg in installer.arguments.game: + mc_args += f" {arg}" + v.minecraft_arguments = mc_args + return v + + +def main(): + # load the locally cached version list + remote_versions = DerivedNeoForgeIndex.parse_file( + os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) + ) + recommended_versions = [] + + + for key, entry in remote_versions.versions.items(): + if entry.mc_version is None: + eprint("Skipping %s with invalid MC version" % key) + continue + + version = NeoForgeVersion(entry) + + if version.long_version in BAD_VERSIONS: + # Version 1.12.2-14.23.5.2851 is ultra cringe, I can't imagine why you would even spend one second on + # actually adding support for this version. + # It is cringe, because it's installer info is broken af + eprint(f"Skipping bad version {version.long_version}") + continue + + if version.url() is None: + eprint("Skipping %s with no valid files" % key) + continue + eprint("Processing Forge %s" % version.rawVersion) + version_elements = version.rawVersion.split(".") + if len(version_elements) < 1: + eprint("Skipping version %s with not enough version elements" % key) + continue + + major_version_str = version_elements[0] + if not major_version_str.isnumeric(): + eprint( + "Skipping version %s with non-numeric major version %s" + % (key, major_version_str) + ) + continue + + if entry.recommended: + recommended_versions.append(version.rawVersion) + + # If we do not have the corresponding Minecraft version, we ignore it + if not os.path.isfile( + os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" + ) + ): + eprint( + "Skipping %s with no corresponding Minecraft version %s" + % (key, version.mc_version_sane) + ) + continue + + # Path for new-style build system based installers + installer_version_filepath = os.path.join( + UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" + ) + profile_filepath = os.path.join( + UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" + ) + + eprint(installer_version_filepath) + if os.path.isfile(installer_version_filepath): + installer = MojangVersion.parse_file(installer_version_filepath) + profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) + v = version_from_build_system_installer(installer, profile, version) + else: + if version.uses_installer(): + + # If we do not have the Forge json, we ignore this version + if not os.path.isfile(profile_filepath): + eprint("Skipping %s with missing profile json" % key) + continue + profile = NeoForgeInstallerProfile.parse_file(profile_filepath) + v = version_from_profile(profile, version) + + v.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, f"{v.version}.json")) + v.version = "NEO-"+v.version + v.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, f"{v.version}.json")) + + recommended_versions.sort() + + print("Recommended versions:", recommended_versions) + + package = MetaPackage( + uid=NEOFORGE_COMPONENT, + name="NeoForge", + project_url="https://neoforged.net", + ) + package.recommended = recommended_versions + package.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/index.py b/index.py index 38687037f4..2bf291616f 100755 --- a/index.py +++ b/index.py @@ -48,7 +48,6 @@ for package in sorted(os.listdir(LAUNCHER_DIR)): for filename in os.listdir(LAUNCHER_DIR + "/%s" % package): if filename in ignore: continue - # parse and hash the version file filepath = LAUNCHER_DIR + "/%s/%s" % (package, filename) filehash = hash_file(hashlib.sha256, filepath) @@ -58,7 +57,7 @@ for package in sorted(os.listdir(LAUNCHER_DIR)): versionEntry = MetaVersionIndexEntry.from_meta_version( versionFile, is_recommended, filehash ) - + versionList.versions.append(versionEntry) # sort the versions in descending order by time of release diff --git a/meta/common/neoforge.py b/meta/common/neoforge.py new file mode 100644 index 0000000000..d34ef19bd6 --- /dev/null +++ b/meta/common/neoforge.py @@ -0,0 +1,17 @@ +from os.path import join + +BASE_DIR = "neoforge" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "installer_info") +INSTALLER_MANIFEST_DIR = join(BASE_DIR, "installer_manifests") +VERSION_MANIFEST_DIR = join(BASE_DIR, "version_manifests") +FILE_MANIFEST_DIR = join(BASE_DIR, "files_manifests") +DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") + +STATIC_LEGACYINFO_FILE = join(BASE_DIR, "neoforge-legacyinfo.json") + +NEOFORGE_COMPONENT = "net.neoforged" + +FORGEWRAPPER_MAVEN = "https://github.com/ZekerZhayard/ForgeWrapper/releases/download/1.5.6/ForgeWrapper-1.5.6.jar" +BAD_VERSIONS = [""] diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 0246cdb3d1..14b054e5d2 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -1,5 +1,6 @@ import copy from datetime import datetime +from pathlib import Path from typing import Optional, List, Dict, Any, Iterator import pydantic @@ -146,6 +147,7 @@ class MetaBase(pydantic.BaseModel): ) def write(self, file_path): + Path(file_path).parent.mkdir(parents=True, exist_ok=True) with open(file_path, "w") as f: f.write(self.json()) diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py new file mode 100644 index 0000000000..b5721d04e8 --- /dev/null +++ b/meta/model/neoforge.py @@ -0,0 +1,264 @@ +from datetime import datetime +from typing import Optional, List, Dict + +from pydantic import Field + +from . import MetaBase, GradleSpecifier, MojangLibrary +from .mojang import MojangVersion + + +class NeoForgeFile(MetaBase): + classifier: str + extension: str + + def filename(self, long_version): + return "%s-%s-%s.%s" % ("forge", long_version, self.classifier, self.extension) + + def url(self, long_version): + return "https://maven.neoforged.net/net/neoforged/forge/%s/%s" % ( + long_version, + self.filename(long_version), + ) + + +class NeoForgeEntry(MetaBase): + long_version: str = Field(alias="longversion") + mc_version: str = Field(alias="mcversion") + version: str + build: int + branch: Optional[str] + latest: Optional[bool] + recommended: Optional[bool] + files: Optional[Dict[str, NeoForgeFile]] + + +class NeoForgeMCVersionInfo(MetaBase): + latest: Optional[str] + recommended: Optional[str] + versions: List[str] = Field([]) + + +class DerivedNeoForgeIndex(MetaBase): + versions: Dict[str, NeoForgeEntry] = Field({}) + by_mc_version: Dict[str, NeoForgeMCVersionInfo] = Field({}, alias="by_mcversion") + + +class FMLLib( + MetaBase +): # old ugly stuff. Maybe merge this with Library or MojangLibrary later + filename: str + checksum: str + ours: bool + + +class NeoForgeInstallerProfileInstallSection(MetaBase): + """ + "install": { + "profileName": "NeoForge", + "target":"NeoForge8.9.0.753", + "path":"net.minecraftNeoForge:minecraftNeoForge:8.9.0.753", + "version":"NeoForge 8.9.0.753", + "filePath":"minecraftNeoForge-universal-1.6.1-8.9.0.753.jar", + "welcome":"Welcome to the simple NeoForge installer.", + "minecraft":"1.6.1", + "logo":"/big_logo.png", + "mirrorList": "http://files.minecraftNeoForge.net/mirror-brand.list" + }, + "install": { + "profileName": "NeoForge", + "target":"1.11-NeoForge1.11-13.19.0.2141", + "path":"net.minecraftNeoForge:NeoForge:1.11-13.19.0.2141", + "version":"NeoForge 1.11-13.19.0.2141", + "filePath":"NeoForge-1.11-13.19.0.2141-universal.jar", + "welcome":"Welcome to the simple NeoForge installer.", + "minecraft":"1.11", + "mirrorList" : "http://files.minecraftNeoForge.net/mirror-brand.list", + "logo":"/big_logo.png", + "modList":"none" + }, + """ + + profile_name: str = Field(alias="profileName") + target: str + path: GradleSpecifier + version: str + file_path: str = Field(alias="filePath") + welcome: str + minecraft: str + logo: str + mirror_list: str = Field(alias="mirrorList") + mod_list: Optional[str] = Field(alias="modList") + + +class NeoForgeLibrary(MojangLibrary): + url: Optional[str] + server_req: Optional[bool] = Field(alias="serverreq") + client_req: Optional[bool] = Field(alias="clientreq") + checksums: Optional[List[str]] + comment: Optional[str] + + +class NeoForgeVersionFile(MojangVersion): + libraries: Optional[List[NeoForgeLibrary]] # overrides Mojang libraries + inherits_from: Optional[str] = Field("inheritsFrom") + jar: Optional[str] + + +class NeoForgeOptional(MetaBase): + """ + "optionals": [ + { + "name": "Mercurius", + "client": true, + "server": true, + "default": true, + "inject": true, + "desc": "A mod that collects statistics about Minecraft and your system.
Useful for NeoForge to understand how Minecraft/NeoForge are used.", + "url": "http://www.minecraftNeoForge.net/forum/index.php?topic=43278.0", + "artifact": "net.minecraftNeoForge:MercuriusUpdater:1.11.2", + "maven": "http://maven.minecraftNeoForge.net/" + } + ] + """ + + name: Optional[str] + client: Optional[bool] + server: Optional[bool] + default: Optional[bool] + inject: Optional[bool] + desc: Optional[str] + url: Optional[str] + artifact: Optional[GradleSpecifier] + maven: Optional[str] + + +class NeoForgeInstallerProfile(MetaBase): + install: NeoForgeInstallerProfileInstallSection + version_info: NeoForgeVersionFile = Field(alias="versionInfo") + optionals: Optional[List[NeoForgeOptional]] + + +class NeoForgeLegacyInfo(MetaBase): + release_time: Optional[datetime] = Field(alias="releaseTime") + size: Optional[int] + sha256: Optional[str] + sha1: Optional[str] + + +class NeoForgeLegacyInfoList(MetaBase): + number: Dict[str, NeoForgeLegacyInfo] = Field({}) + + +class DataSpec(MetaBase): + client: Optional[str] + server: Optional[str] + + +class ProcessorSpec(MetaBase): + jar: Optional[str] + classpath: Optional[List[str]] + args: Optional[List[str]] + outputs: Optional[Dict[str, str]] + sides: Optional[List[str]] + + +class NeoForgeInstallerProfileV2(MetaBase): + _comment: Optional[List[str]] + spec: Optional[int] + profile: Optional[str] + version: Optional[str] + icon: Optional[str] + json_data: Optional[str] = Field(alias="json") + path: Optional[GradleSpecifier] + logo: Optional[str] + minecraft: Optional[str] + welcome: Optional[str] + data: Optional[Dict[str, DataSpec]] + processors: Optional[List[ProcessorSpec]] + libraries: Optional[List[MojangLibrary]] + mirror_list: Optional[str] = Field(alias="mirrorList") + server_jar_path: Optional[str] = Field(alias="serverJarPath") + + +class InstallerInfo(MetaBase): + sha1hash: Optional[str] + sha256hash: Optional[str] + size: Optional[int] + + +# A post-processed entry constructed from the reconstructed NeoForge version index +class NeoForgeVersion: + def __init__(self, entry: NeoForgeEntry): + self.build = entry.build + self.rawVersion = entry.version + self.mc_version = entry.mc_version + self.mc_version_sane = self.mc_version.replace("_pre", "-pre", 1) + self.branch = entry.branch + self.installer_filename = None + self.installer_url = None + self.universal_filename = None + self.universal_url = None + self.changelog_url = None + self.long_version = "%s-%s" % (self.mc_version, self.rawVersion) + if self.branch is not None: + self.long_version += "-%s" % self.branch + + # this comment's whole purpose is to say this: cringe + for classifier, file in entry.files.items(): + extension = file.extension + filename = file.filename(self.long_version) + url = file.url(self.long_version) + print(url) + print(self.long_version) + if (classifier == "installer") and (extension == "jar"): + self.installer_filename = filename + self.installer_url = url + if (classifier == "universal" or classifier == "client") and ( + extension == "jar" or extension == "zip" + ): + self.universal_filename = filename + self.universal_url = url + if (classifier == "changelog") and (extension == "txt"): + self.changelog_url = url + + def name(self): + return "forge %d" % self.build + + def uses_installer(self): + if self.installer_url is None: + return False + if self.mc_version == "1.5.2": + return False + return True + + def filename(self): + if self.uses_installer(): + return self.installer_filename + return self.universal_filename + + def url(self): + if self.uses_installer(): + return self.installer_url + return self.universal_url + + def is_supported(self): + if self.url() is None: + return False + + foo = self.rawVersion.split(".") + if len(foo) < 1: + return False + + major_version = foo[0] + if not major_version.isnumeric(): + return False + + # majorVersion = int(majorVersionStr) + # if majorVersion >= 37: + # return False + + return True + + +def fml_libs_for_version(mc_version: str) -> List[FMLLib]: + return [] diff --git a/testNeo.sh b/testNeo.sh new file mode 100644 index 0000000000..92f7ac04fd --- /dev/null +++ b/testNeo.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +BASEDIR=$(dirname "$0") +cd "${BASEDIR}" || exit 1 +BASEDIR=$(pwd) + +set -x + +source config.sh +if [ -f config/config_local.sh ]; then + source config/config_local.sh +fi + +MODE=${MODE:-develop} + +BRANCH_var="BRANCH_$MODE" +BRANCH="${!BRANCH_var}" + +function fail_in { + upstream_git reset --hard HEAD + exit 1 +} + +function fail_out { + launcher_git reset --hard HEAD + exit 1 +} + +function upstream_git { + git -C "${BASEDIR}/${UPSTREAM_DIR}" "$@" +} + +function launcher_git { + git -C "${BASEDIR}/${LAUNCHER_DIR}" "$@" +} + +# make sure we *could* push to our repo + +currentDate=$(date -I) + +upstream_git reset --hard HEAD || exit 1 +upstream_git checkout "${BRANCH}" || exit 1 + + +python updateNeoForge.py || fail_in + +launcher_git reset --hard HEAD || exit 1 +launcher_git checkout "${BRANCH}" || exit 1 + + +python generateNeoForge.py || fail_out +python index.py || fail_out \ No newline at end of file diff --git a/update.sh b/update.sh index 9286c80ca6..850e1cc883 100755 --- a/update.sh +++ b/update.sh @@ -43,6 +43,7 @@ upstream_git checkout "${BRANCH}" || exit 1 python updateMojang.py || fail_in python updateForge.py || fail_in +python updateNeoForge.py || fail_in python updateFabric.py || fail_in python updateQuilt.py || fail_in python updateLiteloader.py || fail_in @@ -64,6 +65,7 @@ launcher_git checkout "${BRANCH}" || exit 1 python generateMojang.py || fail_out python generateForge.py || fail_out +python generateNeoForge.py || fail_out python generateFabric.py || fail_out python generateQuilt.py || fail_out python generateLiteloader.py || fail_out diff --git a/updateNeoForge.py b/updateNeoForge.py new file mode 100644 index 0000000000..d1ffc99ce3 --- /dev/null +++ b/updateNeoForge.py @@ -0,0 +1,338 @@ +""" + Get the source files necessary for generating Forge versions +""" +import copy +import hashlib +import json +import os +import re +import sys +import zipfile +from contextlib import suppress +from datetime import datetime +from pathlib import Path +from pprint import pprint +import urllib.parse + +from pydantic import ValidationError + +from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session +from meta.common.forge import ( + JARS_DIR, + INSTALLER_INFO_DIR, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + FILE_MANIFEST_DIR, + BAD_VERSIONS, + STATIC_LEGACYINFO_FILE, +) +from meta.model.neoforge import ( + NeoForgeFile, + NeoForgeEntry, + NeoForgeMCVersionInfo, + NeoForgeLegacyInfoList, + DerivedNeoForgeIndex, + NeoForgeVersion, + NeoForgeInstallerProfile, + NeoForgeInstallerProfileV2, + InstallerInfo, + NeoForgeLegacyInfo, +) +from meta.model.mojang import MojangVersion + +UPSTREAM_DIR = upstream_path() +STATIC_DIR = static_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(INSTALLER_MANIFEST_DIR) +ensure_upstream_dir(VERSION_MANIFEST_DIR) +ensure_upstream_dir(FILE_MANIFEST_DIR) + +LEGACYINFO_PATH = os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE) + +sess = default_session() + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def filehash(filename, hashtype, blocksize=65536): + hashtype = hashtype() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + hashtype.update(block) + return hashtype.hexdigest() + +def find_nth(haystack, needle, n): + start = haystack.find(needle) + while start >= 0 and n > 1: + start = haystack.find(needle, start+len(needle)) + n -= 1 + return start + +def get_single_forge_files_manifest(longversion): + print(f"Getting NeoForge manifest for {longversion}") + path_thing = UPSTREAM_DIR + "/neoforge/files_manifests/%s.json" % longversion + files_manifest_file = Path(path_thing) + from_file = False + if files_manifest_file.is_file(): + with open(path_thing, "r") as f: + files_json = json.load(f) + from_file = True + else: + file_url = ( + "https://maven.neoforged.net/api/maven/details/releases/net%2Fneoforged%2Fforge%2F" + urllib.parse.quote(longversion) + ) + r = sess.get(file_url) + r.raise_for_status() + files_json = r.json() + + ret_dict = dict() + + for file in files_json.get("files"): + assert type(file) == dict + name = file["name"] + file_name, file_ext = os.path.splitext(name) + if file_ext in [".md5", ".sha1", ".sha256", ".sha512"]: + continue + + classifier = file["name"][find_nth(name, "-", 3)+1:len(file_name)] + + # assert len(extensionObj.items()) == 1 + index = 0 + count = 0 + file_obj = NeoForgeFile( + classifier=classifier, extension=file_ext[1:] + ) + if count == 0: + ret_dict[classifier] = file_obj + index += 1 + count += 1 + else: + print( + "%s: Multiple objects detected for classifier %s:" + % (longversion, classifier) + ) + assert False + + + + if not from_file: + Path(path_thing).parent.mkdir(parents=True, exist_ok=True) + with open(path_thing, "w", encoding="utf-8") as f: + json.dump(files_json, f, sort_keys=True, indent=4) + + return ret_dict + + +def main(): + # get the remote version list fragments + r = sess.get( + "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fforge" + ) + r.raise_for_status() + main_json = r.json()["versions"] + assert type(main_json) == list + + new_index = DerivedNeoForgeIndex() + + version_expression = re.compile( + "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$" + ) + + print("") + print("Processing versions:") + for long_version in main_json: + assert type(long_version) == str + mc_version = long_version.split("-")[0] + match = version_expression.match(long_version) + if not match: + pprint(long_version) + assert match + assert match.group("mc") == mc_version + try: + files = get_single_forge_files_manifest(long_version) + except: + continue + build = int(match.group("build")) + version = match.group("ver") + branch = match.group("branch") + + is_recommended = False + + entry = NeoForgeEntry( + long_version=long_version, + mc_version=mc_version, + version=version, + build=build, + branch=branch, + # NOTE: we add this later after the fact. The forge promotions file lies about these. + latest=False, + recommended=is_recommended, + files=files, + ) + new_index.versions[long_version] = entry + if not new_index.by_mc_version: + new_index.by_mc_version = dict() + if mc_version not in new_index.by_mc_version: + new_index.by_mc_version.setdefault(mc_version, NeoForgeMCVersionInfo()) + new_index.by_mc_version[mc_version].versions.append(long_version) + # NOTE: we add this later after the fact. The forge promotions file lies about these. + # if entry.latest: + # new_index.by_mc_version[mc_version].latest = long_version + if entry.recommended: + new_index.by_mc_version[mc_version].recommended = long_version + + print("") + print("Dumping index files...") + + with open(UPSTREAM_DIR + "/neoforge/maven-metadata.json", "w", encoding="utf-8") as f: + json.dump(main_json, f, sort_keys=True, indent=4) + + new_index.write(UPSTREAM_DIR + "/neoforge/derived_index.json") + + legacy_info_list = NeoForgeLegacyInfoList() + + print("Grabbing installers and dumping installer profiles...") + # get the installer jars - if needed - and get the installer profiles out of them + for key, entry in new_index.versions.items(): + eprint("Updating NeoForge %s" % key) + if entry.mc_version is None: + eprint("Skipping %d with invalid MC version" % entry.build) + continue + + version = NeoForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + continue + if version.long_version in BAD_VERSIONS: + eprint(f"Skipping bad version {version.long_version}") + continue + + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) + + if version.uses_installer(): + installer_info_path = ( + UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + + "/neoforge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version + ) + + installer_refresh_required = not os.path.isfile( + profile_path + ) or not os.path.isfile(installer_info_path) + + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + try: + rfile = sess.get(version.url(), stream=True) + rfile.raise_for_status() + Path(jar_path).parent.mkdir(parents=True, exist_ok=True) + with open(jar_path, "wb") as f: + for chunk in rfile.iter_content(chunk_size=128): + f.write(chunk) + except Exception as e: + eprint("Failed to download %s" % version.url()) + eprint("Error is %s" % e) + continue + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + Path(version_file_path).parent.mkdir(parents=True, exist_ok=True) + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + NeoForgeInstallerProfile.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + try: + NeoForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + Path(profile_path).parent.mkdir(parents=True, exist_ok=True) + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = filehash(jar_path, hashlib.sha1) + installer_info.sha256hash = filehash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) + else: + # ignore the two versions without install manifests and jar mod class files + # TODO: fix those versions? + if version.mc_version_sane == "1.6.1": + continue + + # only gather legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + # grab the jar/zip if it's not there + if not os.path.isfile(jar_path): + rfile = sess.get(version.url(), stream=True) + rfile.raise_for_status() + with open(jar_path, "wb") as f: + for chunk in rfile.iter_content(chunk_size=128): + f.write(chunk) + # find the latest timestamp in the zip file + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + for info in jar.infolist(): + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + legacy_info = NeoForgeLegacyInfo() + legacy_info.release_time = tstamp + legacy_info.sha1 = filehash(jar_path, hashlib.sha1) + legacy_info.sha256 = filehash(jar_path, hashlib.sha256) + legacy_info.size = os.path.getsize(jar_path) + legacy_info_list.number[key] = legacy_info + + # only write legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + legacy_info_list.write(LEGACYINFO_PATH) + + +if __name__ == "__main__": + main() -- cgit 0.0.5-2-1-g0f52 From 51dda0e273b89640ce9d84ea5b4d3ec12de44714 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Aug 2023 14:56:09 +0200 Subject: fix: switch to Prism fork of ForgeWrapper Signed-off-by: Sefa Eyeoglu --- generateNeoForge.py | 8 ++++---- meta/common/neoforge.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'meta') diff --git a/generateNeoForge.py b/generateNeoForge.py index 55fb9c5862..78898c55c7 100644 --- a/generateNeoForge.py +++ b/generateNeoForge.py @@ -293,13 +293,13 @@ def version_from_build_system_installer( v.libraries = [] wrapper_lib = Library( - name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6") + name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6-prism") ) wrapper_lib.downloads = MojangLibraryDownloads() wrapper_lib.downloads.artifact = MojangArtifact( - url=FORGEWRAPPER_MAVEN, - sha1="b38d28e8b7fde13b1bc0db946a2da6760fecf98d", - size=34715, + url=FORGEWRAPPER_MAVEN % (wrapper_lib.name.path()), + sha1="b059aa8c4d2508055c6ed2a2561923a5e670a5eb", + size=34860, ) v.libraries.append(wrapper_lib) diff --git a/meta/common/neoforge.py b/meta/common/neoforge.py index d34ef19bd6..d5d08ec939 100644 --- a/meta/common/neoforge.py +++ b/meta/common/neoforge.py @@ -13,5 +13,5 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "neoforge-legacyinfo.json") NEOFORGE_COMPONENT = "net.neoforged" -FORGEWRAPPER_MAVEN = "https://github.com/ZekerZhayard/ForgeWrapper/releases/download/1.5.6/ForgeWrapper-1.5.6.jar" +FORGEWRAPPER_MAVEN = "https://files.prismlauncher.org/maven/%s" BAD_VERSIONS = [""] -- cgit 0.0.5-2-1-g0f52 From e3a82eda07264045e9b40859d01c7a36af8d193f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Aug 2023 15:01:45 +0200 Subject: fix: remove unused legacy stuff Signed-off-by: Sefa Eyeoglu --- generateNeoForge.py | 109 ------------------------- meta/common/neoforge.py | 3 - meta/model/neoforge.py | 15 ---- updateNeoForge.py | 208 +++++++++++++++++++----------------------------- 4 files changed, 83 insertions(+), 252 deletions(-) (limited to 'meta') diff --git a/generateNeoForge.py b/generateNeoForge.py index 78898c55c7..2e556a6337 100644 --- a/generateNeoForge.py +++ b/generateNeoForge.py @@ -11,9 +11,7 @@ from meta.common.neoforge import ( INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, - STATIC_LEGACYINFO_FILE, INSTALLER_INFO_DIR, - BAD_VERSIONS, FORGEWRAPPER_MAVEN, ) from meta.common.forge import FORGE_COMPONENT @@ -30,12 +28,9 @@ from meta.model import ( from meta.model.neoforge import ( NeoForgeVersion, NeoForgeInstallerProfile, - NeoForgeLegacyInfo, - fml_libs_for_version, NeoForgeInstallerProfileV2, InstallerInfo, DerivedNeoForgeIndex, - NeoForgeLegacyInfoList, ) from meta.model.mojang import MojangVersion @@ -149,103 +144,6 @@ def version_from_profile( return v -def version_from_modernized_installer( - installer: MojangVersion, version: NeoForgeVersion -) -> MetaVersion: - v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) - mc_version = version.mc_version - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] - v.main_class = installer.main_class - v.release_time = installer.release_time - - args = installer.minecraft_arguments - tweakers = [] - expression = re.compile("--tweakClass ([a-zA-Z0-9.]+)") - match = expression.search(args) - while match is not None: - tweakers.append(match.group(1)) - args = args[: match.start()] + args[match.end() :] - match = expression.search(args) - if len(tweakers) > 0: - args = args.strip() - v.additional_tweakers = tweakers - # v.minecraftArguments = args - - v.libraries = [] - - mc_filter = load_mc_version_filter(mc_version) - for upstream_lib in installer.libraries: - forge_lib = Library.parse_obj( - upstream_lib.dict() - ) # "cast" MojangLibrary to Library - if ( - forge_lib.name.is_lwjgl() - or forge_lib.name.is_log4j() - or should_ignore_artifact(mc_filter, forge_lib.name) - ): - continue - - if forge_lib.name.group == "net.minecraftforge": - if forge_lib.name.artifact == "forge": - overridden_name = forge_lib.name - overridden_name.classifier = "universal" - forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = ( - "https://maven.minecraftforge.net/%s" % overridden_name.path() - ) - forge_lib.name = overridden_name - - elif forge_lib.name.artifact == "minecraftforge": - overridden_name = forge_lib.name - overridden_name.artifact = "forge" - overridden_name.classifier = "universal" - overridden_name.version = "%s-%s" % ( - mc_version, - overridden_name.version, - ) - forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = ( - "https://maven.minecraftforge.net/%s" % overridden_name.path() - ) - forge_lib.name = overridden_name - - v.libraries.append(forge_lib) - - v.order = 5 - return v - - -def version_from_legacy( - info: NeoForgeLegacyInfo, version: NeoForgeVersion -) -> MetaVersion: - v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) - mc_version = version.mc_version_sane - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] - v.release_time = info.release_time - v.order = 5 - if fml_libs_for_version( - mc_version - ): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING - v.additional_traits = ["legacyFML"] - - classifier = "client" - if "universal" in version.url(): - classifier = "universal" - - main_mod = Library( - name=GradleSpecifier( - "net.minecraftforge", "forge", version.long_version, classifier - ) - ) - main_mod.downloads = MojangLibraryDownloads() - main_mod.downloads.artifact = MojangArtifact( - url=version.url(), sha1=info.sha1, size=info.size - ) - main_mod.downloads.artifact.path = None - v.jar_mods = [main_mod] - return v - - def version_from_build_system_installer( installer: MojangVersion, profile: NeoForgeInstallerProfileV2, @@ -345,13 +243,6 @@ def main(): version = NeoForgeVersion(entry) - if version.long_version in BAD_VERSIONS: - # Version 1.12.2-14.23.5.2851 is ultra cringe, I can't imagine why you would even spend one second on - # actually adding support for this version. - # It is cringe, because it's installer info is broken af - eprint(f"Skipping bad version {version.long_version}") - continue - if version.url() is None: eprint("Skipping %s with no valid files" % key) continue diff --git a/meta/common/neoforge.py b/meta/common/neoforge.py index d5d08ec939..079933008a 100644 --- a/meta/common/neoforge.py +++ b/meta/common/neoforge.py @@ -9,9 +9,6 @@ VERSION_MANIFEST_DIR = join(BASE_DIR, "version_manifests") FILE_MANIFEST_DIR = join(BASE_DIR, "files_manifests") DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") -STATIC_LEGACYINFO_FILE = join(BASE_DIR, "neoforge-legacyinfo.json") - NEOFORGE_COMPONENT = "net.neoforged" FORGEWRAPPER_MAVEN = "https://files.prismlauncher.org/maven/%s" -BAD_VERSIONS = [""] diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index b5721d04e8..906b20bfca 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -138,17 +138,6 @@ class NeoForgeInstallerProfile(MetaBase): optionals: Optional[List[NeoForgeOptional]] -class NeoForgeLegacyInfo(MetaBase): - release_time: Optional[datetime] = Field(alias="releaseTime") - size: Optional[int] - sha256: Optional[str] - sha1: Optional[str] - - -class NeoForgeLegacyInfoList(MetaBase): - number: Dict[str, NeoForgeLegacyInfo] = Field({}) - - class DataSpec(MetaBase): client: Optional[str] server: Optional[str] @@ -258,7 +247,3 @@ class NeoForgeVersion: # return False return True - - -def fml_libs_for_version(mc_version: str) -> List[FMLLib]: - return [] diff --git a/updateNeoForge.py b/updateNeoForge.py index d7a6ed80e3..57b5492606 100644 --- a/updateNeoForge.py +++ b/updateNeoForge.py @@ -23,20 +23,16 @@ from meta.common.forge import ( INSTALLER_MANIFEST_DIR, VERSION_MANIFEST_DIR, FILE_MANIFEST_DIR, - BAD_VERSIONS, - STATIC_LEGACYINFO_FILE, ) from meta.model.neoforge import ( NeoForgeFile, NeoForgeEntry, NeoForgeMCVersionInfo, - NeoForgeLegacyInfoList, DerivedNeoForgeIndex, NeoForgeVersion, NeoForgeInstallerProfile, NeoForgeInstallerProfileV2, InstallerInfo, - NeoForgeLegacyInfo, ) from meta.model.mojang import MojangVersion @@ -49,8 +45,6 @@ ensure_upstream_dir(INSTALLER_MANIFEST_DIR) ensure_upstream_dir(VERSION_MANIFEST_DIR) ensure_upstream_dir(FILE_MANIFEST_DIR) -LEGACYINFO_PATH = os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE) - sess = default_session() @@ -194,8 +188,6 @@ def main(): new_index.write(UPSTREAM_DIR + "/neoforge/derived_index.json") - legacy_info_list = NeoForgeLegacyInfoList() - print("Grabbing installers and dumping installer profiles...") # get the installer jars - if needed - and get the installer profiles out of them for key, entry in new_index.versions.items(): @@ -208,134 +200,100 @@ def main(): if version.url() is None: eprint("Skipping %d with no valid files" % version.build) continue - if version.long_version in BAD_VERSIONS: - eprint(f"Skipping bad version {version.long_version}") + if not version.uses_installer(): + eprint(f"version {version.long_version} does not use installer") continue jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) - if version.uses_installer(): - installer_info_path = ( - UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version - ) - profile_path = ( - UPSTREAM_DIR - + "/neoforge/installer_manifests/%s.json" % version.long_version - ) - version_file_path = ( - UPSTREAM_DIR - + "/neoforge/version_manifests/%s.json" % version.long_version - ) - - installer_refresh_required = not os.path.isfile( - profile_path - ) or not os.path.isfile(installer_info_path) - - if installer_refresh_required: - # grab the installer if it's not there - if not os.path.isfile(jar_path): - eprint("Downloading %s" % version.url()) - try: - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - Path(jar_path).parent.mkdir(parents=True, exist_ok=True) - with open(jar_path, "wb") as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) - except Exception as e: - eprint("Failed to download %s" % version.url()) - eprint("Error is %s" % e) - continue - - eprint("Processing %s" % version.url()) - # harvestables from the installer - if not os.path.isfile(profile_path): - print(jar_path) - with zipfile.ZipFile(jar_path) as jar: - with suppress(KeyError): - with jar.open("version.json") as profile_zip_entry: - version_data = profile_zip_entry.read() - - # Process: does it parse? - MojangVersion.parse_raw(version_data) - - Path(version_file_path).parent.mkdir( - parents=True, exist_ok=True - ) - with open(version_file_path, "wb") as versionJsonFile: - versionJsonFile.write(version_data) - versionJsonFile.close() + installer_info_path = ( + UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + + "/neoforge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version + ) - with jar.open("install_profile.json") as profile_zip_entry: - install_profile_data = profile_zip_entry.read() + installer_refresh_required = not os.path.isfile( + profile_path + ) or not os.path.isfile(installer_info_path) - # Process: does it parse? - is_parsable = False - exception = None - try: - NeoForgeInstallerProfile.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - try: - NeoForgeInstallerProfileV2.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - - if not is_parsable: - if version.is_supported(): - raise exception - else: - eprint( - "Version %s is not supported and won't be generated later." - % version.long_version - ) - - Path(profile_path).parent.mkdir(parents=True, exist_ok=True) - with open(profile_path, "wb") as profileFile: - profileFile.write(install_profile_data) - profileFile.close() - - # installer info v1 - if not os.path.isfile(installer_info_path): - installer_info = InstallerInfo() - installer_info.sha1hash = filehash(jar_path, hashlib.sha1) - installer_info.sha256hash = filehash(jar_path, hashlib.sha256) - installer_info.size = os.path.getsize(jar_path) - installer_info.write(installer_info_path) - else: - # ignore the two versions without install manifests and jar mod class files - # TODO: fix those versions? - if version.mc_version_sane == "1.6.1": - continue - - # only gather legacy info if it's missing - if not os.path.isfile(LEGACYINFO_PATH): - # grab the jar/zip if it's not there - if not os.path.isfile(jar_path): + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + try: rfile = sess.get(version.url(), stream=True) rfile.raise_for_status() + Path(jar_path).parent.mkdir(parents=True, exist_ok=True) with open(jar_path, "wb") as f: for chunk in rfile.iter_content(chunk_size=128): f.write(chunk) - # find the latest timestamp in the zip file - tstamp = datetime.fromtimestamp(0) - with zipfile.ZipFile(jar_path) as jar: - for info in jar.infolist(): - tstamp_new = datetime(*info.date_time) - if tstamp_new > tstamp: - tstamp = tstamp_new - legacy_info = NeoForgeLegacyInfo() - legacy_info.release_time = tstamp - legacy_info.sha1 = filehash(jar_path, hashlib.sha1) - legacy_info.sha256 = filehash(jar_path, hashlib.sha256) - legacy_info.size = os.path.getsize(jar_path) - legacy_info_list.number[key] = legacy_info - - # only write legacy info if it's missing - if not os.path.isfile(LEGACYINFO_PATH): - legacy_info_list.write(LEGACYINFO_PATH) + except Exception as e: + eprint("Failed to download %s" % version.url()) + eprint("Error is %s" % e) + continue + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + Path(version_file_path).parent.mkdir( + parents=True, exist_ok=True + ) + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + NeoForgeInstallerProfile.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + try: + NeoForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + Path(profile_path).parent.mkdir(parents=True, exist_ok=True) + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = filehash(jar_path, hashlib.sha1) + installer_info.sha256hash = filehash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) if __name__ == "__main__": -- cgit 0.0.5-2-1-g0f52 From 7675db816943df4014754716a807786ffa397b40 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Aug 2023 15:45:34 +0200 Subject: fix: remove unused code Signed-off-by: Sefa Eyeoglu --- generateNeoForge.py | 121 +++---------------------------------------------- meta/model/neoforge.py | 14 +----- updateNeoForge.py | 26 ++--------- 3 files changed, 12 insertions(+), 149 deletions(-) (limited to 'meta') diff --git a/generateNeoForge.py b/generateNeoForge.py index 2e556a6337..0e45e808bb 100644 --- a/generateNeoForge.py +++ b/generateNeoForge.py @@ -14,7 +14,6 @@ from meta.common.neoforge import ( INSTALLER_INFO_DIR, FORGEWRAPPER_MAVEN, ) -from meta.common.forge import FORGE_COMPONENT from meta.common.mojang import MINECRAFT_COMPONENT from meta.model import ( MetaVersion, @@ -27,7 +26,6 @@ from meta.model import ( ) from meta.model.neoforge import ( NeoForgeVersion, - NeoForgeInstallerProfile, NeoForgeInstallerProfileV2, InstallerInfo, DerivedNeoForgeIndex, @@ -45,105 +43,6 @@ def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) -# Construct a set of libraries out of a Minecraft version file, for filtering. -mc_version_cache = {} - - -def load_mc_version_filter(version: str): - if version in mc_version_cache: - return mc_version_cache[version] - v = MetaVersion.parse_file( - os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json") - ) - libs = set(map(attrgetter("name"), v.libraries)) - mc_version_cache[version] = libs - return libs - - -""" -Match a library coordinate to a set of library coordinates. - * Block those that pass completely. - * For others, block those with lower versions than in the set. -""" - - -def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpecifier): - for ver in libs: - if ( - ver.group == match.group - and ver.artifact == match.artifact - and ver.classifier == match.classifier - ): - if ver.version == match.version: - # Everything is matched perfectly - this one will be ignored - return True - elif LooseVersion(ver.version) > LooseVersion(match.version): - return True - else: - # Otherwise it did not match - new version is higher and this is an upgrade - return False - # No match found in the set - we need to keep this - return False - - -def version_from_profile( - profile: NeoForgeInstallerProfile, version: NeoForgeVersion -) -> MetaVersion: - v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) - mc_version = profile.install.minecraft - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] - v.main_class = profile.version_info.main_class - v.release_time = profile.version_info.time - - args = profile.version_info.minecraft_arguments - tweakers = [] - expression = re.compile(r"--tweakClass ([a-zA-Z0-9.]+)") - match = expression.search(args) - while match is not None: - tweakers.append(match.group(1)) - args = args[: match.start()] + args[match.end() :] - match = expression.search(args) - if len(tweakers) > 0: - args = args.strip() - v.additional_tweakers = tweakers - # v.minecraftArguments = args - - v.libraries = [] - mc_filter = load_mc_version_filter(mc_version) - for forge_lib in profile.version_info.libraries: - if ( - forge_lib.name.is_lwjgl() - or forge_lib.name.is_log4j() - or should_ignore_artifact(mc_filter, forge_lib.name) - ): - continue - - overridden_name = forge_lib.name - if overridden_name.group == "net.minecraftforge": - if overridden_name.artifact == "minecraftforge": - overridden_name.artifact = "forge" - overridden_name.version = "%s-%s" % ( - mc_version, - overridden_name.version, - ) - - overridden_name.classifier = "universal" - elif overridden_name.artifact == "forge": - overridden_name.classifier = "universal" - - overridden_lib = Library(name=overridden_name) - if forge_lib.url == "http://maven.minecraftforge.net/": - overridden_lib.url = "https://maven.minecraftforge.net/" - else: - overridden_lib.url = forge_lib.url - # if forge_lib.checksums and len(forge_lib.checksums) == 2: - # overridden_lib.mmcHint = "forge-pack-xz" - v.libraries.append(overridden_lib) - - v.order = 5 - return v - - def version_from_build_system_installer( installer: MojangVersion, profile: NeoForgeInstallerProfileV2, @@ -284,22 +183,14 @@ def main(): ) eprint(installer_version_filepath) - if os.path.isfile(installer_version_filepath): - installer = MojangVersion.parse_file(installer_version_filepath) - profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) - v = version_from_build_system_installer(installer, profile, version) - else: - if version.uses_installer(): - # If we do not have the Forge json, we ignore this version - if not os.path.isfile(profile_filepath): - eprint("Skipping %s with missing profile json" % key) - continue - profile = NeoForgeInstallerProfile.parse_file(profile_filepath) - v = version_from_profile(profile, version) + assert os.path.isfile( + installer_version_filepath + ), f"version {installer_version_filepath} does not have installer version manifest" + installer = MojangVersion.parse_file(installer_version_filepath) + profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) + v = version_from_build_system_installer(installer, profile, version) v.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, f"{v.version}.json")) - v.version = "NEO-" + v.version - v.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, f"{v.version}.json")) recommended_versions.sort() diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index 906b20bfca..a13605c282 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -132,12 +132,6 @@ class NeoForgeOptional(MetaBase): maven: Optional[str] -class NeoForgeInstallerProfile(MetaBase): - install: NeoForgeInstallerProfileInstallSection - version_info: NeoForgeVersionFile = Field(alias="versionInfo") - optionals: Optional[List[NeoForgeOptional]] - - class DataSpec(MetaBase): client: Optional[str] server: Optional[str] @@ -211,14 +205,10 @@ class NeoForgeVersion: self.changelog_url = url def name(self): - return "forge %d" % self.build + return "neoforge %d" % self.build def uses_installer(self): - if self.installer_url is None: - return False - if self.mc_version == "1.5.2": - return False - return True + return self.installer_url is not None def filename(self): if self.uses_installer(): diff --git a/updateNeoForge.py b/updateNeoForge.py index 57b5492606..431930c401 100644 --- a/updateNeoForge.py +++ b/updateNeoForge.py @@ -17,7 +17,7 @@ import urllib.parse from pydantic import ValidationError from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session -from meta.common.forge import ( +from meta.common.neoforge import ( JARS_DIR, INSTALLER_INFO_DIR, INSTALLER_MANIFEST_DIR, @@ -30,7 +30,6 @@ from meta.model.neoforge import ( NeoForgeMCVersionInfo, DerivedNeoForgeIndex, NeoForgeVersion, - NeoForgeInstallerProfile, NeoForgeInstallerProfileV2, InstallerInfo, ) @@ -98,19 +97,8 @@ def get_single_forge_files_manifest(longversion): classifier = file["name"][find_nth(name, "-", 3) + 1 : len(file_name)] # assert len(extensionObj.items()) == 1 - index = 0 - count = 0 file_obj = NeoForgeFile(classifier=classifier, extension=file_ext[1:]) - if count == 0: - ret_dict[classifier] = file_obj - index += 1 - count += 1 - else: - print( - "%s: Multiple objects detected for classifier %s:" - % (longversion, classifier) - ) - assert False + ret_dict[classifier] = file_obj if not from_file: Path(path_thing).parent.mkdir(parents=True, exist_ok=True) @@ -141,9 +129,7 @@ def main(): assert type(long_version) == str mc_version = long_version.split("-")[0] match = version_expression.match(long_version) - if not match: - pprint(long_version) - assert match + assert match, f"{long_version} doesn't match version regex" assert match.group("mc") == mc_version try: files = get_single_forge_files_manifest(long_version) @@ -153,6 +139,7 @@ def main(): version = match.group("ver") branch = match.group("branch") + # TODO: what *is* recommended? is_recommended = False entry = NeoForgeEntry( @@ -262,11 +249,6 @@ def main(): # Process: does it parse? is_parsable = False exception = None - try: - NeoForgeInstallerProfile.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err try: NeoForgeInstallerProfileV2.parse_raw(install_profile_data) is_parsable = True -- cgit 0.0.5-2-1-g0f52 From 4b38e79f8e69a21f69bac0af1209e129f64749d0 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 17 Aug 2023 16:26:12 +0200 Subject: refactor: define global forgewrapper library Signed-off-by: Sefa Eyeoglu --- generateForge.py | 13 ++----------- generateNeoForge.py | 13 ++----------- meta/common/__init__.py | 2 ++ meta/common/forge.py | 8 +++++++- meta/common/neoforge.py | 8 +++++++- meta/model/__init__.py | 8 ++++++++ 6 files changed, 28 insertions(+), 24 deletions(-) (limited to 'meta') diff --git a/generateForge.py b/generateForge.py index c233f948fc..067a392ad6 100755 --- a/generateForge.py +++ b/generateForge.py @@ -14,7 +14,7 @@ from meta.common.forge import ( STATIC_LEGACYINFO_FILE, INSTALLER_INFO_DIR, BAD_VERSIONS, - FORGEWRAPPER_MAVEN, + FORGEWRAPPER_LIBRARY, ) from meta.common.mojang import MINECRAFT_COMPONENT from meta.model import ( @@ -287,16 +287,7 @@ def version_from_build_system_installer( v.libraries = [] - wrapper_lib = Library( - name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2") - ) - wrapper_lib.downloads = MojangLibraryDownloads() - wrapper_lib.downloads.artifact = MojangArtifact( - url=FORGEWRAPPER_MAVEN % (wrapper_lib.name.path()), - sha1="4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", - size=34444, - ) - v.libraries.append(wrapper_lib) + v.libraries.append(FORGEWRAPPER_LIBRARY) for upstream_lib in installer.libraries: forge_lib = Library.parse_obj(upstream_lib.dict()) diff --git a/generateNeoForge.py b/generateNeoForge.py index 0e45e808bb..781fdce1fe 100644 --- a/generateNeoForge.py +++ b/generateNeoForge.py @@ -12,7 +12,7 @@ from meta.common.neoforge import ( VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, INSTALLER_INFO_DIR, - FORGEWRAPPER_MAVEN, + FORGEWRAPPER_LIBRARY, ) from meta.common.mojang import MINECRAFT_COMPONENT from meta.model import ( @@ -89,16 +89,7 @@ def version_from_build_system_installer( v.libraries = [] - wrapper_lib = Library( - name=GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6-prism") - ) - wrapper_lib.downloads = MojangLibraryDownloads() - wrapper_lib.downloads.artifact = MojangArtifact( - url=FORGEWRAPPER_MAVEN % (wrapper_lib.name.path()), - sha1="b059aa8c4d2508055c6ed2a2561923a5e670a5eb", - size=34860, - ) - v.libraries.append(wrapper_lib) + v.libraries.append(FORGEWRAPPER_LIBRARY) for upstream_lib in installer.libraries: forge_lib = Library.parse_obj(upstream_lib.dict()) diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 7a6514b2be..454a2cfeb8 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -6,6 +6,8 @@ import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache +LAUNCHER_MAVEN = "https://files.prismlauncher.org/maven/%s" + def serialize_datetime(dt: datetime.datetime): if dt.tzinfo is None: diff --git a/meta/common/forge.py b/meta/common/forge.py index be626599ff..d8828036bd 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -1,5 +1,7 @@ from os.path import join +from ..model import GradleSpecifier, make_launcher_library + BASE_DIR = "forge" JARS_DIR = join(BASE_DIR, "jars") @@ -13,5 +15,9 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" -FORGEWRAPPER_MAVEN = "https://files.prismlauncher.org/maven/%s" +FORGEWRAPPER_LIBRARY = make_launcher_library( + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2"), + "4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", + 34444, +) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] diff --git a/meta/common/neoforge.py b/meta/common/neoforge.py index 079933008a..3af76b9a21 100644 --- a/meta/common/neoforge.py +++ b/meta/common/neoforge.py @@ -1,5 +1,7 @@ from os.path import join +from ..model import GradleSpecifier, make_launcher_library + BASE_DIR = "neoforge" JARS_DIR = join(BASE_DIR, "jars") @@ -11,4 +13,8 @@ DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") NEOFORGE_COMPONENT = "net.neoforged" -FORGEWRAPPER_MAVEN = "https://files.prismlauncher.org/maven/%s" +FORGEWRAPPER_LIBRARY = make_launcher_library( + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6-prism"), + "b059aa8c4d2508055c6ed2a2561923a5e670a5eb", + 34860, +) diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 14b054e5d2..68cd034f1b 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -7,6 +7,7 @@ import pydantic from pydantic import Field, validator from ..common import ( + LAUNCHER_MAVEN, serialize_datetime, replace_old_launchermeta_url, get_all_bases, @@ -330,3 +331,10 @@ class MetaPackage(Versioned): authors: Optional[List[str]] description: Optional[str] project_url: Optional[str] = Field(alias="projectUrl") + + +def make_launcher_library( + name: GradleSpecifier, hash: str, size: int, maven=LAUNCHER_MAVEN +): + artifact = MojangArtifact(url=maven % name.path(), sha1=hash, size=size) + return Library(name=name, downloads=MojangLibraryDownloads(artifact=artifact)) -- cgit 0.0.5-2-1-g0f52 From ca4fb33fde501d4c52af123c7b2bf25b37bd645c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 17 Aug 2023 22:21:38 +0200 Subject: fix: use same ForgeWrapper for both Forge and NeoForge Signed-off-by: Sefa Eyeoglu --- generateNeoForge.py | 2 +- meta/common/forge.py | 6 +++--- meta/common/neoforge.py | 6 ------ 3 files changed, 4 insertions(+), 10 deletions(-) (limited to 'meta') diff --git a/generateNeoForge.py b/generateNeoForge.py index 0220ca739d..31df89a2cd 100644 --- a/generateNeoForge.py +++ b/generateNeoForge.py @@ -11,8 +11,8 @@ from meta.common.neoforge import ( VERSION_MANIFEST_DIR, DERIVED_INDEX_FILE, INSTALLER_INFO_DIR, - FORGEWRAPPER_LIBRARY, ) +from meta.common.forge import FORGEWRAPPER_LIBRARY from meta.common.mojang import MINECRAFT_COMPONENT from meta.model import ( MetaVersion, diff --git a/meta/common/forge.py b/meta/common/forge.py index d8828036bd..4a8afbe06f 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -16,8 +16,8 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "mmc2"), - "4ee5f25cc9c7efbf54aff4c695da1054c1a1d7a3", - 34444, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6-prism"), + "b059aa8c4d2508055c6ed2a2561923a5e670a5eb", + 34860, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] diff --git a/meta/common/neoforge.py b/meta/common/neoforge.py index 3af76b9a21..83f4890e97 100644 --- a/meta/common/neoforge.py +++ b/meta/common/neoforge.py @@ -12,9 +12,3 @@ FILE_MANIFEST_DIR = join(BASE_DIR, "files_manifests") DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") NEOFORGE_COMPONENT = "net.neoforged" - -FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6-prism"), - "b059aa8c4d2508055c6ed2a2561923a5e670a5eb", - 34860, -) -- cgit 0.0.5-2-1-g0f52 From 2b6c69544acc65f8b49af633fea85e0184406b9f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 19 Aug 2023 14:38:38 +0200 Subject: fix: disable Quilt beacon on older versions Signed-off-by: Sefa Eyeoglu --- generateQuilt.py | 8 ++++++++ meta/common/quilt.py | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'meta') diff --git a/generateQuilt.py b/generateQuilt.py index b8a881ad8c..ccf2797380 100755 --- a/generateQuilt.py +++ b/generateQuilt.py @@ -14,6 +14,8 @@ from meta.common.quilt import ( INTERMEDIARY_COMPONENT, LOADER_COMPONENT, USE_QUILT_MAPPINGS, + DISABLE_BEACON_ARG, + DISABLE_BEACON_VERSIONS, ) from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses @@ -62,6 +64,12 @@ def process_loader_version(entry) -> (MetaVersion, bool): url="https://maven.quiltmc.org/repository/release", ) v.libraries.append(loader_lib) + + if entry["version"] in DISABLE_BEACON_VERSIONS: + if not v.additional_jvm_args: + v.additional_jvm_args = [] + v.additional_jvm_args.append(DISABLE_BEACON_ARG) + return v, should_recommend diff --git a/meta/common/quilt.py b/meta/common/quilt.py index 6d5f47989e..b8203898b0 100644 --- a/meta/common/quilt.py +++ b/meta/common/quilt.py @@ -15,3 +15,30 @@ INTERMEDIARY_COMPONENT = "org.quiltmc.hashed" if not USE_QUILT_MAPPINGS: INTERMEDIARY_COMPONENT = FABRIC_INTERMEDIARY_COMPONENT + +DISABLE_BEACON_ARG = "-Dloader.disable_beacon=true" +DISABLE_BEACON_VERSIONS = { + "0.19.2-beta.3", + "0.19.2-beta.4", + "0.19.2-beta.5", + "0.19.2-beta.6", + "0.19.2-beta.7", + "0.19.2", + "0.19.3-beta.1", + "0.19.3", + "0.19.4", + "0.20.0-beta.1", + "0.20.0-beta.2", + "0.20.0-beta.3", + "0.20.0-beta.4", + "0.20.0-beta.5", + "0.20.0-beta.6", + "0.20.0-beta.7", + "0.20.0-beta.8", + "0.20.0-beta.9", + "0.20.0-beta.10", + "0.20.0-beta.11", + "0.20.0-beta.12", + "0.20.0-beta.13", + "0.20.0-beta.14", +} -- cgit 0.0.5-2-1-g0f52 From 6671c59e729b5fb099e5b0bb30e33321a958b70e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 15 Oct 2023 16:15:22 +0200 Subject: fix: consider version legacy if it has legacyLaunch Signed-off-by: Sefa Eyeoglu --- meta/model/mojang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 2e35634008..30aa88f4b2 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -134,7 +134,7 @@ class LegacyOverrideEntry(MetaBase): meta_version.additional_jvm_args = [] meta_version.additional_jvm_args += self.additional_jvm_args - if legacy: + if "legacyLaunch" in self.additional_traits: # remove all libraries - they are not needed for legacy meta_version.libraries = None # remove minecraft arguments - we use our own hardcoded ones -- cgit 0.0.5-2-1-g0f52 From 35eb9bf3786fa73ad3e65b73e3810a783f1545b8 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 15 Oct 2023 16:20:32 +0200 Subject: fix: only set main class if not unset Signed-off-by: Sefa Eyeoglu --- meta/model/mojang.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 30aa88f4b2..efd8656732 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -117,8 +117,10 @@ class LegacyOverrideEntry(MetaBase): def apply_onto_meta_version(self, meta_version: MetaVersion, legacy: bool = True): # simply hard override classes - meta_version.main_class = self.main_class - meta_version.applet_class = self.applet_class + if self.main_class: + meta_version.main_class = self.main_class + if self.applet_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 -- cgit 0.0.5-2-1-g0f52 From eb6c6bab00801f8fd70a806c0b818d460d5a0914 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 15 Oct 2023 16:25:20 +0200 Subject: Revert "fix: only set main class if not unset" This reverts commit 35eb9bf3786fa73ad3e65b73e3810a783f1545b8. --- meta/model/mojang.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index efd8656732..30aa88f4b2 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -117,10 +117,8 @@ class LegacyOverrideEntry(MetaBase): def apply_onto_meta_version(self, meta_version: MetaVersion, legacy: bool = True): # simply hard override classes - if self.main_class: - meta_version.main_class = self.main_class - if self.applet_class: - meta_version.applet_class = self.applet_class + 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 -- cgit 0.0.5-2-1-g0f52 From 8ac4ce963fa8f1fc2f2385a2b242e8f422b9dd23 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 15 Oct 2023 16:25:23 +0200 Subject: Revert "fix: consider version legacy if it has legacyLaunch" This reverts commit 6671c59e729b5fb099e5b0bb30e33321a958b70e. --- meta/model/mojang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 30aa88f4b2..2e35634008 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -134,7 +134,7 @@ class LegacyOverrideEntry(MetaBase): meta_version.additional_jvm_args = [] meta_version.additional_jvm_args += self.additional_jvm_args - if "legacyLaunch" in 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 -- cgit 0.0.5-2-1-g0f52 From 5c19d7a034d56c7e6011e3232c079c8613392141 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 15 Oct 2023 21:23:14 +0100 Subject: Add legacyServices to all applicable versions (take 2) --- generateMojang.py | 9 ++ meta/common/mojang.py | 1 + meta/model/mojang.py | 10 ++ static/mojang/minecraft-legacy-services.json | 217 +++++++++++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 static/mojang/minecraft-legacy-services.json (limited to 'meta') diff --git a/generateMojang.py b/generateMojang.py index 54365ed78d..237684a4fe 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -9,6 +9,7 @@ from typing import Optional, List from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path from meta.common.mojang import ( + STATIC_LEGACY_SERVICES_FILE, VERSION_MANIFEST_FILE, MINECRAFT_COMPONENT, LWJGL3_COMPONENT, @@ -28,6 +29,7 @@ from meta.model import ( MojangRules, ) from meta.model.mojang import ( + LegacyServices, MojangIndexWrap, MojangIndex, MojangVersion, @@ -311,6 +313,9 @@ def main(): override_index = LegacyOverrideIndex.parse_file( os.path.join(STATIC_DIR, STATIC_OVERRIDES_FILE) ) + legacy_services = LegacyServices.parse_file( + os.path.join(STATIC_DIR, STATIC_LEGACY_SERVICES_FILE) + ) library_patches = LibraryPatches.parse_file( os.path.join(STATIC_DIR, LIBRARY_PATCHES_FILE) ) @@ -486,6 +491,10 @@ def main(): if v.version in override_index.versions: override = override_index.versions[v.version] override.apply_onto_meta_version(v) + if v.version in legacy_services: + if v.additional_traits == None: + v.additional_traits = [] + v.additional_traits.append("legacyServices"); v.write(out_filename) for lwjglVersionVariant in lwjglVersionVariants: diff --git a/meta/common/mojang.py b/meta/common/mojang.py index dc80f44412..f484e8d6a4 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -9,6 +9,7 @@ ASSETS_DIR = join(BASE_DIR, "assets") STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") STATIC_OLD_SNAPSHOTS_FILE = join(BASE_DIR, "minecraft-old-snapshots.json") STATIC_OVERRIDES_FILE = join(BASE_DIR, "minecraft-legacy-override.json") +STATIC_LEGACY_SERVICES_FILE = join(BASE_DIR, "minecraft-legacy-services.json") LIBRARY_PATCHES_FILE = join(BASE_DIR, "library-patches.json") MINECRAFT_COMPONENT = "net.minecraft" diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 2e35634008..04e9b608ed 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -165,6 +165,16 @@ class LibraryPatches(MetaBase): return self.__root__[item] +class LegacyServices(MetaBase): + __root__: List[str] + + def __iter__(self) -> Iterator[str]: + return iter(self.__root__) + + def __getitem__(self, item) -> str: + return self.__root__[item] + + class MojangArguments(MetaBase): game: Optional[List[Any]] # mixture of strings and objects jvm: Optional[List[Any]] diff --git a/static/mojang/minecraft-legacy-services.json b/static/mojang/minecraft-legacy-services.json new file mode 100644 index 0000000000..994277b127 --- /dev/null +++ b/static/mojang/minecraft-legacy-services.json @@ -0,0 +1,217 @@ +[ + "c0.30_01c", + "inf-20100618", + "a1.0.4", + "a1.0.5_01", + "a1.0.11", + "a1.0.14", + "a1.0.15", + "a1.0.16", + "a1.0.17_02", + "a1.0.17_04", + "a1.1.0", + "a1.1.2", + "a1.1.2_01", + "a1.2.0", + "a1.2.0_01", + "a1.2.0_02", + "a1.2.1", + "a1.2.1_01", + "a1.2.2a", + "a1.2.2b", + "a1.2.3", + "a1.2.3_01", + "a1.2.3_02", + "a1.2.3_04", + "a1.2.4_01", + "a1.2.5", + "a1.2.6", + "b1.0", + "b1.0_01", + "b1.0.2", + "b1.1_01", + "b1.1_02", + "b1.2", + "b1.2_01", + "b1.2_02", + "b1.3b", + "b1.3_01", + "b1.4", + "b1.4_01", + "b1.5", + "b1.5_01", + "b1.6", + "b1.6.1", + "b1.6.2", + "b1.6.3", + "b1.6.4", + "b1.6.5", + "b1.6.6", + "b1.7", + "b1.7.2", + "b1.7.3", + "b1.8-pre1-2", + "b1.8-pre2", + "b1.8", + "b1.8.1", + "b1.9-pre1", + "b1.9-pre2", + "b1.9-pre3", + "b1.9-pre4", + "b1.9-pre5", + "b1.9-pre6", + "1.0", + "11w47a", + "11w48a", + "11w49a", + "11w50a", + "12w01a", + "1.1", + "12w03a", + "12w04a", + "12w05a", + "12w05b", + "12w06a", + "12w07b", + "12w07a", + "12w08a", + "1.2", + "1.2.1", + "1.2.2", + "1.2.3", + "1.2.4", + "1.2.5", + "12w16a", + "12w17a", + "12w18a", + "12w19a", + "12w21a", + "12w21b", + "12w22a", + "12w23a", + "12w23b", + "12w24a", + "12w25a", + "12w26a", + "12w27a", + "12w30a", + "12w30b", + "12w30c", + "12w30d", + "12w30e", + "1.3", + "1.3.1", + "12w32a", + "1.3.2", + "12w34a", + "12w34b", + "12w36a", + "12w37a", + "12w38a", + "12w38b", + "12w39a", + "12w39b", + "12w40a", + "12w40b", + "12w41a", + "12w41b", + "12w42a", + "12w42b", + "1.4", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "12w49a", + "12w50a", + "12w50b", + "1.4.6", + "1.4.7", + "13w01a", + "13w01b", + "13w02a", + "13w02b", + "13w03a", + "13w04a", + "13w05a", + "13w05b", + "13w06a", + "13w07a", + "13w11a", + "13w09a", + "13w09b", + "13w09c", + "13w10a", + "13w10b", + "1.5", + "13w12~", + "1.5.1", + "1.5.2", + "13w17a", + "13w18a", + "13w18b", + "13w18c", + "13w19a", + "13w21a", + "13w21b", + "13w22a", + "13w23a", + "13w23b", + "13w24a", + "13w24b", + "13w25a", + "13w25b", + "13w25c", + "13w26a", + "1.6", + "1.6.1", + "1.6.2", + "13w36a", + "13w36b", + "13w37a", + "1.6.3", + "13w37b", + "1.6.4", + "13w38a", + "13w38b", + "13w38c", + "13w39a", + "13w39b", + "13w41a", + "13w41b", + "13w42a", + "13w42b", + "13w43a", + "1.7", + "1.7.1", + "1.7.2", + "13w47a", + "13w47b", + "13w47c", + "13w47d", + "13w47e", + "13w48a", + "13w48b", + "13w49a", + "1.7.3", + "14w02a", + "14w02b", + "14w02c", + "14w03a", + "14w03b", + "14w04a", + "14w04b", + "14w05a", + "14w05b", + "14w06a", + "14w06b", + "14w07a", + "1.7.5", + "14w08a", + "14w10b", + "14w10c", + "1.7.6-pre1", + "1.7.6-pre2", + "14w11a" +] -- cgit 0.0.5-2-1-g0f52 From 0baa8da3759667eb1247c6dbee33c213b1b75619 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 1 Nov 2023 10:43:35 +0100 Subject: feat: support NeoForge 1.20.2+ Signed-off-by: Sefa Eyeoglu --- meta/model/neoforge.py | 19 +++++++++++---- updateNeoForge.py | 64 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 18 deletions(-) (limited to 'meta') diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index a13605c282..4a110cf300 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -8,20 +8,28 @@ from .mojang import MojangVersion class NeoForgeFile(MetaBase): + artifact: str classifier: str extension: str def filename(self, long_version): - return "%s-%s-%s.%s" % ("forge", long_version, self.classifier, self.extension) + return "%s-%s-%s.%s" % ( + self.artifact, + long_version, + self.classifier, + self.extension, + ) def url(self, long_version): - return "https://maven.neoforged.net/net/neoforged/forge/%s/%s" % ( + return "https://maven.neoforged.net/net/neoforged/%s/%s/%s" % ( + self.artifact, long_version, self.filename(long_version), ) class NeoForgeEntry(MetaBase): + artifact: str long_version: str = Field(alias="longversion") mc_version: str = Field(alias="mcversion") version: str @@ -174,6 +182,9 @@ class NeoForgeVersion: def __init__(self, entry: NeoForgeEntry): self.build = entry.build self.rawVersion = entry.version + if entry.artifact == "neoforge": + self.rawVersion = entry.long_version + self.mc_version = entry.mc_version self.mc_version_sane = self.mc_version.replace("_pre", "-pre", 1) self.branch = entry.branch @@ -182,9 +193,7 @@ class NeoForgeVersion: self.universal_filename = None self.universal_url = None self.changelog_url = None - self.long_version = "%s-%s" % (self.mc_version, self.rawVersion) - if self.branch is not None: - self.long_version += "-%s" % self.branch + self.long_version = entry.long_version # this comment's whole purpose is to say this: cringe for classifier, file in entry.files.items(): diff --git a/updateNeoForge.py b/updateNeoForge.py index 431930c401..2ff8be5d9d 100644 --- a/updateNeoForge.py +++ b/updateNeoForge.py @@ -67,7 +67,7 @@ def find_nth(haystack, needle, n): return start -def get_single_forge_files_manifest(longversion): +def get_single_forge_files_manifest(longversion, artifact: str): print(f"Getting NeoForge manifest for {longversion}") path_thing = UPSTREAM_DIR + "/neoforge/files_manifests/%s.json" % longversion files_manifest_file = Path(path_thing) @@ -78,7 +78,7 @@ def get_single_forge_files_manifest(longversion): from_file = True else: file_url = ( - "https://maven.neoforged.net/api/maven/details/releases/net%2Fneoforged%2Fforge%2F" + f"https://maven.neoforged.net/api/maven/details/releases/net%2Fneoforged%2F{artifact}%2F" + urllib.parse.quote(longversion) ) r = sess.get(file_url) @@ -90,14 +90,26 @@ def get_single_forge_files_manifest(longversion): for file in files_json.get("files"): assert type(file) == dict name = file["name"] - file_name, file_ext = os.path.splitext(name) - if file_ext in [".md5", ".sha1", ".sha256", ".sha512"]: + prefix = f"{artifact}-{longversion}" + assert name.startswith( + prefix + ), f"{longversion} classifier {name} doesn't start with {prefix}" + file_name = name[len(prefix) :] + if file_name.startswith("-"): + file_name = file_name[1:] + if file_name.startswith("."): continue - classifier = file["name"][find_nth(name, "-", 3) + 1 : len(file_name)] + print(f"AAAA {file_name}") + classifier, ext = os.path.splitext(file_name) + + if ext in [".md5", ".sha1", ".sha256", ".sha512"]: + continue # assert len(extensionObj.items()) == 1 - file_obj = NeoForgeFile(classifier=classifier, extension=file_ext[1:]) + file_obj = NeoForgeFile( + artifact=artifact, classifier=classifier, extension=ext[1:] + ) ret_dict[classifier] = file_obj if not from_file: @@ -117,32 +129,58 @@ def main(): main_json = r.json()["versions"] assert type(main_json) == list + # get the new remote version list fragments + r = sess.get( + "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fneoforge" + ) + r.raise_for_status() + new_main_json = r.json()["versions"] + assert type(new_main_json) == list + + main_json += new_main_json + new_index = DerivedNeoForgeIndex() version_expression = re.compile( - "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$" + r"^(?P[0-9a-zA-Z_\.]+)-(?P[0-9\.]+\.(?P[0-9]+))(-(?P[a-zA-Z0-9\.]+))?$" + ) + neoforge_version_re = re.compile( + r"^(?P\d+).(?P\d+).(?P\d+)(?:-(?P\w+))?$" ) print("") print("Processing versions:") for long_version in main_json: assert type(long_version) == str - mc_version = long_version.split("-")[0] + match = version_expression.match(long_version) + if match: + mc_version = match.group("mc") + build = int(match.group("build")) + version = match.group("ver") + branch = match.group("branch") + artifact = "forge" + + match_nf = neoforge_version_re.match(long_version) + if match_nf: + mc_version = f"1.{match_nf.group('mcminor')}.{match_nf.group('mcpatch')}" + build = int(match_nf.group("number")) + version = match_nf.group("number") + branch = match_nf.group("tag") + match = match_nf + artifact = "neoforge" + assert match, f"{long_version} doesn't match version regex" - assert match.group("mc") == mc_version try: - files = get_single_forge_files_manifest(long_version) + files = get_single_forge_files_manifest(long_version, artifact) except: continue - build = int(match.group("build")) - version = match.group("ver") - branch = match.group("branch") # TODO: what *is* recommended? is_recommended = False entry = NeoForgeEntry( + artifact=artifact, long_version=long_version, mc_version=mc_version, version=version, -- cgit 0.0.5-2-1-g0f52 From 8e47317406d9a104743f7764d2a47b07543ab49f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 1 Nov 2023 11:03:31 +0100 Subject: fix: use new neoforge artifact in library names Signed-off-by: Sefa Eyeoglu --- generateNeoForge.py | 9 ++++++--- meta/model/neoforge.py | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'meta') diff --git a/generateNeoForge.py b/generateNeoForge.py index 31df89a2cd..d2f6ceb668 100644 --- a/generateNeoForge.py +++ b/generateNeoForge.py @@ -60,7 +60,7 @@ def version_from_build_system_installer( ) installer_lib = Library( name=GradleSpecifier( - "net.neoforged", "forge", version.long_version, "installer" + "net.neoforged", version.artifact, version.long_version, "installer" ) ) installer_lib.downloads = MojangLibraryDownloads() @@ -78,9 +78,12 @@ def version_from_build_system_installer( if ( forge_lib.name.group == "net.neoforged" - and forge_lib.name.artifact == "forge" + and forge_lib.name.artifact == version.artifact and forge_lib.name.classifier == "universal" ): + # WORKAROUND: Early NeoForge 20.2 versions have an invalid version for universal jars. Instead of 1.20.2-20.2.20-beta it should just be 20.2.20-beta + if version.artifact == "neoforge": + forge_lib.name.version = version.long_version forge_lib.downloads.artifact.url = ( "https://maven.neoforged.net/%s" % forge_lib.name.path() ) @@ -96,7 +99,7 @@ def version_from_build_system_installer( continue if forge_lib.name.group == "net.neoforged": - if forge_lib.name.artifact == "forge": + if forge_lib.name.artifact == version.artifact: forge_lib.name.classifier = "launcher" forge_lib.downloads.artifact.path = forge_lib.name.path() forge_lib.downloads.artifact.url = ( diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index 4a110cf300..853e433068 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -180,9 +180,10 @@ class InstallerInfo(MetaBase): # A post-processed entry constructed from the reconstructed NeoForge version index class NeoForgeVersion: def __init__(self, entry: NeoForgeEntry): + self.artifact = entry.artifact self.build = entry.build self.rawVersion = entry.version - if entry.artifact == "neoforge": + if self.artifact == "neoforge": self.rawVersion = entry.long_version self.mc_version = entry.mc_version -- cgit 0.0.5-2-1-g0f52 From 86cad8b5d8991f38309663054b4b6b5964f78bdb Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 1 Nov 2023 12:07:40 +0100 Subject: chore: bump ForgeWrapper Signed-off-by: Sefa Eyeoglu --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 4a8afbe06f..7c735a2a83 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -16,8 +16,8 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.6-prism"), - "b059aa8c4d2508055c6ed2a2561923a5e670a5eb", - 34860, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.7-prism"), + "29139276224c3b8eac414607ade28b90ba9113ba", + 35062, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From eb47993bf859d0c2b5f3cf119a022c178c24ef30 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 4 Nov 2023 22:39:42 +0100 Subject: refactor: merge MojangLibrary and Library Signed-off-by: Sefa Eyeoglu --- generateForge.py | 11 +++-------- generateNeoForge.py | 28 ++-------------------------- meta/model/__init__.py | 5 +---- meta/model/forge.py | 8 ++++---- meta/model/mojang.py | 3 +-- meta/model/neoforge.py | 8 ++++---- 6 files changed, 15 insertions(+), 48 deletions(-) (limited to 'meta') diff --git a/generateForge.py b/generateForge.py index bb44845569..6bc5edd7a8 100755 --- a/generateForge.py +++ b/generateForge.py @@ -173,10 +173,7 @@ def version_from_modernized_installer( v.libraries = [] mc_filter = load_mc_version_filter(mc_version) - for upstream_lib in installer.libraries: - forge_lib = Library.parse_obj( - upstream_lib.dict() - ) # "cast" MojangLibrary to Library + for forge_lib in installer.libraries: if ( forge_lib.name.is_lwjgl() or forge_lib.name.is_log4j() @@ -270,8 +267,7 @@ def version_from_build_system_installer( ) v.maven_files.append(installer_lib) - for upstream_lib in profile.libraries: - forge_lib = Library.parse_obj(upstream_lib.dict()) + for forge_lib in profile.libraries: if forge_lib.name.is_log4j(): continue @@ -289,8 +285,7 @@ def version_from_build_system_installer( v.libraries.append(FORGEWRAPPER_LIBRARY) - for upstream_lib in installer.libraries: - forge_lib = Library.parse_obj(upstream_lib.dict()) + for forge_lib in installer.libraries: if forge_lib.name.is_log4j(): continue diff --git a/generateNeoForge.py b/generateNeoForge.py index 09a9044140..ab0f1df585 100644 --- a/generateNeoForge.py +++ b/generateNeoForge.py @@ -72,44 +72,20 @@ def version_from_build_system_installer( ) v.maven_files.append(installer_lib) - for upstream_lib in profile.libraries: - forge_lib = Library.parse_obj(upstream_lib.dict()) + for forge_lib in profile.libraries: if forge_lib.name.is_log4j(): continue - if ( - forge_lib.name.group == "net.neoforged" - and forge_lib.name.artifact == version.artifact - and forge_lib.name.classifier == "universal" - ): - # WORKAROUND: Early NeoForge 20.2 versions have an invalid version for universal jars. Instead of 1.20.2-20.2.20-beta it should just be 20.2.20-beta - # See https://github.com/neoforged/NeoGradle/issues/23 - download_name = forge_lib.name - if version.artifact == "neoforge": - download_name = deepcopy(forge_lib.name) - download_name.version = version.long_version - forge_lib.downloads.artifact.url = ( - "https://maven.neoforged.net/%s" % download_name.path() - ) v.maven_files.append(forge_lib) v.libraries = [] v.libraries.append(FORGEWRAPPER_LIBRARY) - for upstream_lib in installer.libraries: - forge_lib = Library.parse_obj(upstream_lib.dict()) + for forge_lib in installer.libraries: if forge_lib.name.is_log4j(): continue - if forge_lib.name.group == "net.neoforged": - if forge_lib.name.artifact == version.artifact: - forge_lib.name.classifier = "launcher" - forge_lib.downloads.artifact.path = forge_lib.name.path() - forge_lib.downloads.artifact.url = ( - "https://maven.neoforged.net/%s" % forge_lib.name.path() - ) - forge_lib.name = forge_lib.name v.libraries.append(forge_lib) v.release_time = installer.release_time diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 68cd034f1b..fb062f5d35 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -281,15 +281,12 @@ class MojangRules(MetaBase): return self.__root__[item] -class MojangLibrary(MetaBase): +class Library(MetaBase): extract: Optional[MojangLibraryExtractRules] name: Optional[GradleSpecifier] downloads: Optional[MojangLibraryDownloads] natives: Optional[Dict[str, str]] rules: Optional[MojangRules] - - -class Library(MojangLibrary): url: Optional[str] mmcHint: Optional[str] = Field(None, alias="MMC-hint") diff --git a/meta/model/forge.py b/meta/model/forge.py index 937cc18cb5..a59b87aa5c 100644 --- a/meta/model/forge.py +++ b/meta/model/forge.py @@ -3,7 +3,7 @@ from typing import Optional, List, Dict from pydantic import Field -from . import MetaBase, GradleSpecifier, MojangLibrary +from . import MetaBase, GradleSpecifier, Library from .mojang import MojangVersion @@ -46,7 +46,7 @@ class DerivedForgeIndex(MetaBase): class FMLLib( MetaBase -): # old ugly stuff. Maybe merge this with Library or MojangLibrary later +): # old ugly stuff. Maybe merge this with Library or Library later filename: str checksum: str ours: bool @@ -91,7 +91,7 @@ class ForgeInstallerProfileInstallSection(MetaBase): mod_list: Optional[str] = Field(alias="modList") -class ForgeLibrary(MojangLibrary): +class ForgeLibrary(Library): url: Optional[str] server_req: Optional[bool] = Field(alias="serverreq") client_req: Optional[bool] = Field(alias="clientreq") @@ -176,7 +176,7 @@ class ForgeInstallerProfileV2(MetaBase): welcome: Optional[str] data: Optional[Dict[str, DataSpec]] processors: Optional[List[ProcessorSpec]] - libraries: Optional[List[MojangLibrary]] + libraries: Optional[List[Library]] mirror_list: Optional[str] = Field(alias="mirrorList") server_jar_path: Optional[str] = Field(alias="serverJarPath") diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 04e9b608ed..25d71ae2bf 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -7,7 +7,6 @@ from . import ( MetaBase, MojangArtifactBase, MojangAssets, - MojangLibrary, MojangArtifact, MojangLibraryDownloads, Library, @@ -216,7 +215,7 @@ class MojangVersion(MetaBase): asset_index: Optional[MojangAssets] = Field(alias="assetIndex") assets: Optional[str] downloads: Optional[Dict[str, MojangArtifactBase]] # TODO improve this? - libraries: Optional[List[MojangLibrary]] # TODO: optional? + libraries: Optional[List[Library]] # TODO: optional? main_class: Optional[str] = Field(alias="mainClass") applet_class: Optional[str] = Field(alias="appletClass") processArguments: Optional[str] diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index 853e433068..5f5237fa5f 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -3,7 +3,7 @@ from typing import Optional, List, Dict from pydantic import Field -from . import MetaBase, GradleSpecifier, MojangLibrary +from . import MetaBase, GradleSpecifier, Library from .mojang import MojangVersion @@ -53,7 +53,7 @@ class DerivedNeoForgeIndex(MetaBase): class FMLLib( MetaBase -): # old ugly stuff. Maybe merge this with Library or MojangLibrary later +): # old ugly stuff. Maybe merge this with Library or Library later filename: str checksum: str ours: bool @@ -98,7 +98,7 @@ class NeoForgeInstallerProfileInstallSection(MetaBase): mod_list: Optional[str] = Field(alias="modList") -class NeoForgeLibrary(MojangLibrary): +class NeoForgeLibrary(Library): url: Optional[str] server_req: Optional[bool] = Field(alias="serverreq") client_req: Optional[bool] = Field(alias="clientreq") @@ -166,7 +166,7 @@ class NeoForgeInstallerProfileV2(MetaBase): welcome: Optional[str] data: Optional[Dict[str, DataSpec]] processors: Optional[List[ProcessorSpec]] - libraries: Optional[List[MojangLibrary]] + libraries: Optional[List[Library]] mirror_list: Optional[str] = Field(alias="mirrorList") server_jar_path: Optional[str] = Field(alias="serverJarPath") -- cgit 0.0.5-2-1-g0f52 From 735421d1554d995cf95f0361a81158c5110b50a8 Mon Sep 17 00:00:00 2001 From: tildejustin Date: Sun, 10 Dec 2023 12:08:41 -0500 Subject: do not remove legacy arguments --- meta/model/mojang.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 25d71ae2bf..d54b7f9851 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -136,8 +136,6 @@ class LegacyOverrideEntry(MetaBase): 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): -- cgit 0.0.5-2-1-g0f52 From 1f0d004561bb129329516a26b7a111385050d797 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 28 Dec 2023 22:08:50 +0100 Subject: fix: use new ForgeWrapper to fix Forge 49 Closes https://github.com/PrismLauncher/PrismLauncher/issues/1934 Signed-off-by: Sefa Eyeoglu --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 7c735a2a83..5ce6442ec9 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -16,8 +16,8 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.7-prism"), - "29139276224c3b8eac414607ade28b90ba9113ba", - 35062, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.8-prism"), + "acd024c0448ec2c577a3f41aaa471acf6d9cda9b", + 36229, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 6def1eece6c5399335f3189844f3bb1420664d98 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 16 Jan 2024 17:13:57 +0200 Subject: Added new java enum Signed-off-by: Trial97 --- meta/model/mojang.py | 1 + update.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index efab4a559a..48a5e5a1dc 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -198,6 +198,7 @@ class MojangJavaComponent(StrEnum): Alpha = "java-runtime-alpha" Beta = "java-runtime-beta" Gamma = "java-runtime-gamma" + GammaSnapshot = "java-runtime-gamma-snapshot" Exe = "minecraft-java-exe" diff --git a/update.sh b/update.sh index 001a25ddd2..777a8f016c 100755 --- a/update.sh +++ b/update.sh @@ -72,7 +72,7 @@ python generateNeoForge.py || fail_out python generateFabric.py || fail_out python generateQuilt.py || fail_out python generateLiteloader.py || fail_out -python generageJava.py || fail_out +python generateJava.py || fail_out python index.py || fail_out if [ "${DEPLOY_TO_GIT}" = true ] ; then -- cgit 0.0.5-2-1-g0f52 From abc32095d8fd61ab71c23c4710d41e5755fd9f5a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 25 Jan 2024 18:50:17 +0200 Subject: Changed mojang java names to match meta Signed-off-by: Trial97 --- generateJava.py | 155 +++++++++++++++++++++++++------------------------ meta/model/__init__.py | 15 ++--- meta/model/mojang.py | 6 ++ 3 files changed, 92 insertions(+), 84 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index 2b3f21810c..6a0bfc1061 100644 --- a/generateJava.py +++ b/generateJava.py @@ -124,13 +124,13 @@ def mojang_os_to_java_os(mojang_os: MojangJavaOsName) -> JavaRuntimeOS: def mojang_runtime_to_java_runtime( mojang_runtime: MojangJavaRuntime, + mojang_component: MojangJavaComponent, ) -> JavaRuntimeMeta: major, _, security = mojang_runtime.version.name.partition("u") if major and security: version_parts = [int(major), 0, int(security)] else: - version_parts = [int(part) - for part in mojang_runtime.version.name.split(".")] + version_parts = [int(part) for part in mojang_runtime.version.name.split(".")] while len(version_parts) < 3: version_parts.append(0) @@ -147,7 +147,7 @@ def mojang_runtime_to_java_runtime( name=mojang_runtime.version.name, ) return JavaRuntimeMeta( - name=f"mojang_jre_{mojang_runtime.version.name}", + name=mojang_component, vendor="mojang", url=mojang_runtime.manifest.url, releaseTime=mojang_runtime.version.released, @@ -177,7 +177,9 @@ def adoptium_release_binary_to_java_runtime( version = JavaVersionMeta( major=rls.version_data.major if rls.version_data.major is not None else 0, minor=rls.version_data.minor if rls.version_data.minor is not None else 0, - security=rls.version_data.security if rls.version_data.security is not None else 0, + security=rls.version_data.security + if rls.version_data.security is not None + else 0, build=rls.version_data.build, ) rls_name = f"{rls.vendor}_temurin_{binary.image_type}{version}" @@ -217,9 +219,7 @@ def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: checksum = None if pkg.sha256_hash is not None: - checksum = JavaChecksumMeta( - type=JavaChecksumType.Sha256, hash=pkg.sha256_hash - ) + checksum = JavaChecksumMeta(type=JavaChecksumType.Sha256, hash=pkg.sha256_hash) return JavaRuntimeMeta( name=rls_name, @@ -262,7 +262,9 @@ def pkg_type_priority(pkg_type: JavaPackageType) -> int: return -1 -def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]) -> Optional[JavaRuntimeMeta]: +def ensure_one_recommended( + runtimes: list[JavaRuntimeMeta], +) -> Optional[JavaRuntimeMeta]: if len(runtimes) < 1: return None # can't do anything @@ -287,7 +289,9 @@ def ensure_one_recommended(runtimes: list[JavaRuntimeMeta]) -> Optional[JavaRunt assert recommended is not None if vendor_priority(runtime.vendor) < vendor_priority(recommended.vendor): return False - if pkg_type_priority(runtime.package_type) < pkg_type_priority(recommended.package_type): + if pkg_type_priority(runtime.package_type) < pkg_type_priority( + recommended.package_type + ): return False if runtime.version < recommended.version: return False @@ -313,8 +317,7 @@ def main(): def add_java_runtime(runtime: JavaRuntimeMeta, major: int, java_os: JavaRuntimeOS): ensure_javamap(major) - print( - f"Regestering runtime: {runtime.name} for Java {major} {java_os}") + print(f"Regestering runtime: {runtime.name} for Java {major} {java_os}") javas[major][java_os].append(runtime) print("Processing Mojang Javas") @@ -334,68 +337,67 @@ def main(): major = 8 else: major = int(mojang_runtime.version.name.partition(".")[0]) - runtime = mojang_runtime_to_java_runtime(mojang_runtime) + runtime = mojang_runtime_to_java_runtime(mojang_runtime, comp) add_java_runtime(runtime, major, java_os) print("Processing Adoptium Releases") - adoptium_available_releases = AdoptiumAvailableReleases.parse_file( - os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") - ) - for major in adoptium_available_releases.available_releases: - adoptium_releases = AdoptiumReleases.parse_file( - os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, - f"java{major}.json") + adoptium_path = os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") + if os.path.exists(adoptium_path): + adoptium_available_releases = AdoptiumAvailableReleases.parse_file( + adoptium_path ) - for _, rls in adoptium_releases: - for binary in rls.binaries: - if binary.package is None: - continue - binary_arch = translate_arch(str(binary.architecture)) - binary_os = translate_os(str(binary.os)) - if binary_arch is None or binary_os is None: - print( - f"Ignoring release for {binary.os} {binary.architecture}") - continue - - java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") - runtime = adoptium_release_binary_to_java_runtime(rls, binary) - add_java_runtime(runtime, major, java_os) + for major in adoptium_available_releases.available_releases: + adoptium_releases = AdoptiumReleases.parse_file( + os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{major}.json") + ) + for _, rls in adoptium_releases: + for binary in rls.binaries: + if binary.package is None: + continue + binary_arch = translate_arch(str(binary.architecture)) + binary_os = translate_os(str(binary.os)) + if binary_arch is None or binary_os is None: + print(f"Ignoring release for {binary.os} {binary.architecture}") + continue + + java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") + runtime = adoptium_release_binary_to_java_runtime(rls, binary) + add_java_runtime(runtime, major, java_os) print("Processing Azul Packages") - azul_packages = ZuluPackageList.parse_file( - os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") - ) - for _, pkg in azul_packages: - pkg_detail = ZuluPackageDetail.parse_file( - os.path.join(UPSTREAM_DIR, AZUL_VERSIONS_DIR, - f"{pkg.package_uuid}.json") - ) - major = pkg_detail.java_version[0] - if major < 8: - continue # we will never need java versions less than 8 - - pkg_os = translate_os(str(pkg_detail.os)) - if pkg_detail.arch == AzulArch.Arm: - pkg_arch = translate_arch( - f"{pkg_detail.arch}{pkg_detail.hw_bitness}") - elif pkg_detail.arch == AzulArch.X86: - pkg_arch = translate_arch(int(pkg_detail.hw_bitness)) - else: - pkg_arch = None - if pkg_arch is None or pkg_os is None: - print( - f"Ignoring release for {pkg_detail.os} {pkg_detail.arch}_{pkg_detail.hw_bitness}" + azul_path = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") + if os.path.exists(azul_path): + azul_packages = ZuluPackageList.parse_file(azul_path) + for _, pkg in azul_packages: + pkg_detail = ZuluPackageDetail.parse_file( + os.path.join( + UPSTREAM_DIR, AZUL_VERSIONS_DIR, f"{pkg.package_uuid}.json" + ) ) - continue + major = pkg_detail.java_version[0] + if major < 8: + continue # we will never need java versions less than 8 + + pkg_os = translate_os(str(pkg_detail.os)) + if pkg_detail.arch == AzulArch.Arm: + pkg_arch = translate_arch(f"{pkg_detail.arch}{pkg_detail.hw_bitness}") + elif pkg_detail.arch == AzulArch.X86: + pkg_arch = translate_arch(int(pkg_detail.hw_bitness)) + else: + pkg_arch = None + if pkg_arch is None or pkg_os is None: + print( + f"Ignoring release for {pkg_detail.os} {pkg_detail.arch}_{pkg_detail.hw_bitness}" + ) + continue - java_os = JavaRuntimeOS(f"{pkg_os}-{pkg_arch}") - runtime = azul_package_to_java_runtime(pkg_detail) - add_java_runtime(runtime, major, java_os) + java_os = JavaRuntimeOS(f"{pkg_os}-{pkg_arch}") + runtime = azul_package_to_java_runtime(pkg_detail) + add_java_runtime(runtime, major, java_os) for major, runtimes in javas.items(): for java_os, runtime_list in runtimes: - print(f"Total runtimes for Java {major} {java_os}:", len( - runtime_list)) + print(f"Total runtimes for Java {major} {java_os}:", len(runtime_list)) rec = ensure_one_recommended(runtime_list) if rec is not None: print(f"Recomending {rec.name} for Java {major} {java_os}") @@ -405,27 +407,26 @@ def main(): return b return a - version_file = os.path.join( - LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") + version_file = os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") java_version = JavaRuntimeVersion( - name = f"Java {major}", - uid = JAVA_COMPONENT, - version = f"java{major}", + name=f"Java {major}", + uid=JAVA_COMPONENT, + version=f"java{major}", releaseTime=reduce( - newest_timestamp, - (runtime.release_time - for _, runtime_list in runtimes - for runtime in runtime_list - ), - None + newest_timestamp, + ( + runtime.release_time + for _, runtime_list in runtimes + for runtime in runtime_list ), - runtimes = runtimes) + None, + ), + runtimes=runtimes, + ) java_version.write(version_file) package = MetaPackage( - uid = JAVA_COMPONENT, - name = "Java Runtimes", - recommended = ["java8", "java17"] + uid=JAVA_COMPONENT, name="Java Runtimes", recommended=["java8", "java17"] ) package.write(os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, "package.json")) diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 733f78d6a4..3d06f998ab 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -93,10 +93,10 @@ class GradleSpecifier: else: return False - def __lt__(self, other: 'GradleSpecifier'): + def __lt__(self, other: "GradleSpecifier"): return str(self) < str(other) - def __gt__(self, other: 'GradleSpecifier'): + def __gt__(self, other: "GradleSpecifier"): return str(self) > str(other) def __hash__(self): @@ -125,7 +125,7 @@ class GradleSpecifier: return cls(group, artifact, version, classifier, extension) @classmethod - def validate(cls, v: 'str | GradleSpecifier'): + def validate(cls, v: "str | GradleSpecifier"): if isinstance(v, cls): return v if isinstance(v, str): @@ -155,7 +155,7 @@ class MetaBase(pydantic.BaseModel): with open(file_path, "w") as f: f.write(self.json()) - def merge(self, other: 'MetaBase'): + def merge(self, other: "MetaBase"): """ Merge other object with self. - Concatenates lists @@ -179,14 +179,14 @@ class MetaBase(pydantic.BaseModel): elif isinstance(ours, set): ours |= theirs elif isinstance(ours, dict): - result = merge_dict(ours, copy.deepcopy(theirs)) # type: ignore + result = merge_dict(ours, copy.deepcopy(theirs)) # type: ignore setattr(self, key, result) elif MetaBase in get_all_bases(field.type_): ours.merge(theirs) else: setattr(self, key, theirs) - def __hash__(self): #type: ignore + def __hash__(self): # type: ignore return hash(self.json()) class Config: @@ -277,7 +277,7 @@ class MojangRule(MetaBase): class MojangRules(MetaBase): __root__: List[MojangRule] - def __iter__(self) -> Iterator[MojangRule]: #type: ignore + def __iter__(self) -> Iterator[MojangRule]: # type: ignore return iter(self.__root__) def __getitem__(self, item: int) -> MojangRule: @@ -319,6 +319,7 @@ class MetaVersion(Versioned): minecraft_arguments: Optional[str] = Field(alias="minecraftArguments") release_time: Optional[datetime] = Field(alias="releaseTime") compatible_java_majors: Optional[List[int]] = Field(alias="compatibleJavaMajors") + compatible_java_name: Optional[str] = Field(alias="compatibleJavaName") additional_traits: Optional[List[str]] = Field(alias="+traits") additional_tweakers: Optional[List[str]] = Field(alias="+tweakers") additional_jvm_args: Optional[List[str]] = Field(alias="+jvmArgs") diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 48a5e5a1dc..749ce7e1eb 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -18,6 +18,9 @@ from . import ( SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 DEFAULT_JAVA_MAJOR = 8 # By default, we should recommend Java 8 if we don't know better +DEFAULT_JAVA_NAME = ( + "jre-legacy" # By default, we should recommend Java 8 if we don't know better +) COMPATIBLE_JAVA_MAPPINGS = {16: [17]} """ @@ -318,10 +321,12 @@ class MojangVersion(MetaBase): raise Exception(f"Unsupported compliance level {self.compliance_level}") major = DEFAULT_JAVA_MAJOR + javaName = DEFAULT_JAVA_NAME if ( self.javaVersion is not None ): # some versions don't have this. TODO: maybe maintain manual overrides major = self.javaVersion.major_version + javaName = self.javaVersion.component compatible_java_majors = [major] if ( @@ -343,6 +348,7 @@ class MojangVersion(MetaBase): release_time=self.release_time, type=new_type, compatible_java_majors=compatible_java_majors, + compatible_java_name=javaName, additional_traits=addn_traits, main_jar=main_jar, ) -- cgit 0.0.5-2-1-g0f52 From 2e6a20a81b937664c9d27ddd61102eeb0f9e99ca Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 29 Feb 2024 13:28:10 +0000 Subject: Update ForgeWrapper Signed-off-by: TheKodeToad --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 5ce6442ec9..4fccc7dcb6 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -16,8 +16,8 @@ STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "1.5.8-prism"), - "acd024c0448ec2c577a3f41aaa471acf6d9cda9b", - 36229, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2024-02-29"), + "86c6791e32ac6478dabf9663f0ad19f8b6465dfe", + 35483, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 97f8750ed72957c26b13146e3c149f2cb43599e9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 19 Mar 2024 22:20:11 +0200 Subject: Split java source Signed-off-by: Trial97 --- generateJava.py | 157 +++++++++++++++++++-------------------------------- meta/common/java.py | 4 +- meta/model/java.py | 28 +++------ meta/model/mojang.py | 1 + 4 files changed, 69 insertions(+), 121 deletions(-) (limited to 'meta') diff --git a/generateJava.py b/generateJava.py index 6a0bfc1061..b9042f1793 100644 --- a/generateJava.py +++ b/generateJava.py @@ -7,7 +7,9 @@ from functools import reduce from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path from meta.common.java import ( - JAVA_COMPONENT, + JAVA_MINECRAFT_COMPONENT, + JAVA_ADOPTIUM_COMPONENT, + JAVA_AZUL_COMPONENT, ADOPTIUM_DIR, ADOPTIUM_VERSIONS_DIR, AZUL_DIR, @@ -16,7 +18,6 @@ from meta.common.java import ( from meta.model import MetaPackage from meta.model.java import ( JavaRuntimeOS, - JavaRuntimeMap, JavaRuntimeVersion, JavaRuntimeMeta, JavaVersionMeta, @@ -48,7 +49,6 @@ LAUNCHER_DIR = launcher_path() UPSTREAM_DIR = upstream_path() STATIC_DIR = static_path() -ensure_component_dir(JAVA_COMPONENT) MOJANG_OS_ARCHITECTURES = [ "x64", @@ -125,6 +125,7 @@ def mojang_os_to_java_os(mojang_os: MojangJavaOsName) -> JavaRuntimeOS: def mojang_runtime_to_java_runtime( mojang_runtime: MojangJavaRuntime, mojang_component: MojangJavaComponent, + runtime_os: JavaRuntimeOS, ) -> JavaRuntimeMeta: major, _, security = mojang_runtime.version.name.partition("u") if major and security: @@ -154,15 +155,17 @@ def mojang_runtime_to_java_runtime( checksum=JavaChecksumMeta( type=JavaChecksumType.Sha1, hash=mojang_runtime.manifest.sha1 ), - recommended=True, downloadType=JavaRuntimeDownloadType.Manifest, packageType=JavaPackageType.Jre, version=version, + runtime_os=runtime_os, ) def adoptium_release_binary_to_java_runtime( - rls: AdoptiumRelease, binary: AdoptiumBinary + rls: AdoptiumRelease, + binary: AdoptiumBinary, + runtime_os: JavaRuntimeOS, ) -> JavaRuntimeMeta: assert binary.package is not None @@ -189,14 +192,16 @@ def adoptium_release_binary_to_java_runtime( url=binary.package.link, releaseTime=rls.timestamp, checksum=checksum, - recommended=False, downloadType=JavaRuntimeDownloadType.Archive, packageType=pkg_type, version=version, + runtime_os=runtime_os, ) -def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: +def azul_package_to_java_runtime( + pkg: ZuluPackageDetail, runtime_os: JavaRuntimeOS +) -> JavaRuntimeMeta: version_parts = copy.copy(pkg.java_version) build = None @@ -227,10 +232,10 @@ def azul_package_to_java_runtime(pkg: ZuluPackageDetail) -> JavaRuntimeMeta: url=pkg.download_url, releaseTime=pkg.build_date, checksum=checksum, - recommended=False, downloadType=JavaRuntimeDownloadType.Archive, packageType=pkg_type, version=version, + runtime_os=runtime_os, ) @@ -262,63 +267,41 @@ def pkg_type_priority(pkg_type: JavaPackageType) -> int: return -1 -def ensure_one_recommended( - runtimes: list[JavaRuntimeMeta], -) -> Optional[JavaRuntimeMeta]: - if len(runtimes) < 1: - return None # can't do anything +def writeJavas(javas: dict[int, list[JavaRuntimeMeta]], uid: str): + ensure_component_dir(uid) + for major, runtimes in javas.items(): - recommended: Optional[JavaRuntimeMeta] = None - found_first = False - need_resort = False - for runtime in runtimes: - if runtime.recommended: - if not found_first: - recommended = runtime - else: - runtime.recommended = False - need_resort = True - - if recommended and not need_resort: - return recommended # we have one recommended already - - if recommended is None: - recommended = runtimes[0] - - def better_java_runtime(runtime: JavaRuntimeMeta): - assert recommended is not None - if vendor_priority(runtime.vendor) < vendor_priority(recommended.vendor): - return False - if pkg_type_priority(runtime.package_type) < pkg_type_priority( - recommended.package_type - ): - return False - if runtime.version < recommended.version: - return False - if runtime.release_time < recommended.release_time: - return False - return True - - for runtime in runtimes: - if better_java_runtime(runtime): - recommended.recommended = False - recommended = runtime - recommended.recommended = True - - return recommended + def newest_timestamp(a: datetime.datetime | None, b: datetime.datetime): + if a is None or a < b: + return b + return a + + version_file = os.path.join(LAUNCHER_DIR, uid, f"java{major}.json") + java_version = JavaRuntimeVersion( + name=f"Java {major}", + uid=uid, + version=f"java{major}", + releaseTime=reduce( + newest_timestamp, + (runtime.release_time for runtime in runtimes), + None, + ), + runtimes=runtimes, + ) + java_version.write(version_file) + + package = MetaPackage(uid=uid, name="Java Runtimes", recommended=[]) + package.write(os.path.join(LAUNCHER_DIR, uid, "package.json")) def main(): - javas: dict[int, JavaRuntimeMap] = {} + javas: dict[int, list[JavaRuntimeMeta]] = {} - def ensure_javamap(major: int): + def add_java_runtime(runtime: JavaRuntimeMeta, major: int): if major not in javas: - javas[major] = JavaRuntimeMap() - - def add_java_runtime(runtime: JavaRuntimeMeta, major: int, java_os: JavaRuntimeOS): - ensure_javamap(major) - print(f"Regestering runtime: {runtime.name} for Java {major} {java_os}") - javas[major][java_os].append(runtime) + javas[major] = list[JavaRuntimeMeta]() + print(f"Regestering runtime: {runtime.name} for Java {major}") + javas[major].append(runtime) print("Processing Mojang Javas") mojang_java_manifest = JavaIndex.parse_file( @@ -337,8 +320,11 @@ def main(): major = 8 else: major = int(mojang_runtime.version.name.partition(".")[0]) - runtime = mojang_runtime_to_java_runtime(mojang_runtime, comp) - add_java_runtime(runtime, major, java_os) + runtime = mojang_runtime_to_java_runtime(mojang_runtime, comp, java_os) + add_java_runtime(runtime, major) + + writeJavas(javas=javas, uid=JAVA_MINECRAFT_COMPONENT) + javas = {} print("Processing Adoptium Releases") adoptium_path = os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") @@ -361,9 +347,13 @@ def main(): continue java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") - runtime = adoptium_release_binary_to_java_runtime(rls, binary) - add_java_runtime(runtime, major, java_os) + runtime = adoptium_release_binary_to_java_runtime( + rls, binary, java_os + ) + add_java_runtime(runtime, major) + writeJavas(javas=javas, uid=JAVA_ADOPTIUM_COMPONENT) + javas = {} print("Processing Azul Packages") azul_path = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") if os.path.exists(azul_path): @@ -392,43 +382,10 @@ def main(): continue java_os = JavaRuntimeOS(f"{pkg_os}-{pkg_arch}") - runtime = azul_package_to_java_runtime(pkg_detail) - add_java_runtime(runtime, major, java_os) - - for major, runtimes in javas.items(): - for java_os, runtime_list in runtimes: - print(f"Total runtimes for Java {major} {java_os}:", len(runtime_list)) - rec = ensure_one_recommended(runtime_list) - if rec is not None: - print(f"Recomending {rec.name} for Java {major} {java_os}") - - def newest_timestamp(a: datetime.datetime | None, b: datetime.datetime): - if a is None or a < b: - return b - return a - - version_file = os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, f"java{major}.json") - java_version = JavaRuntimeVersion( - name=f"Java {major}", - uid=JAVA_COMPONENT, - version=f"java{major}", - releaseTime=reduce( - newest_timestamp, - ( - runtime.release_time - for _, runtime_list in runtimes - for runtime in runtime_list - ), - None, - ), - runtimes=runtimes, - ) - java_version.write(version_file) - - package = MetaPackage( - uid=JAVA_COMPONENT, name="Java Runtimes", recommended=["java8", "java17"] - ) - package.write(os.path.join(LAUNCHER_DIR, JAVA_COMPONENT, "package.json")) + runtime = azul_package_to_java_runtime(pkg_detail, java_os) + add_java_runtime(runtime, major) + writeJavas(javas=javas, uid=JAVA_AZUL_COMPONENT) + javas = {} if __name__ == "__main__": diff --git a/meta/common/java.py b/meta/common/java.py index 541d2fb374..ec13b2a55f 100644 --- a/meta/common/java.py +++ b/meta/common/java.py @@ -9,4 +9,6 @@ AZUL_DIR = join(BASE_DIR, "azul") ADOPTIUM_VERSIONS_DIR = join(ADOPTIUM_DIR, "versions") AZUL_VERSIONS_DIR = join(AZUL_DIR, "versions") -JAVA_COMPONENT = "net.minecraft.java" \ No newline at end of file +JAVA_MINECRAFT_COMPONENT = "net.minecraft.java" +JAVA_ADOPTIUM_COMPONENT = "net.adoptium.java" +JAVA_AZUL_COMPONENT = "com.azul.java" diff --git a/meta/model/java.py b/meta/model/java.py index d232196706..e24932ef85 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -10,6 +10,7 @@ from .enum import StrEnum from typing import Optional, Any, NamedTuple, Generator from urllib.parse import urlencode, urlparse, urlunparse from functools import total_ordering + # namedtuple to match the internal signature of urlunparse @@ -55,10 +56,10 @@ class JavaVersionMeta(MetaBase): return (self.major, self.minor, self.security, build) def __eq__(self, other: Any): - return (self.to_tuple() == other.to_tuple()) + return self.to_tuple() == other.to_tuple() - def __lt__(self, other: 'JavaVersionMeta'): - return (self.to_tuple() < other.to_tuple()) + def __lt__(self, other: "JavaVersionMeta"): + return self.to_tuple() < other.to_tuple() class JavaChecksumType(StrEnum): @@ -82,28 +83,15 @@ class JavaRuntimeMeta(MetaBase): url: str release_time: datetime = Field(alias="releaseTime") checksum: Optional[JavaChecksumMeta] - recommended: bool download_type: JavaRuntimeDownloadType = Field(alias="downloadType") package_type: JavaPackageType = Field(alias="packageType") version: JavaVersionMeta + runtime_os: JavaRuntimeOS = Field(alias="runtimeOS") -class JavaRuntimeMap(MetaBase): - __root__: dict[JavaRuntimeOS, list[JavaRuntimeMeta]] = { - os: [] for os in JavaRuntimeOS if os != JavaRuntimeOS.Unknown - } - - def __iter__(self) -> Generator[tuple[str, list[JavaRuntimeMeta]], None, None]: - yield from ((str(os), runtime) for os, runtime in self.__root__.items()) - - def __getitem__(self, item: JavaRuntimeOS) -> list[JavaRuntimeMeta]: - return self.__root__[item] - - def __len__(self): - return len(self.__root__) - class JavaRuntimeVersion(MetaVersion): - runtimes: JavaRuntimeMap + runtimes: list[JavaRuntimeMeta] + class URLComponents(NamedTuple): scheme: str @@ -122,7 +110,7 @@ class APIQuery(MetaBase): if isinstance(value, Enum): set_parts[key] = value.value elif isinstance(value, list): - if len(value) > 0: #type: ignore + if len(value) > 0: # type: ignore set_parts[key] = value elif isinstance(value, datetime): set_parts[key] = value.isoformat() diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 749ce7e1eb..1ad31d6973 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -203,6 +203,7 @@ class MojangJavaComponent(StrEnum): Gamma = "java-runtime-gamma" GammaSnapshot = "java-runtime-gamma-snapshot" Exe = "minecraft-java-exe" + Delta = "java-runtime-delta" class JavaVersion(MetaBase): -- cgit 0.0.5-2-1-g0f52 From 74fddd3673b50bc3d0c0b4ff6854193240eaa067 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 27 Mar 2024 12:30:06 +0200 Subject: Added supported features to not polute traits Signed-off-by: Trial97 --- generateMojang.py | 21 +++++++++++---------- meta/model/mojang.py | 1 + 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'meta') diff --git a/generateMojang.py b/generateMojang.py index 59a71c75f2..74d7e883bf 100755 --- a/generateMojang.py +++ b/generateMojang.py @@ -35,6 +35,7 @@ from meta.model.mojang import ( MojangVersion, LegacyOverrideIndex, LibraryPatches, + SUPPORTED_FEATURES, ) APPLY_SPLIT_NATIVES_WORKAROUND = True @@ -198,22 +199,20 @@ def adapt_new_style_arguments(arguments): pprint(arg) return " ".join(foo) + def adapt_new_style_arguments_to_traits(arguments): foo = [] # we ignore the jvm arguments entirely. # grab the object, log the errors for arg in arguments.game: - if not isinstance(arg, str): - try: - for rule in arg["rules"]: - for k,v in rule["features"].items(): - if rule["action"] == "allow" and v: - foo.append(f"feature:{k}") - except: - print("something did not go as planed") - pprint(arg) + if isinstance(arg, dict): + for rule in arg["rules"]: + for k, v in rule["features"].items(): + if rule["action"] == "allow" and v and k in SUPPORTED_FEATURES: + foo.append(f"feature:{k}") return foo + def is_macos_only(rules: Optional[MojangRules]): allows_osx = False allows_all = False @@ -503,7 +502,9 @@ def main(): v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) if not v.additional_traits: v.additional_traits = [] - v.additional_traits.extend(adapt_new_style_arguments_to_traits(mojang_version.arguments)) + v.additional_traits.extend( + adapt_new_style_arguments_to_traits(mojang_version.arguments) + ) out_filename = os.path.join( LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{v.version}.json" ) diff --git a/meta/model/mojang.py b/meta/model/mojang.py index d54b7f9851..221f8e074e 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -18,6 +18,7 @@ SUPPORTED_LAUNCHER_VERSION = 21 SUPPORTED_COMPLIANCE_LEVEL = 1 DEFAULT_JAVA_MAJOR = 8 # By default, we should recommend Java 8 if we don't know better COMPATIBLE_JAVA_MAPPINGS = {16: [17]} +SUPPORTED_FEATURES = ["is_quick_play_multiplayer"] """ Mojang index files look like this: -- cgit 0.0.5-2-1-g0f52 From be4317cf9d982018b4ff86375d680826ffacb62f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 28 Dec 2023 22:20:03 +0100 Subject: refactor!: package using Nix Signed-off-by: Sefa Eyeoglu --- .gitignore | 4 +- Containerfile | 31 - Dockerfile | 1 - Pipfile | 17 - Pipfile.lock | 278 -- README.md | 50 +- clone.sh | 20 - config.example.sh | 13 + config.sh | 12 - config/.gitignore | 2 - config/config_local.sh.example | 8 - config/readme.txt | 8 - docker-compose.local.yaml | 12 - docker-compose.yaml | 13 - flake.lock | 94 +- flake.nix | 20 +- generateFabric.py | 143 - generateForge.py | 473 --- generateLiteloader.py | 118 - generateMojang.py | 583 ---- generateNeoForge.py | 182 - generateQuilt.py | 161 - index.py | 78 - meta/common/__init__.py | 23 +- meta/common/forge.py | 5 +- meta/common/mojang-library-patches.json | 2879 ++++++++++++++++ meta/common/mojang-minecraft-experiments.json | 104 + meta/common/mojang-minecraft-legacy-override.json | 585 ++++ meta/common/mojang-minecraft-legacy-services.json | 218 ++ meta/common/mojang-minecraft-old-snapshots.json | 604 ++++ meta/common/mojang.py | 16 +- meta/run/__init__.py | 1 + meta/run/generate_fabric.py | 143 + meta/run/generate_forge.py | 472 +++ meta/run/generate_liteloader.py | 118 + meta/run/generate_mojang.py | 576 ++++ meta/run/generate_neoforge.py | 181 + meta/run/generate_quilt.py | 161 + meta/run/index.py | 78 + meta/run/update_fabric.py | 130 + meta/run/update_forge.py | 397 +++ meta/run/update_liteloader.py | 37 + meta/run/update_mojang.py | 161 + meta/run/update_neoforge.py | 319 ++ meta/run/update_quilt.py | 122 + nix/default.nix | 11 - nix/dev.nix | 44 +- nix/nixos/default.nix | 10 + nix/nixos/meta.nix | 69 + nix/packages.nix | 18 + nix/pkgs/blockgame-meta.nix | 64 + poetry.lock | 340 ++ pyproject.toml | 37 + static/forge/forge-legacyinfo.json | 3712 --------------------- static/mojang/library-patches.json | 2879 ---------------- static/mojang/minecraft-experiments.json | 104 - static/mojang/minecraft-legacy-override.json | 585 ---- static/mojang/minecraft-legacy-services.json | 218 -- static/mojang/minecraft-old-snapshots.json | 604 ---- status.sh | 24 - update.sh | 54 +- updateFabric.py | 130 - updateForge.py | 397 --- updateLiteloader.py | 37 - updateMojang.py | 165 - updateNeoForge.py | 319 -- updateQuilt.py | 122 - 67 files changed, 8001 insertions(+), 11593 deletions(-) delete mode 100644 Containerfile delete mode 120000 Dockerfile delete mode 100644 Pipfile delete mode 100644 Pipfile.lock delete mode 100755 clone.sh create mode 100644 config.example.sh delete mode 100644 config.sh delete mode 100644 config/.gitignore delete mode 100644 config/config_local.sh.example delete mode 100644 config/readme.txt delete mode 100644 docker-compose.local.yaml delete mode 100644 docker-compose.yaml delete mode 100755 generateFabric.py delete mode 100755 generateForge.py delete mode 100755 generateLiteloader.py delete mode 100755 generateMojang.py delete mode 100644 generateNeoForge.py delete mode 100755 generateQuilt.py delete mode 100755 index.py create mode 100644 meta/common/mojang-library-patches.json create mode 100644 meta/common/mojang-minecraft-experiments.json create mode 100644 meta/common/mojang-minecraft-legacy-override.json create mode 100644 meta/common/mojang-minecraft-legacy-services.json create mode 100644 meta/common/mojang-minecraft-old-snapshots.json create mode 100644 meta/run/__init__.py create mode 100755 meta/run/generate_fabric.py create mode 100755 meta/run/generate_forge.py create mode 100755 meta/run/generate_liteloader.py create mode 100755 meta/run/generate_mojang.py create mode 100644 meta/run/generate_neoforge.py create mode 100755 meta/run/generate_quilt.py create mode 100755 meta/run/index.py create mode 100755 meta/run/update_fabric.py create mode 100755 meta/run/update_forge.py create mode 100755 meta/run/update_liteloader.py create mode 100755 meta/run/update_mojang.py create mode 100644 meta/run/update_neoforge.py create mode 100755 meta/run/update_quilt.py delete mode 100644 nix/default.nix create mode 100644 nix/nixos/default.nix create mode 100644 nix/nixos/meta.nix create mode 100644 nix/packages.nix create mode 100644 nix/pkgs/blockgame-meta.nix create mode 100644 poetry.lock create mode 100644 pyproject.toml delete mode 100644 static/forge/forge-legacyinfo.json delete mode 100644 static/mojang/library-patches.json delete mode 100644 static/mojang/minecraft-experiments.json delete mode 100644 static/mojang/minecraft-legacy-override.json delete mode 100644 static/mojang/minecraft-legacy-services.json delete mode 100644 static/mojang/minecraft-old-snapshots.json delete mode 100755 status.sh delete mode 100755 updateFabric.py delete mode 100755 updateForge.py delete mode 100755 updateLiteloader.py delete mode 100755 updateMojang.py delete mode 100644 updateNeoForge.py delete mode 100755 updateQuilt.py (limited to 'meta') diff --git a/.gitignore b/.gitignore index e05d6a236e..e923628164 100644 --- a/.gitignore +++ b/.gitignore @@ -4,11 +4,13 @@ .direnv/ .pre-commit-config.yaml +result + public/*/ caches/ !caches/*/.keep __pycache__ -config_local.sh +config.sh launcher upstream diff --git a/Containerfile b/Containerfile deleted file mode 100644 index 68e22b68c7..0000000000 --- a/Containerfile +++ /dev/null @@ -1,31 +0,0 @@ -FROM python:3.11.5-alpine3.17 -ARG UID=1337 -ARG GID=1337 - -RUN pip install pipenv \ - && apk add --no-cache rsync cronie git openssh bash - -WORKDIR /app -COPY Pipfile Pipfile.lock . -RUN pipenv install --system --deploy - -# add our cronjob -COPY docker/update.cron /etc/cron.d/meta-update -RUN chmod 644 /etc/cron.d/meta-update \ - && crontab /etc/cron.d/meta-update - -# install entrypoint -COPY docker/entrypoint.sh /usr/local/bin/entrypoint -RUN chmod +x /usr/local/bin/entrypoint - -RUN addgroup -g $GID user \ - && adduser --disabled-password --ingroup user --uid $UID user \ - && mkdir -p /home/user/.ssh \ - && ssh-keyscan github.com > /home/user/.ssh/known_hosts \ - && mkdir -p /app \ - && chown -R $UID:$GID /app /home/user/.ssh - -COPY . . - -ENTRYPOINT ["/usr/local/bin/entrypoint"] -CMD ["update"] diff --git a/Dockerfile b/Dockerfile deleted file mode 120000 index 5240dc01ed..0000000000 --- a/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -Containerfile \ No newline at end of file diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 868e17316e..0000000000 --- a/Pipfile +++ /dev/null @@ -1,17 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -cachecontrol = "*" -requests = "*" -lockfile = "*" -packaging = "*" -pydantic = "*" - -[dev-packages] - -[requires] -python_version = "3.11" -python_full_version = "3.11.1" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index b861cffa2c..0000000000 --- a/Pipfile.lock +++ /dev/null @@ -1,278 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "15c961d5f6a169119087dbf265b01a2f7b40fa434595ffb0d85ea6f3d8ec6409" - }, - "pipfile-spec": 6, - "requires": { - "python_full_version": "3.11.1", - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "cachecontrol": { - "hashes": [ - "sha256:2c75d6a8938cb1933c75c50184549ad42728a27e9f6b92fd677c3151aa72555b", - "sha256:a5b9fcc986b184db101aa280b42ecdcdfc524892596f606858e0b7a8b4d9e144" - ], - "index": "pypi", - "version": "==0.12.11" - }, - "certifi": { - "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.12.7" - }, - "charset-normalizer": { - "hashes": [ - "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b", - "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42", - "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d", - "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b", - "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a", - "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59", - "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154", - "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1", - "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c", - "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a", - "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d", - "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6", - "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b", - "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b", - "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783", - "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5", - "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918", - "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555", - "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639", - "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786", - "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e", - "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed", - "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820", - "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8", - "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3", - "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541", - "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14", - "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be", - "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e", - "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76", - "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b", - "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c", - "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b", - "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3", - "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc", - "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6", - "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59", - "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4", - "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d", - "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d", - "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3", - "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", - "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea", - "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6", - "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e", - "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603", - "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24", - "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a", - "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58", - "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678", - "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a", - "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c", - "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6", - "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18", - "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174", - "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317", - "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f", - "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc", - "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837", - "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41", - "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c", - "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579", - "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753", - "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8", - "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291", - "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087", - "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866", - "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3", - "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d", - "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1", - "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca", - "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e", - "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db", - "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72", - "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d", - "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc", - "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539", - "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d", - "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af", - "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b", - "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602", - "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", - "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478", - "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c", - "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e", - "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479", - "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7", - "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8" - ], - "version": "==3.0.1" - }, - "idna": { - "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" - ], - "markers": "python_version >= '3.5'", - "version": "==3.4" - }, - "lockfile": { - "hashes": [ - "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799", - "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa" - ], - "index": "pypi", - "version": "==0.12.2" - }, - "msgpack": { - "hashes": [ - "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467", - "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae", - "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92", - "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef", - "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624", - "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227", - "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88", - "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9", - "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8", - "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd", - "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6", - "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55", - "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e", - "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2", - "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44", - "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6", - "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9", - "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab", - "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae", - "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa", - "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9", - "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e", - "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250", - "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce", - "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075", - "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236", - "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae", - "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e", - "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f", - "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08", - "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6", - "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d", - "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43", - "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1", - "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6", - "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0", - "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c", - "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff", - "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db", - "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243", - "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661", - "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba", - "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e", - "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb", - "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52", - "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6", - "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1", - "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f", - "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da", - "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f", - "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c", - "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8" - ], - "version": "==1.0.4" - }, - "packaging": { - "hashes": [ - "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", - "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" - ], - "index": "pypi", - "version": "==23.0" - }, - "pydantic": { - "hashes": [ - "sha256:05a81b006be15655b2a1bae5faa4280cf7c81d0e09fcb49b342ebf826abe5a72", - "sha256:0b53e1d41e97063d51a02821b80538053ee4608b9a181c1005441f1673c55423", - "sha256:2b3ce5f16deb45c472dde1a0ee05619298c864a20cded09c4edd820e1454129f", - "sha256:2e82a6d37a95e0b1b42b82ab340ada3963aea1317fd7f888bb6b9dfbf4fff57c", - "sha256:301d626a59edbe5dfb48fcae245896379a450d04baeed50ef40d8199f2733b06", - "sha256:39f4a73e5342b25c2959529f07f026ef58147249f9b7431e1ba8414a36761f53", - "sha256:4948f264678c703f3877d1c8877c4e3b2e12e549c57795107f08cf70c6ec7774", - "sha256:4b05697738e7d2040696b0a66d9f0a10bec0efa1883ca75ee9e55baf511909d6", - "sha256:51bdeb10d2db0f288e71d49c9cefa609bca271720ecd0c58009bd7504a0c464c", - "sha256:55b1625899acd33229c4352ce0ae54038529b412bd51c4915349b49ca575258f", - "sha256:572066051eeac73d23f95ba9a71349c42a3e05999d0ee1572b7860235b850cc6", - "sha256:6a05a9db1ef5be0fe63e988f9617ca2551013f55000289c671f71ec16f4985e3", - "sha256:6dc1cc241440ed7ca9ab59d9929075445da6b7c94ced281b3dd4cfe6c8cff817", - "sha256:6e7124d6855b2780611d9f5e1e145e86667eaa3bd9459192c8dc1a097f5e9903", - "sha256:75d52162fe6b2b55964fbb0af2ee58e99791a3138588c482572bb6087953113a", - "sha256:78cec42b95dbb500a1f7120bdf95c401f6abb616bbe8785ef09887306792e66e", - "sha256:7feb6a2d401f4d6863050f58325b8d99c1e56f4512d98b11ac64ad1751dc647d", - "sha256:8775d4ef5e7299a2f4699501077a0defdaac5b6c4321173bcb0f3c496fbadf85", - "sha256:887ca463c3bc47103c123bc06919c86720e80e1214aab79e9b779cda0ff92a00", - "sha256:9193d4f4ee8feca58bc56c8306bcb820f5c7905fd919e0750acdeeeef0615b28", - "sha256:983e720704431a6573d626b00662eb78a07148c9115129f9b4351091ec95ecc3", - "sha256:990406d226dea0e8f25f643b370224771878142155b879784ce89f633541a024", - "sha256:9cbdc268a62d9a98c56e2452d6c41c0263d64a2009aac69246486f01b4f594c4", - "sha256:a48f1953c4a1d9bd0b5167ac50da9a79f6072c63c4cef4cf2a3736994903583e", - "sha256:a9a6747cac06c2beb466064dda999a13176b23535e4c496c9d48e6406f92d42d", - "sha256:a9f2de23bec87ff306aef658384b02aa7c32389766af3c5dee9ce33e80222dfa", - "sha256:b5635de53e6686fe7a44b5cf25fcc419a0d5e5c1a1efe73d49d48fe7586db854", - "sha256:b6f9d649892a6f54a39ed56b8dfd5e08b5f3be5f893da430bed76975f3735d15", - "sha256:b9a3859f24eb4e097502a3be1fb4b2abb79b6103dd9e2e0edb70613a4459a648", - "sha256:cd8702c5142afda03dc2b1ee6bc358b62b3735b2cce53fc77b31ca9f728e4bc8", - "sha256:d7b5a3821225f5c43496c324b0d6875fde910a1c2933d726a743ce328fbb2a8c", - "sha256:d88c4c0e5c5dfd05092a4b271282ef0588e5f4aaf345778056fc5259ba098857", - "sha256:eb992a1ef739cc7b543576337bebfc62c0e6567434e522e97291b251a41dad7f", - "sha256:f2f7eb6273dd12472d7f218e1fef6f7c7c2f00ac2e1ecde4db8824c457300416", - "sha256:fdf88ab63c3ee282c76d652fc86518aacb737ff35796023fae56a65ced1a5978", - "sha256:fdf8d759ef326962b4678d89e275ffc55b7ce59d917d9f72233762061fd04a2d" - ], - "index": "pypi", - "version": "==1.10.4" - }, - "requests": { - "hashes": [ - "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", - "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" - ], - "index": "pypi", - "version": "==2.28.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", - "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" - ], - "markers": "python_version >= '3.7'", - "version": "==4.4.0" - }, - "urllib3": { - "hashes": [ - "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", - "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.14" - } - }, - "develop": {} -} diff --git a/README.md b/README.md index 352fe34b4b..02b43e60f4 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,37 @@ # Prism Launcher Meta + Scripts to generate jsons and jars that Prism Launcher will access. -## Deployment -It is recommended to use Docker to deploy the environment. - -- Clone this repo to a server -- Make sure it's writable by the container later: `chown -R 1337:1337 .` -- Configure `config/config_local.sh` - - The defaults should be fine (apart from committer email and name perhaps) -- Put your SSH key (which has push access to meta-upstream and meta-launcher) at `config/deploy.key` -- Pull meta- repos: `bash clone.sh` -- Customize docker-compose.yaml -- Run `docker-compose up -d --build` -- Observe Cron logs using `docker-compose logs -f` (Runs hourly by default) -- (Optional) Run once to fill caches: `docker-compose run meta update` - -For local development you can also use `docker-compose.local.yaml`. By default, it uses `UID=1000` and `GID=1000`. -Make sure it's the same as your host instance. +## Recommended Deployment + +Assuming you have a Flake-based NixOS configuration + +- Add Flake input: + + ```nix + { + inputs.prism-meta.url = "github:PrismLauncher/meta"; + } + ``` + +- Import NixOS module and configure + + ```nix + {inputs, ...}: { + imports = [inputs.prism-meta.nixosModules.default]; + services.blockgame-meta = { + enable = true; + settings = { + DEPLOY_TO_GIT = "true"; + GIT_AUTHOR_NAME = "Herpington Derpson"; + GIT_AUTHOR_EMAIL = "herpderp@derpmail.com"; + GIT_COMMITTER_NAME = "Herpington Derpson"; + GIT_COMMITTER_EMAIL = "herpderp@derpmail.com"; + }; + }; + } + ``` + +- Rebuild and activate! +- Trigger it `systemctl start blockgame-meta.service` +- Monitor it `journalctl -fu blockgame-meta.service` diff --git a/clone.sh b/clone.sh deleted file mode 100755 index 350a9b5e8a..0000000000 --- a/clone.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -BASEDIR=$(dirname "$0") -cd "${BASEDIR}" || exit 1 -BASEDIR=$(pwd) - -source config.sh -if [ -f config/config_local.sh ]; then - source config/config_local.sh -fi - -set -x - -if [ ! -d "${UPSTREAM_DIR}" ]; then - git clone "${UPSTREAM_REPO}" "${UPSTREAM_DIR}" -fi - -if [ ! -d "${LAUNCHER_DIR}" ]; then - git clone "${LAUNCHER_REPO}" "${LAUNCHER_DIR}" -fi diff --git a/config.example.sh b/config.example.sh new file mode 100644 index 0000000000..835059f3af --- /dev/null +++ b/config.example.sh @@ -0,0 +1,13 @@ +export META_UPSTREAM_DIR=upstream +export META_LAUNCHER_DIR=launcher +export DEPLOY_TO_FOLDER=false +export DEPLOY_FOLDER=/app/public/v1 +export DEPLOY_FOLDER_USER=http +export DEPLOY_FOLDER_GROUP=http + +export DEPLOY_TO_GIT=true +export GIT_AUTHOR_NAME="Herpington Derpson" +export GIT_AUTHOR_EMAIL="herpderp@derpmail.com" +export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" +export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" +export GIT_SSH_COMMAND="ssh -i ${BASEDIR}/config/deploy.key" diff --git a/config.sh b/config.sh deleted file mode 100644 index 49c3b66f12..0000000000 --- a/config.sh +++ /dev/null @@ -1,12 +0,0 @@ -export UPSTREAM_DIR=upstream -export UPSTREAM_REPO=git@github.com:PrismLauncher/meta-upstream.git -export LAUNCHER_DIR=launcher -export LAUNCHER_REPO=git@github.com:PrismLauncher/meta-launcher.git -export BRANCH_master=master -export BRANCH_develop=develop -export DEPLOY_TO_S3=false -export DEPLOY_TO_FOLDER=true -export DEPLOY_FOLDER_master=/app/public/v1 -export DEPLOY_FOLDER_develop=/app/public/dev -export DEPLOY_FOLDER_USER=http -export DEPLOY_FOLDER_GROUP=http diff --git a/config/.gitignore b/config/.gitignore deleted file mode 100644 index f31346ea33..0000000000 --- a/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.key -*.pub diff --git a/config/config_local.sh.example b/config/config_local.sh.example deleted file mode 100644 index 1292af9e6f..0000000000 --- a/config/config_local.sh.example +++ /dev/null @@ -1,8 +0,0 @@ -export MODE=master -export GIT_AUTHOR_NAME="Herpington Derpson" -export GIT_AUTHOR_EMAIL="herpderp@derpmail.com" -export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" -export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" -export DEPLOY_TO_FOLDER=false -export DEPLOY_TO_GIT=true -export GIT_SSH_COMMAND="ssh -i ${BASEDIR}/config/deploy.key" diff --git a/config/readme.txt b/config/readme.txt deleted file mode 100644 index bcbda08466..0000000000 --- a/config/readme.txt +++ /dev/null @@ -1,8 +0,0 @@ -This is where you should put the git deploy keys. - -These are expected: -* meta-multimc.key -* meta-multimc.key.pub -* meta-upstream.key -* meta-upstream.key.pub -* s3cmd.cfg \ No newline at end of file diff --git a/docker-compose.local.yaml b/docker-compose.local.yaml deleted file mode 100644 index 43f18c6b1a..0000000000 --- a/docker-compose.local.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: "3" - -services: - meta: - build: - context: . - args: - UID: 1000 - GID: 1000 - command: update - volumes: - - "./:/app" diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index f15ea051f4..0000000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,13 +0,0 @@ -version: "3" - -services: - meta: - build: . - command: cron - volumes: - - "./caches:/app/caches" - - "./upstream:/app/upstream" - - "./launcher:/app/launcher" - - "./public:/app/public" - - "./config:/app/config" - restart: unless-stopped diff --git a/flake.lock b/flake.lock index 9bb05cb5ee..17853bda56 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", "owner": "edolstra", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "type": "github" }, "original": { @@ -21,11 +21,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1698579227, - "narHash": "sha256-KVWjFZky+gRuWennKsbo6cWyo7c/z/VgCte5pR9pEKg=", + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "f76e870d64779109e41370848074ac4eaa1606ec", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", "type": "github" }, "original": { @@ -39,11 +39,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -52,19 +52,45 @@ "type": "github" } }, + "git-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1713954846, + "narHash": "sha256-RWFafuSb5nkWGu8dDbW7gVb8FOQOPqmX/9MlxUUDguw=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "6fb82e44254d6a0ece014ec423cb62d92435336f", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, "gitignore": { "inputs": { "nixpkgs": [ - "pre-commit-hooks", + "git-hooks", "nixpkgs" ] }, "locked": { - "lastModified": 1660459072, - "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", "type": "github" }, "original": { @@ -75,11 +101,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1698553279, - "narHash": "sha256-T/9P8yBSLcqo/v+FTOBK+0rjzjPMctVymZydbvR/Fak=", + "lastModified": 1713805509, + "narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=", "owner": "nixos", "repo": "nixpkgs", - "rev": "90e85bc7c1a6fc0760a94ace129d3a1c61c3d035", + "rev": "1e1dc66fe68972a76679644a5577828b6a7e8be4", "type": "github" }, "original": { @@ -92,11 +118,11 @@ "nixpkgs-lib": { "locked": { "dir": "lib", - "lastModified": 1696019113, - "narHash": "sha256-X3+DKYWJm93DRSdC5M6K5hLqzSya9BjibtBsuARoPco=", + "lastModified": 1711703276, + "narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f5892ddac112a1e9b3612c39af1b72987ee5783a", + "rev": "d8fe5e6c92d0d190646fb9f1056741a229980089", "type": "github" }, "original": { @@ -107,37 +133,11 @@ "type": "github" } }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": "flake-compat", - "flake-utils": "flake-utils", - "gitignore": "gitignore", - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgs-stable": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1698227354, - "narHash": "sha256-Fi5H9jbaQLmLw9qBi/mkR33CoFjNbobo5xWdX4tKz1Q=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "bd38df3d508dfcdff52cd243d297f218ed2257bf", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, "root": { "inputs": { "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs", - "pre-commit-hooks": "pre-commit-hooks" + "git-hooks": "git-hooks", + "nixpkgs": "nixpkgs" } }, "systems": { diff --git a/flake.nix b/flake.nix index 513f05345a..153f7eb534 100644 --- a/flake.nix +++ b/flake.nix @@ -4,8 +4,8 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; - pre-commit-hooks = { - url = "github:cachix/pre-commit-hooks.nix"; + git-hooks = { + url = "github:cachix/git-hooks.nix"; inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs-stable.follows = "nixpkgs"; }; @@ -14,5 +14,19 @@ outputs = inputs: inputs.flake-parts.lib.mkFlake {inherit inputs;} - {imports = [./nix];}; + { + imports = [ + inputs.git-hooks.flakeModule + + ./nix/dev.nix + ./nix/nixos + ./nix/packages.nix + ]; + + # Supported systems. + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; + }; } diff --git a/generateFabric.py b/generateFabric.py deleted file mode 100755 index 7ca50dd6aa..0000000000 --- a/generateFabric.py +++ /dev/null @@ -1,143 +0,0 @@ -import json -import os - -from meta.common import ( - ensure_component_dir, - launcher_path, - upstream_path, - transform_maven_key, -) -from meta.common.fabric import ( - JARS_DIR, - INSTALLER_INFO_DIR, - META_DIR, - INTERMEDIARY_COMPONENT, - LOADER_COMPONENT, -) -from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier -from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses - -LAUNCHER_DIR = launcher_path() -UPSTREAM_DIR = upstream_path() - -ensure_component_dir(LOADER_COMPONENT) -ensure_component_dir(INTERMEDIARY_COMPONENT) - - -def load_jar_info(artifact_key) -> FabricJarInfo: - return FabricJarInfo.parse_file( - os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") - ) - - -def load_installer_info(version) -> FabricInstallerDataV1: - return FabricInstallerDataV1.parse_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") - ) - - -def process_loader_version(entry) -> MetaVersion: - jar_info = load_jar_info(transform_maven_key(entry["maven"])) - installer_info = load_installer_info(entry["version"]) - - v = MetaVersion( - name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"] - ) - v.release_time = jar_info.release_time - v.requires = [Dependency(uid="net.fabricmc.intermediary")] - v.order = 10 - v.type = "release" - if isinstance(installer_info.main_class, FabricMainClasses): - v.main_class = installer_info.main_class.client - else: - v.main_class = installer_info.main_class - v.libraries = [] - v.libraries.extend(installer_info.libraries.common) - v.libraries.extend(installer_info.libraries.client) - loader_lib = Library( - name=GradleSpecifier.from_string(entry["maven"]), - url="https://maven.fabricmc.net", - ) - v.libraries.append(loader_lib) - return v - - -def process_intermediary_version(entry) -> MetaVersion: - jar_info = load_jar_info(transform_maven_key(entry["maven"])) - - v = MetaVersion( - name="Intermediary Mappings", - uid="net.fabricmc.intermediary", - version=entry["version"], - ) - v.release_time = jar_info.release_time - v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] - v.order = 11 - v.type = "release" - v.libraries = [] - v.volatile = True - intermediary_lib = Library( - name=GradleSpecifier.from_string(entry["maven"]), - url="https://maven.fabricmc.net", - ) - v.libraries.append(intermediary_lib) - return v - - -def main(): - recommended_loader_versions = [] - recommended_intermediary_versions = [] - - with open( - os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" - ) as f: - loader_version_index = json.load(f) - for entry in loader_version_index: - version = entry["version"] - print(f"Processing loader {version}") - - v = process_loader_version(entry) - - # Fabric Meta has a separate "stable" field, let's use that - if not recommended_loader_versions and entry["stable"]: - recommended_loader_versions.append(version) - - v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) - - with open( - os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), "r", encoding="utf-8" - ) as f: - intermediary_version_index = json.load(f) - for entry in intermediary_version_index: - version = entry["version"] - print(f"Processing intermediary {version}") - - v = process_intermediary_version(entry) - - recommended_intermediary_versions.append( - version - ) # all intermediaries are recommended - - v.write( - os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json") - ) - - package = MetaPackage(uid=LOADER_COMPONENT, name="Fabric Loader") - package.recommended = recommended_loader_versions - package.description = ( - "Fabric Loader is a tool to load Fabric-compatible mods in game environments." - ) - package.project_url = "https://fabricmc.net" - package.authors = ["Fabric Developers"] - package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) - - package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name="Intermediary Mappings") - package.recommended = recommended_intermediary_versions - package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." - package.project_url = "https://fabricmc.net" - package.authors = ["Fabric Developers"] - package.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json")) - - -if __name__ == "__main__": - main() diff --git a/generateForge.py b/generateForge.py deleted file mode 100755 index 9359dd4812..0000000000 --- a/generateForge.py +++ /dev/null @@ -1,473 +0,0 @@ -import os -import re -import sys -from packaging import version as pversion -from operator import attrgetter -from typing import Collection - -from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path -from meta.common.forge import ( - FORGE_COMPONENT, - INSTALLER_MANIFEST_DIR, - VERSION_MANIFEST_DIR, - DERIVED_INDEX_FILE, - STATIC_LEGACYINFO_FILE, - INSTALLER_INFO_DIR, - BAD_VERSIONS, - FORGEWRAPPER_LIBRARY, -) -from meta.common.mojang import MINECRAFT_COMPONENT -from meta.model import ( - MetaVersion, - Dependency, - Library, - GradleSpecifier, - MojangLibraryDownloads, - MojangArtifact, - MetaPackage, -) -from meta.model.forge import ( - ForgeVersion, - ForgeInstallerProfile, - ForgeLegacyInfo, - fml_libs_for_version, - ForgeInstallerProfileV2, - InstallerInfo, - DerivedForgeIndex, - ForgeLegacyInfoList, -) -from meta.model.mojang import MojangVersion - -LAUNCHER_DIR = launcher_path() -UPSTREAM_DIR = upstream_path() -STATIC_DIR = static_path() - -ensure_component_dir(FORGE_COMPONENT) - - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - -# Construct a set of libraries out of a Minecraft version file, for filtering. -mc_version_cache = {} - - -def load_mc_version_filter(version: str): - if version in mc_version_cache: - return mc_version_cache[version] - v = MetaVersion.parse_file( - os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json") - ) - libs = set(map(attrgetter("name"), v.libraries)) - mc_version_cache[version] = libs - return libs - - -""" -Match a library coordinate to a set of library coordinates. - * Block those that pass completely. - * For others, block those with lower versions than in the set. -""" - - -def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpecifier): - for ver in libs: - if ( - ver.group == match.group - and ver.artifact == match.artifact - and ver.classifier == match.classifier - ): - if ver.version == match.version: - # Everything is matched perfectly - this one will be ignored - return True - elif pversion.parse(ver.version) > pversion.parse(match.version): - return True - else: - # Otherwise it did not match - new version is higher and this is an upgrade - return False - # No match found in the set - we need to keep this - return False - - -def version_from_profile( - profile: ForgeInstallerProfile, version: ForgeVersion -) -> MetaVersion: - v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - mc_version = profile.install.minecraft - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] - v.main_class = profile.version_info.main_class - v.release_time = profile.version_info.time - - args = profile.version_info.minecraft_arguments - tweakers = [] - expression = re.compile(r"--tweakClass ([a-zA-Z0-9.]+)") - match = expression.search(args) - while match is not None: - tweakers.append(match.group(1)) - args = args[: match.start()] + args[match.end() :] - match = expression.search(args) - if len(tweakers) > 0: - args = args.strip() - v.additional_tweakers = tweakers - # v.minecraftArguments = args - - v.libraries = [] - mc_filter = load_mc_version_filter(mc_version) - for forge_lib in profile.version_info.libraries: - if ( - forge_lib.name.is_lwjgl() - or forge_lib.name.is_log4j() - or should_ignore_artifact(mc_filter, forge_lib.name) - ): - continue - - overridden_name = forge_lib.name - if overridden_name.group == "net.minecraftforge": - if overridden_name.artifact == "minecraftforge": - overridden_name.artifact = "forge" - overridden_name.version = "%s-%s" % ( - mc_version, - overridden_name.version, - ) - - overridden_name.classifier = "universal" - elif overridden_name.artifact == "forge": - overridden_name.classifier = "universal" - - overridden_lib = Library(name=overridden_name) - if forge_lib.url == "http://maven.minecraftforge.net/": - overridden_lib.url = "https://maven.minecraftforge.net/" - else: - overridden_lib.url = forge_lib.url - # if forge_lib.checksums and len(forge_lib.checksums) == 2: - # overridden_lib.mmcHint = "forge-pack-xz" - v.libraries.append(overridden_lib) - - v.order = 5 - return v - - -def version_from_modernized_installer( - installer: MojangVersion, version: ForgeVersion -) -> MetaVersion: - v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - mc_version = version.mc_version - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] - v.main_class = installer.main_class - v.release_time = installer.release_time - - args = installer.minecraft_arguments - tweakers = [] - expression = re.compile("--tweakClass ([a-zA-Z0-9.]+)") - match = expression.search(args) - while match is not None: - tweakers.append(match.group(1)) - args = args[: match.start()] + args[match.end() :] - match = expression.search(args) - if len(tweakers) > 0: - args = args.strip() - v.additional_tweakers = tweakers - # v.minecraftArguments = args - - v.libraries = [] - - mc_filter = load_mc_version_filter(mc_version) - for forge_lib in installer.libraries: - if ( - forge_lib.name.is_lwjgl() - or forge_lib.name.is_log4j() - or should_ignore_artifact(mc_filter, forge_lib.name) - ): - continue - - if forge_lib.name.group == "net.minecraftforge": - if forge_lib.name.artifact == "forge": - overridden_name = forge_lib.name - overridden_name.classifier = "universal" - forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = ( - "https://maven.minecraftforge.net/%s" % overridden_name.path() - ) - forge_lib.name = overridden_name - - elif forge_lib.name.artifact == "minecraftforge": - overridden_name = forge_lib.name - overridden_name.artifact = "forge" - overridden_name.classifier = "universal" - overridden_name.version = "%s-%s" % ( - mc_version, - overridden_name.version, - ) - forge_lib.downloads.artifact.path = overridden_name.path() - forge_lib.downloads.artifact.url = ( - "https://maven.minecraftforge.net/%s" % overridden_name.path() - ) - forge_lib.name = overridden_name - - v.libraries.append(forge_lib) - - v.order = 5 - return v - - -def version_from_legacy(info: ForgeLegacyInfo, version: ForgeVersion) -> MetaVersion: - v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - mc_version = version.mc_version_sane - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] - v.release_time = info.release_time - v.order = 5 - if fml_libs_for_version( - mc_version - ): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING - v.additional_traits = ["legacyFML"] - - classifier = "client" - if "universal" in version.url(): - classifier = "universal" - - main_mod = Library( - name=GradleSpecifier( - "net.minecraftforge", "forge", version.long_version, classifier - ) - ) - main_mod.downloads = MojangLibraryDownloads() - main_mod.downloads.artifact = MojangArtifact( - url=version.url(), sha1=info.sha1, size=info.size - ) - main_mod.downloads.artifact.path = None - v.jar_mods = [main_mod] - return v - - -def version_from_build_system_installer( - installer: MojangVersion, profile: ForgeInstallerProfileV2, version: ForgeVersion -) -> MetaVersion: - v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] - v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" - - # FIXME: Add the size and hash here - v.maven_files = [] - - # load the locally cached installer file info and use it to add the installer entry in the json - info = InstallerInfo.parse_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") - ) - installer_lib = Library( - name=GradleSpecifier( - "net.minecraftforge", "forge", version.long_version, "installer" - ) - ) - installer_lib.downloads = MojangLibraryDownloads() - installer_lib.downloads.artifact = MojangArtifact( - url="https://maven.minecraftforge.net/%s" % (installer_lib.name.path()), - sha1=info.sha1hash, - size=info.size, - ) - v.maven_files.append(installer_lib) - - for forge_lib in profile.libraries: - if forge_lib.name.is_log4j(): - continue - - if ( - forge_lib.name.group == "net.minecraftforge" - and forge_lib.name.artifact == "forge" - and forge_lib.name.classifier == "universal" - ): - forge_lib.downloads.artifact.url = ( - "https://maven.minecraftforge.net/%s" % forge_lib.name.path() - ) - v.maven_files.append(forge_lib) - - v.libraries = [] - - v.libraries.append(FORGEWRAPPER_LIBRARY) - - for forge_lib in installer.libraries: - if forge_lib.name.is_log4j(): - continue - - if forge_lib.name.group == "net.minecraftforge": - if forge_lib.name.artifact == "forge" and not forge_lib.name.classifier: - forge_lib.name.classifier = "launcher" - forge_lib.downloads.artifact.path = forge_lib.name.path() - forge_lib.downloads.artifact.url = ( - "https://maven.minecraftforge.net/%s" % forge_lib.name.path() - ) - forge_lib.name = forge_lib.name - # net.minecraftforge.forge:client doesn't exist??? (49.0.x) - if not len(forge_lib.downloads.artifact.url): - continue - v.libraries.append(forge_lib) - - v.release_time = installer.release_time - v.order = 5 - mc_args = ( - "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " - "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " - "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" - ) - for arg in installer.arguments.game: - mc_args += f" {arg}" - if "--fml.forgeGroup" not in installer.arguments.game: - mc_args += f" --fml.forgeGroup net.minecraftforge" - if "--fml.forgeVersion" not in installer.arguments.game: - mc_args += f" --fml.forgeVersion {version.rawVersion}" - if "--fml.mcVersion" not in installer.arguments.game: - mc_args += f" --fml.mcVersion {version.mc_version}" - v.minecraft_arguments = mc_args - return v - - -def main(): - # load the locally cached version list - remote_versions = DerivedForgeIndex.parse_file( - os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) - ) - recommended_versions = [] - - legacy_info_list = ForgeLegacyInfoList.parse_file( - os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE) - ) - legacy_versions = [ - "1.1", - "1.2.3", - "1.2.4", - "1.2.5", - "1.3.2", - "1.4.1", - "1.4.2", - "1.4.3", - "1.4.4", - "1.4.5", - "1.4.6", - "1.4.7", - "1.5", - "1.5.1", - "1.5.2", - "1.6.1", - "1.6.2", - "1.6.3", - "1.6.4", - "1.7.10", - "1.7.10-pre4", - "1.7.2", - "1.8", - "1.8.8", - "1.8.9", - "1.9", - "1.9.4", - "1.10", - "1.10.2", - "1.11", - "1.11.2", - "1.12", - "1.12.1", - "1.12.2", - ] - - for key, entry in remote_versions.versions.items(): - if entry.mc_version is None: - eprint("Skipping %s with invalid MC version" % key) - continue - - version = ForgeVersion(entry) - - if version.long_version in BAD_VERSIONS: - # Version 1.12.2-14.23.5.2851 is ultra cringe, I can't imagine why you would even spend one second on - # actually adding support for this version. - # It is cringe, because it's installer info is broken af - eprint(f"Skipping bad version {version.long_version}") - continue - - if version.url() is None: - eprint("Skipping %s with no valid files" % key) - continue - eprint("Processing Forge %s" % version.rawVersion) - version_elements = version.rawVersion.split(".") - if len(version_elements) < 1: - eprint("Skipping version %s with not enough version elements" % key) - continue - - major_version_str = version_elements[0] - if not major_version_str.isnumeric(): - eprint( - "Skipping version %s with non-numeric major version %s" - % (key, major_version_str) - ) - continue - - if entry.recommended: - recommended_versions.append(version.rawVersion) - - # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile( - os.path.join( - LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" - ) - ): - eprint( - "Skipping %s with no corresponding Minecraft version %s" - % (key, version.mc_version_sane) - ) - continue - - # Path for new-style build system based installers - installer_version_filepath = os.path.join( - UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" - ) - profile_filepath = os.path.join( - UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" - ) - - eprint(installer_version_filepath) - if os.path.isfile(installer_version_filepath): - installer = MojangVersion.parse_file(installer_version_filepath) - if entry.mc_version in legacy_versions: - v = version_from_modernized_installer(installer, version) - else: - profile = ForgeInstallerProfileV2.parse_file(profile_filepath) - v = version_from_build_system_installer(installer, profile, version) - else: - if version.uses_installer(): - # If we do not have the Forge json, we ignore this version - if not os.path.isfile(profile_filepath): - eprint("Skipping %s with missing profile json" % key) - continue - profile = ForgeInstallerProfile.parse_file(profile_filepath) - v = version_from_profile(profile, version) - else: - # Generate json for legacy here - if version.mc_version_sane == "1.6.1": - continue - build = version.build - if ( - str(build).encode("utf-8").decode("utf8") - not in legacy_info_list.number - ): - eprint( - "Legacy build %d is missing in legacy info. Ignoring." % build - ) - continue - - v = version_from_legacy(legacy_info_list.number[str(build)], version) - - v.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, f"{v.version}.json")) - - recommended_versions.sort() - - print("Recommended versions:", recommended_versions) - - package = MetaPackage( - uid=FORGE_COMPONENT, - name="Forge", - project_url="https://www.minecraftforge.net/forum/", - ) - package.recommended = recommended_versions - package.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, "package.json")) - - -if __name__ == "__main__": - main() diff --git a/generateLiteloader.py b/generateLiteloader.py deleted file mode 100755 index 2fe95fcc42..0000000000 --- a/generateLiteloader.py +++ /dev/null @@ -1,118 +0,0 @@ -import os -from datetime import datetime -from typing import List, Tuple, Dict, Optional - -from meta.common import ensure_component_dir, launcher_path, upstream_path -from meta.common.liteloader import LITELOADER_COMPONENT, VERSIONS_FILE -from meta.common.mojang import MINECRAFT_COMPONENT -from meta.model import MetaVersion, GradleSpecifier, Library, MetaPackage, Dependency -from meta.model.liteloader import LiteloaderIndex, LiteloaderArtefact - -LAUNCHER_DIR = launcher_path() -UPSTREAM_DIR = upstream_path() - -ensure_component_dir(LITELOADER_COMPONENT) - - -def process_artefacts( - mc_version: str, artefacts: Dict[str, LiteloaderArtefact], is_snapshot: bool -) -> Tuple[List[MetaVersion], Optional[MetaVersion]]: - versions: List[MetaVersion] = [] - lookup: Dict[str, MetaVersion] = {} - latest_version = None - latest = None - for x, artefact in artefacts.items(): - if x == "latest": - latest_version = artefact.version - continue - v = MetaVersion( - name="LiteLoader", - uid=LITELOADER_COMPONENT, - version=artefact.version, - requires=[Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)], - release_time=datetime.utcfromtimestamp(int(artefact.timestamp)), - additional_tweakers=[artefact.tweakClass], - main_class="net.minecraft.launchwrapper.Launch", - order=10, - libraries=artefact.libraries, - type="release", - ) - - if is_snapshot: - v.type = "snapshot" - - # hack to make broken liteloader versions work - for lib in v.libraries: - if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.0.3"): - lib.url = "https://repo.maven.apache.org/maven2/" - if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.2"): - lib.url = "http://repo.liteloader.com/" - - liteloader_lib = Library( - name=GradleSpecifier("com.mumfrey", "liteloader", v.version), - url="http://dl.liteloader.com/versions/", - ) - if is_snapshot: - liteloader_lib.mmcHint = "always-stale" - v.libraries.append(liteloader_lib) - - versions.append(v) - lookup[v.version] = v - - if latest_version: - latest = lookup[latest_version] - return versions, latest - - -def process_versions(index: LiteloaderIndex) -> Tuple[List[MetaVersion], List[str]]: - all_versions: List[MetaVersion] = [] - recommended: List[str] = [] - for mcVersion, versionObject in index.versions.items(): - # ignore this for now. It should be a jar mod or something. - if mcVersion == "1.5.2": - continue - - latest_release = None - if versionObject.artefacts: - versions, latest_release = process_artefacts( - mcVersion, versionObject.artefacts.liteloader, False - ) - all_versions.extend(versions) - if versionObject.snapshots: - versions, latest_snapshot = process_artefacts( - mcVersion, versionObject.snapshots.liteloader, True - ) - all_versions.extend(versions) - - if latest_release: - recommended.append(latest_release.version) - - recommended.sort() - - all_versions.sort(key=lambda x: x.release_time, reverse=True) - return all_versions, recommended - - -def main(): - index = LiteloaderIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) - - all_versions, recommended = process_versions(index) - - for version in all_versions: - version.write( - os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, f"{version.version}.json") - ) - - package = MetaPackage( - uid=LITELOADER_COMPONENT, - name="LiteLoader", - description=index.meta.description, - project_url=index.meta.url, - authors=[index.meta.authors], - recommended=recommended, - ) - package.write(os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, "package.json")) - - -if __name__ == "__main__": - main() diff --git a/generateMojang.py b/generateMojang.py deleted file mode 100755 index 65eea73488..0000000000 --- a/generateMojang.py +++ /dev/null @@ -1,583 +0,0 @@ -import copy -import hashlib -import os -from collections import defaultdict, namedtuple -from operator import attrgetter -from pprint import pprint -from packaging import version as pversion -from typing import Optional, List - -from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path -from meta.common.mojang import ( - STATIC_LEGACY_SERVICES_FILE, - VERSION_MANIFEST_FILE, - MINECRAFT_COMPONENT, - LWJGL3_COMPONENT, - LWJGL_COMPONENT, - STATIC_OVERRIDES_FILE, - VERSIONS_DIR, - LIBRARY_PATCHES_FILE, -) -from meta.model import ( - MetaVersion, - Library, - GradleSpecifier, - MojangLibraryDownloads, - MojangArtifact, - Dependency, - MetaPackage, - MojangRules, -) -from meta.model.mojang import ( - LegacyServices, - MojangIndexWrap, - MojangIndex, - MojangVersion, - LegacyOverrideIndex, - LibraryPatches, - SUPPORTED_FEATURES, -) - -APPLY_SPLIT_NATIVES_WORKAROUND = True - -LAUNCHER_DIR = launcher_path() -UPSTREAM_DIR = upstream_path() -STATIC_DIR = static_path() - -ensure_component_dir(MINECRAFT_COMPONENT) -ensure_component_dir(LWJGL_COMPONENT) -ensure_component_dir(LWJGL3_COMPONENT) - - -def map_log4j_artifact(version): - x = pversion.parse(version) - if x <= pversion.parse("2.0"): - return "2.0-beta9-fixed", "https://files.prismlauncher.org/maven/%s" - if x <= pversion.parse("2.17.1"): - return ( - "2.17.1", - "https://repo1.maven.org/maven2/%s", - ) # This is the only version that's patched (as of 2022/02/19) - return None, None - - -LOG4J_HASHES = { - "2.0-beta9-fixed": { - "log4j-api": { - "sha1": "b61eaf2e64d8b0277e188262a8b771bbfa1502b3", - "size": 107347, - }, - "log4j-core": { - "sha1": "677991ea2d7426f76309a73739cecf609679492c", - "size": 677588, - }, - }, - "2.17.1": { - "log4j-api": { - "sha1": "d771af8e336e372fb5399c99edabe0919aeaf5b2", - "size": 301872, - }, - "log4j-core": { - "sha1": "779f60f3844dadc3ef597976fcb1e5127b1f343d", - "size": 1790452, - }, - "log4j-slf4j18-impl": { - "sha1": "ca499d751f4ddd8afb016ef698c30be0da1d09f7", - "size": 21268, - }, - }, -} - -# We want versions that contain natives for all platforms. If there are multiple, pick the latest one -# LWJGL versions we want -PASS_VARIANTS = [ - # TODO: needs arm64 for Linux? - "8a9b08f11271eb4de3b50e5d069949500b2c7bc1", # 3.3.3 (2024-04-03 11:49:39+00:00) - "765b4ab443051d286bdbb1c19cd7dc86b0792dce", # 3.3.2 (2024-01-17 13:19:20+00:00) - "54c4fb1d6a96ac3007c947bf310c8bcf94a862be", # 3.3.1 (2023-04-20 11:55:19+00:00) split natives, with WoA natives - "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) will be patched, missing tinyfd - "235fc413bc4c76b269c207f7bca6464f1e1f1d80", # 3.2.1 (2019-02-13 16:12:08+00:00) - "deb1a436d806413207350735a00e04b54d113916", # 3.1.6 (2018-10-18 14:46:12+00:00) - "3e47f0f742fb759401754769fa59c508fd8fda75", # 3.1.2 (2018-06-21 12:57:11+00:00) - "a3f254df5a63a0a1635755733022029e8cfae1b3", # 2.9.4-nightly-20150209 (2016-12-20 14:05:34+00:00) - "879be09c0bd0d4bafc2ea4ea3d2ab8607a0d976c", # 2.9.3 (2015-01-30 11:58:24+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) - "27dcadcba29a1a7127880ca1a77efa9ece866f24", # 2.9.0 (2013-09-06 12:31:58+00:00) -] - -# LWJGL versions we def. don't want! -BAD_VARIANTS = [ - "79bde9e46e9ad9accebda11e8293ed08d80dbdc3", # 3.3.2 (2023-08-30 11:24:35+00:00) does not have lwjgl-freetype - "8836c419f90f69a278b97d945a34af165c24ff60", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, with workaround, replaced by 23w26a - "3c624b94c06dbc4abae08fe6156d74abe4a2cca5", # 3.3.1 (2022-05-04 14:41:35+00:00) we already have a nice 3.3.1 - "e1106ca765798218323b7a6d7528050260ea9d88", # 3.3.1 (2022-05-04 14:41:35+00:00) doesn't use split natives - "90b3d9ca01058286c033b6b7ae7f6dc370a04015", # 3.2.2 (2022-03-31 14:53:25+00:00) only linux, windows - "d986df9598fa2bcf4a5baab5edf044548e66d011", # 3.2.2 (2021-12-10 03:36:38+00:00) only linux, windows - "4b73fccb9e5264c2068bdbc26f9651429abbf21a", # 3.2.2 (2021-08-25 14:41:57+00:00) only linux, windows - "090cec3577ecfe438b890b2a9410ea07aa725e16", # 3.2.2 (2021-04-07 14:04:09+00:00) only linux, windows - "ab463e9ebc6a36abf22f2aa27b219dd372ff5069", # 3.2.2 (2019-08-13 07:33:42+00:00) only linux, windows - "51d8ff5a7efc949b4ad2088930e151d6b88ba616", # 3.2.2 (2019-07-19 09:25:47+00:00) only linux, windows - "854649a5bd1455b89117593ae82ff90c8132cacf", # 3.2.1 (2019-04-18 11:05:19+00:00) only osx, windows - "89fcb489261b05f622e8052fe0b588b0cfe49c24", # 3.1.6 (2019-04-18 11:05:19+00:00) only linux - "f04052162b50fa1433f67e1a90bc79466c4ab776", # 2.9.0 (2013-10-21 16:34:47+00:00) only linux, windows - "6442fc475f501fbd0fc4244fd1c38c02d9ebaf7e", # 2.9.0 (2011-03-30 22:00:00+00:00) fine but newer variant available -] - - -def add_or_get_bucket(buckets, rules: Optional[MojangRules]) -> MetaVersion: - rule_hash = None - if rules: - rule_hash = hash(rules.json()) - - if rule_hash in buckets: - bucket = buckets[rule_hash] - else: - bucket = MetaVersion(name="LWJGL", version="undetermined", uid=LWJGL_COMPONENT) - bucket.type = "release" - buckets[rule_hash] = bucket - return bucket - - -def hash_lwjgl_version(lwjgl: MetaVersion): - 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): - return library.name - - -LWJGLEntry = namedtuple("LWJGLEntry", ("version", "sha1")) - -lwjglVersionVariants = defaultdict(list) - - -def add_lwjgl_version(variants, lwjgl): - lwjgl_copy = copy.deepcopy(lwjgl) - libraries = list(lwjgl_copy.libraries) - libraries.sort(key=sort_libs_by_name) - lwjgl_copy.libraries = libraries - - version = lwjgl_copy.version - current_hash = hash_lwjgl_version(lwjgl_copy) - found = False - for variant in variants[version]: - existing_hash = variant.sha1 - if current_hash == existing_hash: - found = True - break - if not found: - print("!!! New variant for LWJGL version %s" % version) - variants[version].append(LWJGLEntry(version=lwjgl_copy, sha1=current_hash)) - - -def remove_paths_from_lib(lib): - if lib.downloads.artifact: - lib.downloads.artifact.path = None - if lib.downloads.classifiers: - for key, value in lib.downloads.classifiers.items(): - value.path = None - - -def adapt_new_style_arguments(arguments): - foo = [] - # we ignore the jvm arguments entirely. - # grab the strings, log the complex stuff - for arg in arguments.game: - if isinstance(arg, str): - if arg == "--clientId": - continue - if arg == "${clientid}": - continue - if arg == "--xuid": - continue - if arg == "${auth_xuid}": - continue - foo.append(arg) - else: - print("!!! Unrecognized structure in Minecraft game arguments:") - pprint(arg) - return " ".join(foo) - - -def adapt_new_style_arguments_to_traits(arguments): - foo = [] - # we ignore the jvm arguments entirely. - # grab the object, log the errors - for arg in arguments.game: - if isinstance(arg, dict): - for rule in arg["rules"]: - for k, v in rule["features"].items(): - if rule["action"] == "allow" and v and k in SUPPORTED_FEATURES: - foo.append(f"feature:{k}") - return foo - - -def is_macos_only(rules: Optional[MojangRules]): - 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": - allows_osx = True - if rule.action == "allow" and not rule.os: - allows_all = True - if allows_osx and not allows_all: - return True - return False - - -def patch_library(lib: Library, patches: LibraryPatches) -> List[Library]: - to_patch = [lib] - - new_libraries = [] - while to_patch: - target = to_patch.pop(0) - - for patch in patches: - if patch.applies(target): - if patch.override: - target.merge(patch.override) - - if patch.additionalLibraries: - additional_copy = copy.deepcopy(patch.additionalLibraries) - new_libraries += list(dict.fromkeys(additional_copy)) - if patch.patchAdditionalLibraries: - to_patch += additional_copy - - return new_libraries - - -def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): - lwjgl_version = lwjgl_variant.version - v = copy.deepcopy(lwjgl_variant) - - new_libraries = [] - for lib in v.libraries: - new_libraries += patch_library(lib, patches) - v.libraries += list(dict.fromkeys(new_libraries)) - - if lwjgl_version[0] == "2": - filename = os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") - - v.name = "LWJGL 2" - v.uid = LWJGL_COMPONENT - v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] - elif lwjgl_version[0] == "3": - filename = os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") - - v.name = "LWJGL 3" - v.uid = LWJGL3_COMPONENT - v.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 - filtered_libraries = list( - filter(lambda l: l.name.artifact not in ["jutils", "jinput"], v.libraries) - ) - v.libraries = filtered_libraries - else: - raise Exception("LWJGL version not recognized: %s" % v.version) - - v.volatile = True - v.order = -1 - good = True - for lib in v.libraries: - # skip libraries without natives or that we patched - if not lib.natives or lib in new_libraries: - continue - checked_dict = {"linux", "windows", "osx"} - if not checked_dict.issubset(lib.natives.keys()): - print("Missing system classifier!", v.version, lib.name, lib.natives.keys()) - good = False - break - if lib.downloads: - for entry in checked_dict: - baked_entry = lib.natives[entry] - if baked_entry not in lib.downloads.classifiers: - print( - "Missing download for classifier!", - v.version, - lib.name, - baked_entry, - lib.downloads.classifiers.keys(), - ) - good = False - break - if good: - v.write(filename) - else: - print("Skipped LWJGL", v.version) - - -def lib_is_split_native(lib: Library) -> bool: - if lib.name.classifier and lib.name.classifier.startswith("natives-"): - return True - return False - - -def version_has_split_natives(v: MojangVersion) -> bool: - for lib in v.libraries: - if lib_is_split_native(lib): - return True - return False - - -def main(): - # get the local version list - override_index = LegacyOverrideIndex.parse_file( - os.path.join(STATIC_DIR, STATIC_OVERRIDES_FILE) - ) - legacy_services = LegacyServices.parse_file( - os.path.join(STATIC_DIR, STATIC_LEGACY_SERVICES_FILE) - ) - library_patches = LibraryPatches.parse_file( - os.path.join(STATIC_DIR, LIBRARY_PATCHES_FILE) - ) - - found_any_lwjgl3 = False - - 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) - mojang_version = MojangVersion.parse_file(input_file) - v = mojang_version.to_meta_version( - "Minecraft", MINECRAFT_COMPONENT, mojang_version.id - ) - - libs_minecraft = [] - new_libs_minecraft = [] - is_lwjgl_3 = False - has_split_natives = version_has_split_natives(v) - buckets = {} - - for lib in v.libraries: - specifier = lib.name - - # generic fixes - remove_paths_from_lib(lib) - - if APPLY_SPLIT_NATIVES_WORKAROUND and lib_is_split_native(lib): - # merge classifier into artifact name to workaround bug in launcher - specifier.artifact += f"-{specifier.classifier}" - specifier.classifier = None - - if specifier.is_lwjgl(): - if has_split_natives: # implies lwjgl3 - bucket = add_or_get_bucket(buckets, None) - is_lwjgl_3 = True - found_any_lwjgl3 = True - bucket.version = specifier.version - if not bucket.libraries: - bucket.libraries = [] - bucket.libraries.append(lib) - bucket.release_time = v.release_time - else: - rules = None - if lib.rules: - rules = lib.rules - lib.rules = None - if is_macos_only(rules): - print( - "Candidate library ", - specifier, - " is only for macOS and is therefore ignored.", - ) - continue - 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": - is_lwjgl_3 = True - found_any_lwjgl3 = True - bucket.version = specifier.version - if not bucket.libraries: - bucket.libraries = [] - bucket.libraries.append(lib) - bucket.release_time = v.release_time - # FIXME: workaround for insane log4j nonsense from December 2021. Probably needs adjustment. - elif lib.name.is_log4j(): - version_override, maven_override = map_log4j_artifact(lib.name.version) - - if version_override and maven_override: - if version_override not in LOG4J_HASHES: - raise Exception( - "ERROR: unhandled log4j version (overriden) %s!" - % version_override - ) - - if lib.name.artifact not in LOG4J_HASHES[version_override]: - raise Exception( - "ERROR: unhandled log4j artifact %s!" % lib.name.artifact - ) - - replacement_name = GradleSpecifier( - "org.apache.logging.log4j", lib.name.artifact, version_override - ) - artifact = MojangArtifact( - url=maven_override % (replacement_name.path()), - sha1=LOG4J_HASHES[version_override][lib.name.artifact]["sha1"], - size=LOG4J_HASHES[version_override][lib.name.artifact]["size"], - ) - - libs_minecraft.append( - Library( - name=replacement_name, - downloads=MojangLibraryDownloads(artifact=artifact), - ) - ) - else: - libs_minecraft.append(lib) - else: - new_libs_minecraft += patch_library(lib, library_patches) - libs_minecraft.append(lib) - if len(buckets) == 1: - for key in buckets: - lwjgl = buckets[key] - lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) - add_lwjgl_version(lwjglVersionVariants, lwjgl) - print("Found only candidate LWJGL", lwjgl.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 is None: - continue - lwjgl = buckets[key] - if None in buckets: - lwjgl.libraries = sorted( - lwjgl.libraries + buckets[None].libraries, - key=attrgetter("name"), - ) - else: - lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) - add_lwjgl_version(lwjglVersionVariants, lwjgl) - print("Found candidate LWJGL", lwjgl.version, key) - # remove the common bucket... - if None in buckets: - del buckets[None] - v.libraries = libs_minecraft + list(dict.fromkeys(new_libs_minecraft)) - - if is_lwjgl_3: - lwjgl_dependency = Dependency(uid=LWJGL3_COMPONENT) - else: - lwjgl_dependency = Dependency(uid=LWJGL_COMPONENT) - if len(buckets) == 1: - suggested_version = next(iter(buckets.values())).version - if is_lwjgl_3: - lwjgl_dependency.suggests = suggested_version - else: - lwjgl_dependency.suggests = "2.9.4-nightly-20150209" - else: - bad_versions = {"3.1.6", "3.2.1"} - our_versions = set() - - for lwjgl in iter(buckets.values()): - our_versions = our_versions.union({lwjgl.version}) - - if our_versions == bad_versions: - print("Found broken 3.1.6/3.2.1 combo, forcing LWJGL to 3.2.1") - suggested_version = "3.2.1" - lwjgl_dependency.suggests = suggested_version - else: - raise Exception( - "ERROR: cannot determine single suggested LWJGL version in %s" - % mojang_version.id - ) - - # if it uses LWJGL 3, add the trait that enables starting on first thread on macOS - if is_lwjgl_3: - if not v.additional_traits: - v.additional_traits = [] - v.additional_traits.append("FirstThreadOnMacOS") - v.requires = [lwjgl_dependency] - v.order = -2 - # process 1.13 arguments into previous version - if not mojang_version.minecraft_arguments and mojang_version.arguments: - v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) - if not v.additional_traits: - v.additional_traits = [] - v.additional_traits.extend( - adapt_new_style_arguments_to_traits(mojang_version.arguments) - ) - out_filename = os.path.join( - LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{v.version}.json" - ) - if v.version in override_index.versions: - override = override_index.versions[v.version] - override.apply_onto_meta_version(v) - if v.version in legacy_services: - if v.additional_traits == None: - v.additional_traits = [] - v.additional_traits.append("legacyServices") - v.write(out_filename) - - for lwjglVersionVariant in lwjglVersionVariants: - decided_variant = None - passed_variants = 0 - unknown_variants = 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) - decided_variant = variant - passed_variants += 1 - continue - # print natives classifiers to decide which variant to use - n = [ - x.natives.keys() - for x in variant.version.libraries - if x.natives is not None - ] - print(n) - - print( - f' "{variant.sha1}", # {lwjglVersionVariant} ({variant.version.release_time})' - ) - unknown_variants += 1 - print("") - - if decided_variant and passed_variants == 1 and unknown_variants == 0: - process_single_variant(decided_variant.version, library_patches) - else: - raise Exception( - "No variant decided for version %s out of %d possible ones and %d unknown ones." - % (lwjglVersionVariant, passed_variants, unknown_variants) - ) - - lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name="LWJGL 2") - lwjgl_package.write(os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, "package.json")) - - if found_any_lwjgl3: - lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name="LWJGL 3") - lwjgl_package.write( - os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, "package.json") - ) - - mojang_index = MojangIndexWrap( - MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE)) - ) - - minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name="Minecraft") - minecraft_package.recommended = [mojang_index.latest.release] - minecraft_package.write( - os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, "package.json") - ) - - -if __name__ == "__main__": - main() diff --git a/generateNeoForge.py b/generateNeoForge.py deleted file mode 100644 index ab0f1df585..0000000000 --- a/generateNeoForge.py +++ /dev/null @@ -1,182 +0,0 @@ -from copy import deepcopy -import os -import re -import sys -from operator import attrgetter -from typing import Collection - -from meta.common import ensure_component_dir, launcher_path, upstream_path, static_path -from meta.common.neoforge import ( - NEOFORGE_COMPONENT, - INSTALLER_MANIFEST_DIR, - VERSION_MANIFEST_DIR, - DERIVED_INDEX_FILE, - INSTALLER_INFO_DIR, -) -from meta.common.forge import FORGEWRAPPER_LIBRARY -from meta.common.mojang import MINECRAFT_COMPONENT -from meta.model import ( - MetaVersion, - Dependency, - Library, - GradleSpecifier, - MojangLibraryDownloads, - MojangArtifact, - MetaPackage, -) -from meta.model.neoforge import ( - NeoForgeVersion, - NeoForgeInstallerProfileV2, - InstallerInfo, - DerivedNeoForgeIndex, -) -from meta.model.mojang import MojangVersion - -LAUNCHER_DIR = launcher_path() -UPSTREAM_DIR = upstream_path() -STATIC_DIR = static_path() - -ensure_component_dir(NEOFORGE_COMPONENT) - - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - -def version_from_build_system_installer( - installer: MojangVersion, - profile: NeoForgeInstallerProfileV2, - version: NeoForgeVersion, -) -> MetaVersion: - v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] - v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" - - # FIXME: Add the size and hash here - v.maven_files = [] - - # load the locally cached installer file info and use it to add the installer entry in the json - info = InstallerInfo.parse_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") - ) - installer_lib = Library( - name=GradleSpecifier( - "net.neoforged", version.artifact, version.long_version, "installer" - ) - ) - installer_lib.downloads = MojangLibraryDownloads() - installer_lib.downloads.artifact = MojangArtifact( - url="https://maven.neoforged.net/%s" % (installer_lib.name.path()), - sha1=info.sha1hash, - size=info.size, - ) - v.maven_files.append(installer_lib) - - for forge_lib in profile.libraries: - if forge_lib.name.is_log4j(): - continue - - v.maven_files.append(forge_lib) - - v.libraries = [] - - v.libraries.append(FORGEWRAPPER_LIBRARY) - - for forge_lib in installer.libraries: - if forge_lib.name.is_log4j(): - continue - - v.libraries.append(forge_lib) - - v.release_time = installer.release_time - v.order = 5 - mc_args = ( - "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " - "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " - "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" - ) - for arg in installer.arguments.game: - mc_args += f" {arg}" - v.minecraft_arguments = mc_args - return v - - -def main(): - # load the locally cached version list - remote_versions = DerivedNeoForgeIndex.parse_file( - os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) - ) - recommended_versions = [] - - for key, entry in remote_versions.versions.items(): - if entry.mc_version is None: - eprint("Skipping %s with invalid MC version" % key) - continue - - version = NeoForgeVersion(entry) - - if version.url() is None: - eprint("Skipping %s with no valid files" % key) - continue - eprint("Processing Forge %s" % version.rawVersion) - version_elements = version.rawVersion.split(".") - if len(version_elements) < 1: - eprint("Skipping version %s with not enough version elements" % key) - continue - - major_version_str = version_elements[0] - if not major_version_str.isnumeric(): - eprint( - "Skipping version %s with non-numeric major version %s" - % (key, major_version_str) - ) - continue - - if entry.recommended: - recommended_versions.append(version.rawVersion) - - # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile( - os.path.join( - LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" - ) - ): - eprint( - "Skipping %s with no corresponding Minecraft version %s" - % (key, version.mc_version_sane) - ) - continue - - # Path for new-style build system based installers - installer_version_filepath = os.path.join( - UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" - ) - profile_filepath = os.path.join( - UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" - ) - - eprint(installer_version_filepath) - assert os.path.isfile( - installer_version_filepath - ), f"version {installer_version_filepath} does not have installer version manifest" - installer = MojangVersion.parse_file(installer_version_filepath) - profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) - v = version_from_build_system_installer(installer, profile, version) - - v.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, f"{v.version}.json")) - - recommended_versions.sort() - - print("Recommended versions:", recommended_versions) - - package = MetaPackage( - uid=NEOFORGE_COMPONENT, - name="NeoForge", - project_url="https://neoforged.net", - ) - package.recommended = recommended_versions - package.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, "package.json")) - - -if __name__ == "__main__": - main() diff --git a/generateQuilt.py b/generateQuilt.py deleted file mode 100755 index ccf2797380..0000000000 --- a/generateQuilt.py +++ /dev/null @@ -1,161 +0,0 @@ -import json -import os - -from meta.common import ( - ensure_component_dir, - launcher_path, - upstream_path, - transform_maven_key, -) -from meta.common.quilt import ( - JARS_DIR, - INSTALLER_INFO_DIR, - META_DIR, - INTERMEDIARY_COMPONENT, - LOADER_COMPONENT, - USE_QUILT_MAPPINGS, - DISABLE_BEACON_ARG, - DISABLE_BEACON_VERSIONS, -) -from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier -from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses - -LAUNCHER_DIR = launcher_path() -UPSTREAM_DIR = upstream_path() - -ensure_component_dir(LOADER_COMPONENT) -ensure_component_dir(INTERMEDIARY_COMPONENT) - - -def load_jar_info(artifact_key) -> FabricJarInfo: - return FabricJarInfo.parse_file( - os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") - ) - - -def load_installer_info(version) -> FabricInstallerDataV1: - return FabricInstallerDataV1.parse_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") - ) - - -def process_loader_version(entry) -> (MetaVersion, bool): - should_recommend = ( - "-" not in entry["version"] - ) # Don't recommend pre releases as per SemVer - - jar_info = load_jar_info(transform_maven_key(entry["maven"])) - installer_info = load_installer_info(entry["version"]) - - v = MetaVersion(name="Quilt Loader", uid=LOADER_COMPONENT, version=entry["version"]) - v.release_time = jar_info.release_time - v.requires = [Dependency(uid=INTERMEDIARY_COMPONENT)] - v.order = 10 - v.type = "release" - if isinstance(installer_info.main_class, FabricMainClasses): - v.main_class = installer_info.main_class.client - else: - v.main_class = installer_info.main_class - v.libraries = [] - v.libraries.extend(installer_info.libraries.common) - v.libraries.extend(installer_info.libraries.client) - loader_lib = Library( - name=GradleSpecifier.from_string(entry["maven"]), - url="https://maven.quiltmc.org/repository/release", - ) - v.libraries.append(loader_lib) - - if entry["version"] in DISABLE_BEACON_VERSIONS: - if not v.additional_jvm_args: - v.additional_jvm_args = [] - v.additional_jvm_args.append(DISABLE_BEACON_ARG) - - return v, should_recommend - - -def process_intermediary_version(entry) -> MetaVersion: - jar_info = load_jar_info(transform_maven_key(entry["maven"])) - - v = MetaVersion( - name="Quilt Intermediary Mappings", - uid=INTERMEDIARY_COMPONENT, - version=entry["version"], - ) - v.release_time = jar_info.release_time - v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] - v.order = 11 - v.type = "release" - v.libraries = [] - v.volatile = True - intermediary_lib = Library( - name=GradleSpecifier.from_string(entry["maven"]), - url="https://maven.quiltmc.org/repository/release", - ) - v.libraries.append(intermediary_lib) - return v - - -def main(): - recommended_loader_versions = [] - recommended_intermediary_versions = [] - - with open( - os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" - ) as f: - loader_version_index = json.load(f) - for entry in loader_version_index: - version = entry["version"] - print(f"Processing loader {version}") - - v, should_recommend = process_loader_version(entry) - - if ( - not recommended_loader_versions and should_recommend - ): # newest stable loader is recommended - recommended_loader_versions.append(version) - - v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) - - if USE_QUILT_MAPPINGS: - with open( - os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), "r", encoding="utf-8" - ) as f: - intermediary_version_index = json.load(f) - for entry in intermediary_version_index: - version = entry["version"] - print(f"Processing intermediary {version}") - - v = process_intermediary_version(entry) - - recommended_intermediary_versions.append( - version - ) # all intermediaries are recommended - - v.write( - os.path.join( - LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json" - ) - ) - - package = MetaPackage(uid=LOADER_COMPONENT, name="Quilt Loader") - package.recommended = recommended_loader_versions - package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." - package.project_url = "https://quiltmc.org/" - package.authors = ["Quilt Project"] - package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) - - if USE_QUILT_MAPPINGS: - package = MetaPackage( - uid=INTERMEDIARY_COMPONENT, name="Quilt Intermediary Mappings" - ) - package.recommended = recommended_intermediary_versions - package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." - package.project_url = "https://quiltmc.org/" - package.authors = ["Quilt Project"] - package.write( - os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json") - ) - - -if __name__ == "__main__": - main() diff --git a/index.py b/index.py deleted file mode 100755 index 23dc2336ea..0000000000 --- a/index.py +++ /dev/null @@ -1,78 +0,0 @@ -import hashlib -import os -from operator import attrgetter - -from meta.common import launcher_path -from meta.model import MetaVersion, MetaPackage -from meta.model.index import ( - MetaPackageIndex, - MetaVersionIndex, - MetaVersionIndexEntry, - MetaPackageIndexEntry, -) - -LAUNCHER_DIR = launcher_path() - - -# take the hash type (like hashlib.md5) and filename, return hex string of hash -def hash_file(hash_fn, file_name): - hash_instance = hash_fn() - with open(file_name, "rb") as f: - for chunk in iter(lambda: f.read(4096), b""): - hash_instance.update(chunk) - return hash_instance.hexdigest() - - -# ignore these files when indexing versions -ignore = {"index.json", "package.json", ".git", ".github"} - -# initialize output structures - package list level -packages = MetaPackageIndex() - -# walk through all the package folders -for package in sorted(os.listdir(LAUNCHER_DIR)): - if package in ignore: - continue - - sharedData = MetaPackage.parse_file( - os.path.join(LAUNCHER_DIR, package, "package.json") - ) - recommendedVersions = set() - if sharedData.recommended: - recommendedVersions = set(sharedData.recommended) - - # initialize output structures - version list level - versionList = MetaVersionIndex(uid=package, name=sharedData.name) - - # walk through all the versions of the package - for filename in os.listdir(LAUNCHER_DIR + "/%s" % package): - if filename in ignore: - continue - # parse and hash the version file - filepath = LAUNCHER_DIR + "/%s/%s" % (package, filename) - filehash = hash_file(hashlib.sha256, filepath) - versionFile = MetaVersion.parse_file(filepath) - is_recommended = versionFile.version in recommendedVersions - - versionEntry = MetaVersionIndexEntry.from_meta_version( - versionFile, is_recommended, filehash - ) - - versionList.versions.append(versionEntry) - - # sort the versions in descending order by time of release - versionList.versions = sorted( - versionList.versions, key=attrgetter("release_time"), reverse=True - ) - - # write the version index for the package - outFilePath = LAUNCHER_DIR + "/%s/index.json" % package - versionList.write(outFilePath) - - # insert entry into the package index - packageEntry = MetaPackageIndexEntry( - uid=package, name=sharedData.name, sha256=hash_file(hashlib.sha256, outFilePath) - ) - packages.packages.append(packageEntry) - -packages.write(os.path.join(LAUNCHER_DIR, "index.json")) diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 454a2cfeb8..9e623bdca8 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -1,4 +1,5 @@ import os +import os.path import datetime from urllib.parse import urlparse @@ -16,24 +17,24 @@ def serialize_datetime(dt: datetime.datetime): return dt.isoformat() +def cache_path(): + if "META_CACHE_DIR" in os.environ: + return os.environ["META_CACHE_DIR"] + return "cache" + + def launcher_path(): - if "LAUNCHER_DIR" in os.environ: - return os.environ["LAUNCHER_DIR"] + if "META_LAUNCHER_DIR" in os.environ: + return os.environ["META_LAUNCHER_DIR"] return "launcher" def upstream_path(): - if "UPSTREAM_DIR" in os.environ: - return os.environ["UPSTREAM_DIR"] + if "META_UPSTREAM_DIR" in os.environ: + return os.environ["META_UPSTREAM_DIR"] return "upstream" -def static_path(): - if "STATIC_DIR" in os.environ: - return os.environ["STATIC_DIR"] - return "static" - - def ensure_upstream_dir(path): path = os.path.join(upstream_path(), path) if not os.path.exists(path): @@ -78,7 +79,7 @@ def merge_dict(base: dict, overlay: dict): def default_session(): - forever_cache = FileCache("caches/http_cache", forever=True) + forever_cache = FileCache(os.path.join(cache_path(), "http_cache"), forever=True) sess = CacheControl(requests.Session(), forever_cache) sess.headers.update({"User-Agent": "PrismLauncherMeta/1.0"}) diff --git a/meta/common/forge.py b/meta/common/forge.py index 4fccc7dcb6..25be5a9949 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -1,4 +1,4 @@ -from os.path import join +from os.path import join, dirname from ..model import GradleSpecifier, make_launcher_library @@ -10,8 +10,7 @@ INSTALLER_MANIFEST_DIR = join(BASE_DIR, "installer_manifests") VERSION_MANIFEST_DIR = join(BASE_DIR, "version_manifests") FILE_MANIFEST_DIR = join(BASE_DIR, "files_manifests") DERIVED_INDEX_FILE = join(BASE_DIR, "derived_index.json") - -STATIC_LEGACYINFO_FILE = join(BASE_DIR, "forge-legacyinfo.json") +LEGACYINFO_FILE = join(BASE_DIR, "legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json new file mode 100644 index 0000000000..74d4d26c4b --- /dev/null +++ b/meta/common/mojang-library-patches.json @@ -0,0 +1,2879 @@ +[ + { + "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.2/3.3.3", + "match": [ + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.2", + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.3" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + }, + { + "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.2/3.3.3", + "match": [ + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.2", + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.3" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + }, + { + "_comment": "Add missing tinyfd to the broken LWJGL 3.2.2 variant", + "match": [ + "org.lwjgl:lwjgl:3.2.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" + }, + { + "downloads": { + "artifact": { + "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", + "size": 7092, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" + }, + "classifiers": { + "natives-linux": { + "sha1": "39e35b161c130635d9c8918ce04e887a30c5b687", + "size": 38804, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" + }, + "natives-macos": { + "sha1": "46d0798228b8a28e857a2a0f02310fd6ba2a4eab", + "size": 42136, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar" + }, + "natives-windows": { + "sha1": "e9115958773644e863332a6a06488d26f9e1fc9f", + "size": 208314, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", + "natives": { + "linux": "natives-linux", + "osx": "natives-macos", + "windows": "natives-windows" + } + } + ], + "patchAdditionalLibraries": true + }, + { + "_comment": "Add additional library just for osx-arm64. No override needed", + "match": [ + "ca.weblite:java-objc-bridge:1.0.0" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "369a83621e3c65496348491e533cb97fe5f2f37d", + "size": 91947, + "url": "https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar" + } + }, + "name": "ca.weblite:java-objc-bridge:1.1.0-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add additional classifiers for jinput-platform", + "match": [ + "net.java.jinput:jinput-platform:2.0.5" + ], + "override": { + "downloads": { + "classifiers": { + "natives-osx-arm64": { + "sha1": "5189eb40db3087fb11ca063b68fa4f4c20b199dd", + "size": 10031, + "url": "https://github.com/r58Playz/jinput-m1/raw/main/plugins/OSX/bin/jinput-platform-2.0.5.jar" + }, + "natives-linux-arm64": { + "sha1": "42b388ccb7c63cec4e9f24f4dddef33325f8b212", + "size": 10932, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" + }, + "natives-linux-arm32": { + "sha1": "f3c455b71c5146acb5f8a9513247fc06db182fd5", + "size": 4521, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" + } + } + }, + "natives": { + "linux-arm64": "natives-linux-arm64", + "linux-arm32": "natives-linux-arm32", + "osx-arm64": "natives-osx-arm64" + } + } + }, + { + "_comment": "Use a newer version on osx-arm64", + "match": [ + "com.mojang:text2speech:1.0.10", + "com.mojang:text2speech:1.5", + "com.mojang:text2speech:1.6", + "com.mojang:text2speech:1.7", + "com.mojang:text2speech:1.10.1", + "com.mojang:text2speech:1.10.3", + "com.mojang:text2speech:1.11.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f378f889797edd7df8d32272c06ca80a1b6b0f58", + "size": 13164, + "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar" + } + }, + "name": "com.mojang:text2speech:1.11.3", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl.lwjgl:lwjgl:2.9.3", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl:2.9.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "697517568c68e78ae0b4544145af031c81082dfe", + "size": 1047168, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar" + } + }, + "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl.lwjgl:lwjgl_util:2.9.3", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl_util:2.9.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", + "size": 173887, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar" + } + }, + "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.3", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131120", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131017", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20130708-debug3", + "org.lwjgl.lwjgl:lwjgl-platform:2.9.1" + ], + "override": { + "downloads": { + "classifiers": { + "natives-osx-arm64": { + "sha1": "eff546c0b319d6ffc7a835652124c18089c67f36", + "size": 488316, + "url": "https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" + }, + "natives-linux-arm64": { + "sha1": "63ac7da0f4a4785c7eadc0f8edc1e9dcc4dd08cb", + "size": 579979, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + }, + "natives-linux-arm32": { + "sha1": "fa483e540a9a753a5ffbb23dcf7879a5bf752611", + "size": 475177, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + } + } + }, + "natives": { + "linux-arm64": "natives-linux-arm64", + "linux-arm32": "natives-linux-arm32", + "osx-arm64": "natives-osx-arm64" + } + } + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-glfw:3.2.2", + "org.lwjgl:lwjgl-glfw:3.2.1", + "org.lwjgl:lwjgl-glfw:3.1.6", + "org.lwjgl:lwjgl-glfw:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "074ad243761147df0d060fbefc814614d2ff75cc", + "size": 85072, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", + "size": 108691, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "4265f2fbe3b9d642591165165a17cf406cf7b98e", + "size": 80186, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", + "size": 130128, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", + "size": 130128, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "71d793d0a5a42e3dfe78eb882abc2523a2c6b496", + "size": 129076, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-glfw:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.2.2", + "org.lwjgl:lwjgl-jemalloc:3.2.1", + "org.lwjgl:lwjgl-jemalloc:3.1.6", + "org.lwjgl:lwjgl-jemalloc:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "762d7d80c9cdf3a3f3fc80c8a5f86612255edfe0", + "size": 156343, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc-patched-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman64.2", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", + "size": 33790, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "9163a2a5559ef87bc13ead8fea84417ea3928748", + "size": 134237, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "4fb94224378d3588d52d2beb172f2eeafea2d546", + "size": 36976, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "4fb94224378d3588d52d2beb172f2eeafea2d546", + "size": 36976, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "b0be721188d2e7195798780b1c5fe7eafe8091c1", + "size": 103478, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-jemalloc:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-openal:3.2.2", + "org.lwjgl:lwjgl-openal:3.2.1", + "org.lwjgl:lwjgl-openal:3.1.6", + "org.lwjgl:lwjgl-openal:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "948e415b5b2a2c650c25b377a4a9f443b21ce92e", + "size": 469432, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", + "size": 79582, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "ecbc981fdd996492a1f6334f003ed62e5a8c0cd5", + "size": 398418, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "d48e753d85916fc8a200ccddc709b36e3865cc4e", + "size": 88880, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "d48e753d85916fc8a200ccddc709b36e3865cc4e", + "size": 88880, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "6b80fc0b982a0723b141e88859c42d6f71bd723f", + "size": 346131, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-openal:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-opengl:3.2.2", + "org.lwjgl:lwjgl-opengl:3.2.1", + "org.lwjgl:lwjgl-opengl:3.1.6", + "org.lwjgl:lwjgl-opengl:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "bd40897077bf7d12f562da898b18ac2c68e1f9d7", + "size": 56109, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", + "size": 937609, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "3af5599c74dd76dd8dbb567b3f9b4963a6abeed5", + "size": 56388, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "962c2a8d2a8cdd3b89de3d78d766ab5e2133c2f4", + "size": 929233, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "962c2a8d2a8cdd3b89de3d78d766ab5e2133c2f4", + "size": 929233, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "bb575058e0372f515587b5d2d04ff7db185f3ffe", + "size": 41667, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-opengl:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-stb:3.2.2", + "org.lwjgl:lwjgl-stb:3.2.1", + "org.lwjgl:lwjgl-stb:3.1.6", + "org.lwjgl:lwjgl-stb:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "077efa7d7ea41b32df5c6078e912e724cccd06db", + "size": 202038, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", + "size": 104075, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "ec9d70aaebd0ff76dfeecf8f00b56118bf3706b1", + "size": 149387, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "703e4b533e2542560e9f94d6d8bd148be1c1d572", + "size": 113273, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "703e4b533e2542560e9f94d6d8bd148be1c1d572", + "size": 113273, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "98f0ad956c754723ef354d50057cc30417ef376a", + "size": 178409, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-stb:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.2.2", + "org.lwjgl:lwjgl-tinyfd:3.2.1", + "org.lwjgl:lwjgl-tinyfd:3.1.6", + "org.lwjgl:lwjgl-tinyfd:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "37c744ca289b5d7ae155d79e39029488b3254e5b", + "size": 37893, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", + "size": 5571, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "82d16054ada6633297a3108fb6d8bae98800c76f", + "size": 41663, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "1203660b3131cbb8681b17ce6437412545be95e0", + "size": 6802, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "1203660b3131cbb8681b17ce6437412545be95e0", + "size": 6802, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "015b931a2daba8f0c317d84c9d14e8e98ae56e0c", + "size": 41384, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl-tinyfd:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", + "match": [ + "org.lwjgl:lwjgl:3.2.2", + "org.lwjgl:lwjgl:3.2.1", + "org.lwjgl:lwjgl:3.1.6", + "org.lwjgl:lwjgl:3.1.2" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux-arm64" + } + }, + { + "action": "disallow", + "os": { + "name": "linux-arm32" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "360899386df83d6a8407844a94478607af937f97", + "size": 318833, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar" + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "360899386df83d6a8407844a94478607af937f97", + "size": 318833, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar" + }, + "classifiers": { + "natives-linux-arm64": { + "sha1": "612efd57d12b2e48e554858eb35e7e2eb46ebb4c", + "size": 87121, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman64.1", + "natives": { + "linux-arm64": "natives-linux-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", + "size": 318413, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar" + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman32.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", + "size": 318413, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar" + }, + "classifiers": { + "natives-linux-arm32": { + "sha1": "6bd0b37fef777a309936a72dc7f63126e8c79ea5", + "size": 90296, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm32.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.2.2-gman32.1", + "natives": { + "linux-arm32": "natives-linux-arm32" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8e664dd69ad7bbcf2053da23efc7848e39e498db", + "size": 719038, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl.jar" + } + }, + "name": "org.lwjgl:lwjgl:3.3.1-mmachina.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + { + "downloads": { + "artifact": { + "sha1": "8e664dd69ad7bbcf2053da23efc7848e39e498db", + "size": 719038, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl.jar" + }, + "classifiers": { + "natives-osx-arm64": { + "sha1": "984df31fadaab86838877b112e5b4e4f68a00ccf", + "size": 42693, + "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-natives-macos-arm64.jar" + } + } + }, + "name": "org.lwjgl:lwjgl:3.3.1-mmachina.1", + "natives": { + "osx-arm64": "natives-osx-arm64" + }, + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.1", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + }, + { + "_comment": "Only allow osx-arm64 for existing java-objc-bridge:1.1", + "match": [ + "ca.weblite:java-objc-bridge:1.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + }, + { + "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.1", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.1" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "windows-arm64" + } + } + ] + } + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "513eb39b866d0fe131a18d5c517087805433b029", + "size": 112350, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "749be48a9b86ee2c3a2da5fd77511208adcfb33b", + "size": 159993, + "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.3.1/lwjgl-jemalloc-patched-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.1-gman64.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "cf4e303257e82981b8b2e31bba3d7f8f7b8f42b2", + "size": 470743, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1c528fb258a6e63e8fceb4482d8db0f3af10a634", + "size": 57908, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8e8348a1813aad7f30aaf75ea197151ebb7beba9", + "size": 205491, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "964f628b7a82fd909def086c0dd9a4b84bb259ae", + "size": 42654, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b597401014acb7196c76d97e15a6288f54f1f692", + "size": 86308, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "816d935933f2dd743074c4e717cc25b55720f294", + "size": 104027, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "a96a6d6cb3876d7813fcee53c3c24f246aeba3b3", + "size": 136157, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ffbe35d7fa5ec9b7eca136a7c71f24d4025a510b", + "size": 400129, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "e3550fa91097fd56e361b4370fa822220fef3595", + "size": 58474, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b08226bab162c06ae69337d8a1b0ee0a3fdf0b90", + "size": 153889, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d53d331e859217a61298fcbcf8d79137f3df345c", + "size": 48061, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.1", + "match": [ + "org.lwjgl:lwjgl:3.3.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "41a3c1dd15d6b964eb8196dde69720a3e3e5e969", + "size": 82374, + "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "896e7d9b8f60d7273f3d491c69270afc67ece3ce", + "size": 1073374, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "bc49e64bae0f7ff103a312ee8074a34c4eb034c7", + "size": 120168, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "5249f18a9ae20ea86c5816bc3107a888ce7a17d2", + "size": 206402, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "22408980cc579709feaf9acb807992d3ebcf693f", + "size": 590865, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "bb9eb56da6d1d549d6a767218e675e36bc568eb9", + "size": 58627, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "11a380c37b0f03cb46db235e064528f84d736ff7", + "size": 207419, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "93f8c5bc1984963cd79109891fb5a9d1e580373e", + "size": 43381, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8bd89332c90a90e6bc4aa997a25c05b7db02c90a", + "size": 90795, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b7f77ceb951182659fd400437272aa7e96709968", + "size": 924657, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "5907d9a6b7c44fb0612a63bb1cff5992588f65be", + "size": 110067, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "9367437ce192e4d6f5725d53d85520644c0b0d6f", + "size": 177571, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7c82bbc33ef49ee4094b216c940db564b2998224", + "size": 503352, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "821f9a2d1d583c44893f42b96f6977682b48a99b", + "size": 59265, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ca9333da184aade20757151f4615f1e27ca521ae", + "size": 154928, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "807e220913aa0740449ff90d3b3d825cf5f359ed", + "size": 48788, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.2", + "match": [ + "org.lwjgl:lwjgl:3.3.2" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "afcbfaaa46f217e98a6da4208550f71de1f2a225", + "size": 89347, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.2-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "498965aac06c4a0d42df1fbef6bacd05bde7f974", + "size": 1093516, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "492a0f11f85b85899a6568f07511160c1b87cd38", + "size": 122159, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "eff8b86798191192fe2cba2dc2776109f30c239d", + "size": 209315, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ad8f302118a65bb8d615f8a2a680db58fb8f835e", + "size": 592963, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2096f6b94b2d68745d858fbfe53aacf5f0c8074c", + "size": 58625, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ddc177afc2be1ee8d93684b11363b80589a13fe1", + "size": 207418, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2823a8c955c758d0954d282888075019ef99cec7", + "size": 43864, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f35d8b6ffe1ac1e3a5eb1d4e33de80f044ad5fd8", + "size": 91294, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7dd3b1f751571adaf2c4dc882bc675a5d1e796e6", + "size": 942636, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d9af485c32545b37dd5359b163161d42d7534dcf", + "size": 112560, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "109b6931880d02d4e65ced38928a16e41d19873e", + "size": 178324, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "e1702aa09d20359d6cf5cb2999fa7685a785eca7", + "size": 505618, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "dbba17fc5ac0985d14a57c11f9537617d67b9952", + "size": 59263, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1ae28ff044699ff29b0e980ffabd73fba8a664b3", + "size": 154931, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "c2a0a05c82c4b9f69ded0b6ad5f417addea78ce2", + "size": 49495, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.3", + "match": [ + "org.lwjgl:lwjgl:3.3.3" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2075c51a80f0ef0f22ba616ba54007ac2b0debd4", + "size": 89565, + "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.3-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Replace glfw from 3.3.1 with version from 3.3.2 to prevent stack smashing", + "match": [ + "org.lwjgl:lwjgl-glfw-natives-linux:3.3.1" + ], + "override": { + "downloads": { + "artifact": { + "sha1": "0766bb0e8e829598b1c8052fd8173c62af741c52", + "size": 115553, + "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux:3.3.2-lwjgl.1" + } + } +] diff --git a/meta/common/mojang-minecraft-experiments.json b/meta/common/mojang-minecraft-experiments.json new file mode 100644 index 0000000000..94b50c1a60 --- /dev/null +++ b/meta/common/mojang-minecraft-experiments.json @@ -0,0 +1,104 @@ +{ + "experiments": [ + { + "id": "1_19_deep_dark_experimental_snapshot-1", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/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", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8c", + "url": "https://launcher.mojang.com/experiments/combat/ea08f7eb1f96cdc82464e27c0f95d23965083cfb/1_16_combat-6.zip" + }, + { + "id": "1_16_combat-5", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8b", + "url": "https://launcher.mojang.com/experiments/combat/9b2b984d635d373564b50803807225c75d7fd447/1_16_combat-5.zip" + }, + { + "id": "1_16_combat-4", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8", + "url": "https://cdn.discordapp.com/attachments/369990015096455168/947864881028272198/1_16_combat-4.zip" + }, + { + "id": "1_16_combat-3", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7c", + "url": "https://launcher.mojang.com/experiments/combat/2557b99d95588505e988886220779087d7d6b1e9/1_16_combat-3.zip" + }, + { + "id": "1_16_combat-2", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7b", + "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-2.zip" + }, + { + "id": "1_16_combat-1", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7", + "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-1.zip" + }, + { + "id": "1_16_combat-0", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_6", + "url": "https://launcher.mojang.com/experiments/combat/5a8ceec8681ed96ab6ecb9607fb5d19c8a755559/1_16_combat-0.zip" + }, + { + "id": "1_15_combat-6", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_5", + "url": "https://launcher.mojang.com/experiments/combat/52263d42a626b40c947e523128f7a195ec5af76a/1_15_combat-6.zip" + }, + { + "id": "1_15_combat-1", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_4", + "url": "https://launcher.mojang.com/experiments/combat/ac11ea96f3bb2fa2b9b76ab1d20cacb1b1f7ef60/1_15_combat-1.zip" + }, + { + "id": "1_14_combat-3", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_3", + "url": "https://launcher.mojang.com/experiments/combat/0f209c9c84b81c7d4c88b4632155b9ae550beb89/1_14_combat-3.zip" + }, + { + "id": "1_14_combat-0", + "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_2", + "url": "https://launcher.mojang.com/experiments/combat/d164bb6ecc5fca9ac02878c85f11befae61ac1ca/1_14_combat-0.zip" + }, + { + "id": "1_14_combat-212796", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.14.3_-_Combat_Test", + "url": "https://launcher.mojang.com/experiments/combat/610f5c9874ba8926d5ae1bcce647e5f0e6e7c889/1_14_combat-212796.zip" + } + ] +} \ No newline at end of file diff --git a/meta/common/mojang-minecraft-legacy-override.json b/meta/common/mojang-minecraft-legacy-override.json new file mode 100644 index 0000000000..d1d951d05f --- /dev/null +++ b/meta/common/mojang-minecraft-legacy-override.json @@ -0,0 +1,585 @@ +{ + "versions": { + "1.5.2": { + "releaseTime": "2013-04-25T17:45:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.5.1": { + "releaseTime": "2013-03-20T12:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w12~": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.5": { + "releaseTime": "2013-03-07T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w10b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w10a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09c": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w09a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w11a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w07a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w06a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w05b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w05a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w04a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w03a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w02b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w02a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w01b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "13w01a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.7": { + "releaseTime": "2012-12-28T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.6": { + "releaseTime": "2012-12-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w50b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w50a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w49a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.5": { + "releaseTime": "2012-11-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.4": { + "releaseTime": "2012-11-14T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.3": { + "releaseTime": "2012-11-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.2": { + "releaseTime": "2012-10-25T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4.1": { + "releaseTime": "2012-10-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.4": { + "releaseTime": "2012-10-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w42b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w42a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w41b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w41a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w40b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w40a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w39b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w39a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w38b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w38a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w37a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w36a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w34b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w34a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3.2": { + "releaseTime": "2012-08-16T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w32a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3.1": { + "releaseTime": "2012-08-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.3": { + "releaseTime": "2012-07-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30e": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30d": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30c": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w30a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w27a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w26a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w25a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w24a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w23b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w23a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w22a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w21b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w21a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w19a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w18a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w17a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w16a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.5": { + "releaseTime": "2012-03-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.4": { + "releaseTime": "2012-03-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.3": { + "releaseTime": "2012-03-02T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.2": { + "releaseTime": "2012-03-01T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2.1": { + "releaseTime": "2012-03-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w08a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w07a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w07b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w06a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w05b": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w05a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w04a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w03a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.1": { + "releaseTime": "2012-01-12T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "12w01a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w50a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w49a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w48a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "11w47a": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "1.0": { + "releaseTime": "2011-11-18T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre6": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre5": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre4": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre3": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.9-pre1": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8.1": { + "releaseTime": "2011-09-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8": { + "releaseTime": "2011-09-15T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8-pre2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.8-pre1-2": { + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7.3": { + "releaseTime": "2011-07-08T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7.2": { + "releaseTime": "2011-07-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.7": { + "releaseTime": "2011-06-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.6": { + "releaseTime": "2011-05-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.5": { + "releaseTime": "2011-05-28T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.4": { + "releaseTime": "2011-05-26T00:00:04+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.3": { + "releaseTime": "2011-05-26T00:00:03+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.2": { + "releaseTime": "2011-05-26T00:00:02+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6.1": { + "releaseTime": "2011-05-26T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.6": { + "releaseTime": "2011-05-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.5_01": { + "releaseTime": "2011-04-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.5": { + "releaseTime": "2011-04-19T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.4_01": { + "releaseTime": "2011-04-05T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.4": { + "releaseTime": "2011-03-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.3_01": { + "releaseTime": "2011-02-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.3b": { + "releaseTime": "2011-02-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2_02": { + "releaseTime": "2011-01-21T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2_01": { + "releaseTime": "2011-01-14T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.2": { + "releaseTime": "2011-01-13T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.1_02": { + "releaseTime": "2010-12-22T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.1_01": { + "releaseTime": "2010-12-22T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0.2": { + "releaseTime": "2010-12-21T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0_01": { + "releaseTime": "2010-12-20T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "b1.0": { + "releaseTime": "2010-12-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.6": { + "releaseTime": "2010-12-03T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.5": { + "releaseTime": "2010-12-01T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.4_01": { + "releaseTime": "2010-11-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_04": { + "releaseTime": "2010-11-26T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_02": { + "releaseTime": "2010-11-25T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3_01": { + "releaseTime": "2010-11-24T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.3": { + "releaseTime": "2010-11-24T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.2b": { + "releaseTime": "2010-11-10T00:00:01+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.2a": { + "releaseTime": "2010-11-10T00:00:00+02:00", + "+traits": ["legacyLaunch", "texturepacks"] + }, + "a1.2.1_01": { + "releaseTime": "2010-11-05T00:00:01+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.1": { + "releaseTime": "2010-11-05T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0_02": { + "releaseTime": "2010-11-04T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0_01": { + "releaseTime": "2010-10-31T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.2.0": { + "releaseTime": "2010-10-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "a1.1.2_01": { + "releaseTime": "2010-09-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.1.2": { + "releaseTime": "2010-09-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.1.0": { + "releaseTime": "2010-09-13T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.17_04": { + "releaseTime": "2010-08-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.17_02": { + "releaseTime": "2010-08-20T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.16": { + "releaseTime": "2010-08-12T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.15": { + "releaseTime": "2010-08-04T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.14": { + "releaseTime": "2010-07-30T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.11": { + "releaseTime": "2010-07-23T00:00:00+02:00", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.5_01": { + "releaseTime": "2010-07-13T00:00:00+02:00", + "mainClass": "y", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "a1.0.4": { + "releaseTime": "2010-07-09T00:00:00+02:00", + "mainClass": "ax", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "inf-20100618": { + "releaseTime": "2010-06-16T00:00:00+02:00", + "mainClass": "net.minecraft.client.d", + "appletClass": "net.minecraft.client.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"], + "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] + }, + "c0.30_01c": { + "releaseTime": "2009-12-22T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.l", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.13a_03": { + "releaseTime": "2009-05-22T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.c", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.13a": { + "releaseTime": "2009-05-31T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.Minecraft", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "c0.0.11a": { + "releaseTime": "2009-05-17T00:00:00+02:00", + "mainClass": "com.mojang.minecraft.Minecraft", + "appletClass": "com.mojang.minecraft.MinecraftApplet", + "+traits": ["legacyLaunch", "no-texturepacks"] + }, + "rd-161348": { + "releaseTime": "2009-05-16T13:48:00+02:00", + "mainClass": "com.mojang.minecraft.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-160052": { + "releaseTime": "2009-05-16T00:52:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-20090515": { + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-132328": { + "releaseTime": "2009-05-13T23:28:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + }, + "rd-132211": { + "releaseTime": "2009-05-13T22:11:00+02:00", + "mainClass": "com.mojang.rubydung.RubyDung", + "+traits": ["no-texturepacks"] + } + } +} diff --git a/meta/common/mojang-minecraft-legacy-services.json b/meta/common/mojang-minecraft-legacy-services.json new file mode 100644 index 0000000000..420d3f8c74 --- /dev/null +++ b/meta/common/mojang-minecraft-legacy-services.json @@ -0,0 +1,218 @@ +[ + "c0.30_01c", + "inf-20100618", + "a1.0.4", + "a1.0.5_01", + "a1.0.11", + "a1.0.14", + "a1.0.15", + "a1.0.16", + "a1.0.17_02", + "a1.0.17_04", + "a1.1.0", + "a1.1.2", + "a1.1.2_01", + "a1.2.0", + "a1.2.0_01", + "a1.2.0_02", + "a1.2.1", + "a1.2.1_01", + "a1.2.2a", + "a1.2.2b", + "a1.2.3", + "a1.2.3_01", + "a1.2.3_02", + "a1.2.3_04", + "a1.2.4_01", + "a1.2.5", + "a1.2.6", + "b1.0", + "b1.0_01", + "b1.0.2", + "b1.1_01", + "b1.1_02", + "b1.2", + "b1.2_01", + "b1.2_02", + "b1.3b", + "b1.3_01", + "b1.4", + "b1.4_01", + "b1.5", + "b1.5_01", + "b1.6", + "b1.6.1", + "b1.6.2", + "b1.6.3", + "b1.6.4", + "b1.6.5", + "b1.6.6", + "b1.7", + "b1.7.2", + "b1.7.3", + "b1.8-pre1-2", + "b1.8-pre2", + "b1.8", + "b1.8.1", + "b1.9-pre1", + "b1.9-pre2", + "b1.9-pre3", + "b1.9-pre4", + "b1.9-pre5", + "b1.9-pre6", + "1.0", + "11w47a", + "11w48a", + "11w49a", + "11w50a", + "12w01a", + "1.1", + "12w03a", + "12w04a", + "12w05a", + "12w05b", + "12w06a", + "12w07b", + "12w07a", + "12w08a", + "1.2", + "1.2.1", + "1.2.2", + "1.2.3", + "1.2.4", + "1.2.5", + "12w16a", + "12w17a", + "12w18a", + "12w19a", + "12w21a", + "12w21b", + "12w22a", + "12w23a", + "12w23b", + "12w24a", + "12w25a", + "12w26a", + "12w27a", + "12w30a", + "12w30b", + "12w30c", + "12w30d", + "12w30e", + "1.3", + "1.3.1", + "12w32a", + "1.3.2", + "12w34a", + "12w34b", + "12w36a", + "12w37a", + "12w38a", + "12w38b", + "12w39a", + "12w39b", + "12w40a", + "12w40b", + "12w41a", + "12w41b", + "12w42a", + "12w42b", + "1.4", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "12w49a", + "12w50a", + "12w50b", + "1.4.6", + "1.4.7", + "13w01a", + "13w01b", + "13w02a", + "13w02b", + "13w03a", + "13w04a", + "13w05a", + "13w05b", + "13w06a", + "13w07a", + "13w11a", + "13w09a", + "13w09b", + "13w09c", + "13w10a", + "13w10b", + "1.5", + "13w12~", + "1.5.1", + "1.5.2", + "13w17a", + "13w18a", + "13w18b", + "13w18c", + "13w19a", + "13w21a", + "13w21b", + "13w22a", + "13w23a", + "13w23b", + "13w24a", + "13w24b", + "13w25a", + "13w25b", + "13w25c", + "13w26a", + "1.6", + "1.6.1", + "1.6.2", + "13w36a", + "13w36b", + "13w37a", + "1.6.3", + "13w37b", + "1.6.4", + "13w38a", + "13w38b", + "13w38c", + "13w39a", + "13w39b", + "13w41a", + "13w41b", + "13w42a", + "13w42b", + "13w43a", + "1.7", + "1.7.1", + "1.7.2", + "13w47a", + "13w47b", + "13w47c", + "13w47d", + "13w47e", + "13w48a", + "13w48b", + "13w49a", + "1.7.3", + "1.7.4", + "14w02a", + "14w02b", + "14w02c", + "14w03a", + "14w03b", + "14w04a", + "14w04b", + "14w05a", + "14w05b", + "14w06a", + "14w06b", + "14w07a", + "1.7.5", + "14w08a", + "14w10b", + "14w10c", + "1.7.6-pre1", + "1.7.6-pre2", + "14w11a" +] diff --git a/meta/common/mojang-minecraft-old-snapshots.json b/meta/common/mojang-minecraft-old-snapshots.json new file mode 100644 index 0000000000..24ee0ce8b8 --- /dev/null +++ b/meta/common/mojang-minecraft-old-snapshots.json @@ -0,0 +1,604 @@ +{ + "old_snapshots": [ + { + "id": "1_2", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.2", + "url": "https://archive.org/download/Minecraft-JSONs/1.2.json", + "sha1": "a2064011425a5e5befd9dee5eeb4f968ddf5ac77", + "size": 3988919, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_2/minecraft.jar" + }, + { + "id": "11w47a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w47a", + "url": "https://archive.org/download/Minecraft-JSONs/11w47a.json", + "sha1": "4e327918708d22e7443fbadefb9831ca04af4b90", + "size": 2242242, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w47a/minecraft.jar" + }, + { + "id": "11w48a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w48a", + "url": "https://archive.org/download/Minecraft-JSONs/11w48a.json", + "sha1": "fede770abe88a19e844d99dda611a7d18184155a", + "size": 2242604, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w48a/minecraft.jar" + }, + { + "id": "11w49a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w49a", + "url": "https://archive.org/download/Minecraft-JSONs/11w49a.json", + "sha1": "6f92a726e6b8b64f66c7e4d236f983c278d5af54", + "size": 3510866, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w49a/minecraft.jar" + }, + { + "id": "11w50a", + "wiki": "https://minecraft.wiki/w/Java_Edition_11w50a", + "url": "https://archive.org/download/Minecraft-JSONs/11w50a.json", + "sha1": "f4981ba0fee00a16d8dc9ec87bf2c4fdb51e4b7c", + "size": 3509701, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w50a/minecraft.jar" + }, + { + "id": "12w01a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w01a", + "url": "https://archive.org/download/Minecraft-JSONs/12w01a.json", + "sha1": "653a9cf55884b6bc4dcf3c574331e04bd5ad1032", + "size": 3839447, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w01a/minecraft.jar" + }, + { + "id": "12w03a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w03a", + "url": "https://archive.org/download/Minecraft-JSONs/12w03a.json", + "sha1": "e581c7c9dd57cbf73f72b833be5eff6109187df0", + "size": 3875210, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w03a/minecraft.jar" + }, + { + "id": "12w04a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w04a", + "url": "https://archive.org/download/Minecraft-JSONs/12w04a.json", + "sha1": "4911c473e856ec8102b8419eb36d0f54dad029a0", + "size": 3911974, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w04a/minecraft.jar" + }, + { + "id": "12w05a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w05a", + "url": "https://archive.org/download/Minecraft-JSONs/12w05a.json", + "sha1": "28328e67b82564335aa8280095a0716a2eb790de", + "size": 3931639, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05a/minecraft.jar" + }, + { + "id": "12w05b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w05b", + "url": "https://archive.org/download/Minecraft-JSONs/12w05b.json", + "sha1": "75fbc4a39a244d0f1eb842ff8385e992e2b47dd5", + "size": 3931694, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05b/minecraft.jar" + }, + { + "id": "12w06a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w06a", + "url": "https://archive.org/download/Minecraft-JSONs/12w06a.json", + "sha1": "a8403c0d4c0cdb65722d864d9cf42663b8aab08b", + "size": 3934973, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w06a/minecraft.jar" + }, + { + "id": "12w07a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w07a", + "url": "https://archive.org/download/Minecraft-JSONs/12w07a.json", + "sha1": "e7ad115b29612b893972f0817030d993bc56fb7e", + "size": 3956252, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07a/minecraft.jar" + }, + { + "id": "12w07b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w07b", + "url": "https://archive.org/download/Minecraft-JSONs/12w07b.json", + "sha1": "0eea35d588fc2cee5d397472aa3565f48c220217", + "size": 3956323, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07b/minecraft.jar" + }, + { + "id": "12w08a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w08a", + "url": "https://archive.org/download/Minecraft-JSONs/12w08a.json", + "sha1": "db2fcfdd23526b0f381ef2f3f2fd049d36227230", + "size": 3981486, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w08a/minecraft.jar" + }, + { + "id": "12w16a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w16a", + "url": "https://archive.org/download/Minecraft-JSONs/12w16a.json", + "sha1": "6b0a9fe3ac275f79ac6d259f4279752274ec05f8", + "size": 4080437, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w16a/minecraft.jar" + }, + { + "id": "12w17a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w17a", + "url": "https://archive.org/download/Minecraft-JSONs/12w17a.json", + "sha1": "17d41f8a07e054040ba34e523593bdea7f0fb6ba", + "size": 4114768, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w17a/minecraft.jar" + }, + { + "id": "12w18a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w18a", + "url": "https://archive.org/download/Minecraft-JSONs/12w18a.json", + "sha1": "9e9ab992317048bee9158ad9d1e2bc758db2b4af", + "size": 4317820, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w18a/minecraft.zip/bin/minecraft.jar" + }, + { + "id": "12w19a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w19a", + "url": "https://archive.org/download/Minecraft-JSONs/12w19a.json", + "sha1": "474aaac9a8b1dcbf312a5c09c7eae4a6aa401225", + "size": 4343792, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w19a/minecraft.zip/bin/minecraft.jar" + }, + { + "id": "12w21a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w21a", + "url": "https://archive.org/download/Minecraft-JSONs/12w21a.json", + "sha1": "e755423a04b0efde01e035a9d651acadeba0aef9", + "size": 4409586, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21a/minecraft.jar" + }, + { + "id": "12w21b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w21b", + "url": "https://archive.org/download/Minecraft-JSONs/12w21b.json", + "sha1": "84437ded4839b29d34f83e9f3bab07cc48980faf", + "size": 4499708, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21b/minecraft.jar" + }, + { + "id": "12w22a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w22a", + "url": "https://archive.org/download/Minecraft-JSONs/12w22a.json", + "sha1": "3631a714cb465d39f5cb5c18aa23abf38031b359", + "size": 4542344, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w22a/minecraft.jar" + }, + { + "id": "12w23a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w23a", + "url": "https://archive.org/download/Minecraft-JSONs/12w23a.json", + "sha1": "4a5a8e3349ea2e9d67fa4dde6ec68d385bff46f0", + "size": 4543912, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23a/minecraft.jar" + }, + { + "id": "12w23b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w23b", + "url": "https://archive.org/download/Minecraft-JSONs/12w23b.json", + "sha1": "e107667bcbb4443afc160a7eeb8f347acc9826f8", + "size": 4543928, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23b/minecraft.jar" + }, + { + "id": "12w24a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w24a", + "url": "https://archive.org/download/Minecraft-JSONs/12w24a.json", + "sha1": "e479c425ffe6ca3512d97ad0e02a8cd85356bf83", + "size": 4540049, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w24a/minecraft.jar" + }, + { + "id": "12w25a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w25a", + "url": "https://archive.org/download/Minecraft-JSONs/12w25a.json", + "sha1": "eddf53994e40ecc44f582d4b47b9a441844909b6", + "size": 4556548, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w25a/minecraft.jar" + }, + { + "id": "12w26a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w26a", + "url": "https://archive.org/download/Minecraft-JSONs/12w26a.json", + "sha1": "2d1e782a4c4435fe921027ae464a272945cca925", + "size": 4573075, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w26a/minecraft.jar" + }, + { + "id": "12w27a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w27a", + "url": "https://archive.org/download/Minecraft-JSONs/12w27a.json", + "sha1": "5e69b80f9c757bdc8275c1f6ce7e71820fe6d79a", + "size": 4584956, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w27a/minecraft.jar" + }, + { + "id": "12w30a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30a", + "url": "https://archive.org/download/Minecraft-JSONs/12w30a.json", + "sha1": "368215d7fd38ee3e829725e11b3f193d45801128", + "size": 4584574, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30a/minecraft.jar" + }, + { + "id": "12w30b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30b", + "url": "https://archive.org/download/Minecraft-JSONs/12w30b.json", + "sha1": "9d1e450cdb300ec426b50762e031796a8349aa1c", + "size": 4584593, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30b/minecraft.jar" + }, + { + "id": "12w30c", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30c", + "url": "https://archive.org/download/Minecraft-JSONs/12w30c.json", + "sha1": "92817a0c3f3c913ad68bdb082ac1f147db986282", + "size": 4584617, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30c/minecraft.jar" + }, + { + "id": "12w30d", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30d", + "url": "https://archive.org/download/Minecraft-JSONs/12w30d.json", + "sha1": "a5e7508de2d3993cb5222d8e4f8415226745d6ff", + "size": 4585459, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30d/minecraft.jar" + }, + { + "id": "12w30e", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w30e", + "url": "https://archive.org/download/Minecraft-JSONs/12w30e.json", + "sha1": "1a37562cda14028dae15b331bfd36108e617a477", + "size": 4585506, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30e/minecraft.jar" + }, + { + "id": "12w32a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w32a", + "url": "https://archive.org/download/Minecraft-JSONs/12w32a.json", + "sha1": "13183e023c8918ed08c302c2fe1438f61b53d094", + "size": 4628354, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w32a/minecraft.jar" + }, + { + "id": "12w34a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w34a", + "url": "https://archive.org/download/Minecraft-JSONs/12w34a.json", + "sha1": "41769085c020f4651b5b5dd50a6f83be2b000b29", + "size": 4676139, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34a/minecraft.jar" + }, + { + "id": "12w34b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w34b", + "url": "https://archive.org/download/Minecraft-JSONs/12w34b.json", + "sha1": "5fb51efc8f07ea57ffc2a02a7dac8a2835651b61", + "size": 4682004, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34b/minecraft.jar" + }, + { + "id": "12w36a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w36a", + "url": "https://archive.org/download/Minecraft-JSONs/12w36a.json", + "sha1": "914bd89686c4621da327d50375a1edbdd9c177da", + "size": 4705667, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w36a/minecraft.jar" + }, + { + "id": "12w37a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w37a", + "url": "https://archive.org/download/Minecraft-JSONs/12w37a.json", + "sha1": "50ea0bac2c91b13c0881bbf99aad66a046533781", + "size": 4727781, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w37a/minecraft.jar" + }, + { + "id": "12w38a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w38a", + "url": "https://archive.org/download/Minecraft-JSONs/12w38a.json", + "sha1": "69e5a531fa615eb870345feb25f26126fe95586b", + "size": 4752649, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38a/minecraft.jar" + }, + { + "id": "12w38b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w38b", + "url": "https://archive.org/download/Minecraft-JSONs/12w38b.json", + "sha1": "867505cb4934016bf46cb8c7833ef0eaef8d39d9", + "size": 4767044, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38b/minecraft.jar" + }, + { + "id": "12w39a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w39a", + "url": "https://archive.org/download/Minecraft-JSONs/12w39a.json", + "sha1": "65247c02036156b9f34c17f7d8bb053641afd0e7", + "size": 4768937, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39a/minecraft.jar" + }, + { + "id": "12w39b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w39b", + "url": "https://archive.org/download/Minecraft-JSONs/12w39b.json", + "sha1": "620d02bfd74204462a810874f83929d0b8b0b936", + "size": 4766448, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39b/minecraft.jar" + }, + { + "id": "12w40a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w40a", + "url": "https://archive.org/download/Minecraft-JSONs/12w40a.json", + "sha1": "434652551e93fdfb4de30cbe64310037777f7eff", + "size": 4884173, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40a/minecraft.jar" + }, + { + "id": "12w40b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w40b", + "url": "https://archive.org/download/Minecraft-JSONs/12w40b.json", + "sha1": "1612e0fa6062f764844c5a71ff89660c311f38ae", + "size": 4884732, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40b/minecraft.jar" + }, + { + "id": "12w41a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w41a", + "url": "https://archive.org/download/Minecraft-JSONs/12w41a.json", + "sha1": "7327bcd4da0d194565d6ee732b1fa48e8b14b347", + "size": 4900512, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41a/minecraft.jar" + }, + { + "id": "12w41b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w41b", + "url": "https://archive.org/download/Minecraft-JSONs/12w41b.json", + "sha1": "d73a5b6919d10689811c11d1c3debcd817050039", + "size": 4900976, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41b/minecraft.jar" + }, + { + "id": "12w42a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w42a", + "url": "https://archive.org/download/Minecraft-JSONs/12w42a.json", + "sha1": "0b10f7afbd54392b387a23c34547cb0f30d48998", + "size": 4919860, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42a/minecraft.jar" + }, + { + "id": "12w42b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w42b", + "url": "https://archive.org/download/Minecraft-JSONs/12w42b.json", + "sha1": "74024eab7588bd33dd53baa756fd4deb92557b0a", + "size": 4921744, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42b/minecraft.jar" + }, + { + "id": "12w49a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w49a", + "url": "https://archive.org/download/Minecraft-JSONs/12w49a.json", + "sha1": "a5a4cf65cf89207eb6ad7371c9237973865eba81", + "size": 4990865, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w49a/minecraft.jar" + }, + { + "id": "12w50a", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w50a", + "url": "https://archive.org/download/Minecraft-JSONs/12w50a.json", + "sha1": "96a6427720aef608a594ed1e0291e77cba398155", + "size": 5004175, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50a/minecraft.jar" + }, + { + "id": "12w50b", + "wiki": "https://minecraft.wiki/w/Java_Edition_12w50b", + "url": "https://archive.org/download/Minecraft-JSONs/12w50b.json", + "sha1": "73dc6efe46fef478cc5ed123e711872450e193fd", + "size": 5005360, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50b/minecraft.jar" + }, + { + "id": "13w01a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w01a", + "url": "https://archive.org/download/Minecraft-JSONs/13w01a.json", + "sha1": "e3256fe44cd7c6a1bf45570337e634b030589878", + "size": 5033591, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01a/minecraft.jar" + }, + { + "id": "13w01b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w01b", + "url": "https://archive.org/download/Minecraft-JSONs/13w01b.json", + "sha1": "87f9f88eb3dcc80dcf818e44af774ab7ff63eb66", + "size": 5035543, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01b/minecraft.jar" + }, + { + "id": "13w02a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w02a", + "url": "https://archive.org/download/Minecraft-JSONs/13w02a.json", + "sha1": "e9a57e8d5dcddcc9d919054c19b10eb71fcc304e", + "size": 5499864, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02a/minecraft.jar" + }, + { + "id": "13w02b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w02b", + "url": "https://archive.org/download/Minecraft-JSONs/13w02b.json", + "sha1": "9289953c82ce69ec3d2e59a6044a9c900a99478f", + "size": 5363159, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02b/minecraft.jar" + }, + { + "id": "13w03a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w03a", + "url": "https://archive.org/download/Minecraft-JSONs/13w03a.json", + "sha1": "6a2d3ffa88b7f5e0949f041193c6525d1c4cc22e", + "size": 6401672, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w03a/minecraft.jar" + }, + { + "id": "13w04a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w04a", + "url": "https://archive.org/download/Minecraft-JSONs/13w04a.json", + "sha1": "dff06285694aab7771682f949d51bca98ce52359", + "size": 6426112, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w04a/minecraft.jar" + }, + { + "id": "13w05a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w05a", + "url": "https://archive.org/download/Minecraft-JSONs/13w05a.json", + "sha1": "7808f090cb92afc8084545dd2ea305773bbd5e6e", + "size": 6442319, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05a/minecraft.jar" + }, + { + "id": "13w05b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w05b", + "url": "https://archive.org/download/Minecraft-JSONs/13w05b.json", + "sha1": "72074d7cb843229292f71ae917dcefbc0f01461d", + "size": 6442459, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05b/minecraft.jar" + }, + { + "id": "13w06a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w06a", + "url": "https://archive.org/download/Minecraft-JSONs/13w06a.json", + "sha1": "da409ce9f9c910c08cc729aadc6f592b8ff813cb", + "size": 6445893, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w06a/minecraft.jar" + }, + { + "id": "13w07a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w07a", + "url": "https://archive.org/download/Minecraft-JSONs/13w07a.json", + "sha1": "61f7dad52c34838be7a1e7d37a2370ac847ab87a", + "size": 6510193, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w07a/minecraft.jar" + }, + { + "id": "13w09a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w09a", + "url": "https://archive.org/download/Minecraft-JSONs/13w09a.json", + "sha1": "9ac49c55ca76eedfc985fa245dd0682e08b34982", + "size": 5574252, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09a/minecraft.jar" + }, + { + "id": "13w09b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w09b", + "url": "https://archive.org/download/Minecraft-JSONs/13w09b.json", + "sha1": "635161d84725b1988f814c890fe5841ad99121e1", + "size": 5578604, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09b/minecraft.jar" + }, + { + "id": "13w09c", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w09c", + "url": "https://archive.org/download/Minecraft-JSONs/13w09c.json", + "sha1": "1367ef1410c2ce7ac0f1c58727aa4883c8677469", + "size": 5533426, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09c/minecraft.jar" + }, + { + "id": "13w10a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w10a", + "url": "https://archive.org/download/Minecraft-JSONs/13w10a.json", + "sha1": "9162bca3ba8a77da2cd26cda1e46ca89a44bac4a", + "size": 5534991, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10a/minecraft.jar" + }, + { + "id": "13w10b", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w10b", + "url": "https://archive.org/download/Minecraft-JSONs/13w10b.json", + "sha1": "21e35ffe1772d1cf89aea653c7a883acb54b13a3", + "size": 5555235, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10b/minecraft.jar" + }, + { + "id": "13w11a", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w11a", + "url": "https://archive.org/download/Minecraft-JSONs/13w11a.json", + "sha1": "bec6c96bc4413ea3092428aba93d7425fe6a4ea9", + "size": 5556608, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w11a/minecraft.jar" + }, + { + "id": "13w12~", + "wiki": "https://minecraft.wiki/w/Java_Edition_13w12~", + "url": "https://archive.org/download/Minecraft-JSONs/13w12~.json", + "sha1": "66d6c6b5205ae1e8f0ad3eb78ccf66500f39c0c7", + "size": 5561634, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w12_/minecraft.jar" + }, + { + "id": "b1_8-pre1", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.8-pre1-2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre1-2.json", + "sha1": "6789c69ede3aedf83b800c76bea56855d38a0afc", + "size": 1893151, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre/minecraft.jar" + }, + { + "id": "b1_8-pre2", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.8-pre2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre2.json", + "sha1": "44191f2895bf1e064269c9279778f2e3e9c3c9c7", + "size": 1897780, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre2/minecraft.jar" + }, + { + "id": "b1_9-pre1", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre1", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre1.json", + "sha1": "fdeef0129af130aa00702e53c37c5c4029b7d50e", + "size": 1966908, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre/minecraft.jar" + }, + { + "id": "b1_9-pre2", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre2", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre2.json", + "sha1": "b0d40cf43b625631af65e2a645c34b533251da0e", + "size": 1988123, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre2/minecraft.jar" + }, + { + "id": "b1_9-pre3", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre3", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre3.json", + "sha1": "5b7fe76a602b7511c97740e36dc25040ccb6e76b", + "size": 2087104, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre3/minecraft.jar" + }, + { + "id": "b1_9-pre4", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre4", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre4.json", + "sha1": "5c4831d9705f2e00e3cd993e89b822636492932a", + "size": 2147107, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre4/minecraft.jar" + }, + { + "id": "b1_9-pre5", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre5", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre5.json", + "sha1": "e109b297d2c4ee7a0bd6aed72f38f7e3185654cf", + "size": 2211261, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre5/minecraft.jar" + }, + { + "id": "b1_9-pre6", + "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre6", + "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre6.json", + "sha1": "f0983e65cd1c0768b0d1fec471ce4f69173b8126", + "size": 2239270, + "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre6/minecraft.jar" + } + ] +} diff --git a/meta/common/mojang.py b/meta/common/mojang.py index f484e8d6a4..5fda2e002f 100644 --- a/meta/common/mojang.py +++ b/meta/common/mojang.py @@ -1,4 +1,4 @@ -from os.path import join +from os.path import join, dirname BASE_DIR = "mojang" @@ -6,11 +6,15 @@ VERSION_MANIFEST_FILE = join(BASE_DIR, "version_manifest_v2.json") VERSIONS_DIR = join(BASE_DIR, "versions") ASSETS_DIR = join(BASE_DIR, "assets") -STATIC_EXPERIMENTS_FILE = join(BASE_DIR, "minecraft-experiments.json") -STATIC_OLD_SNAPSHOTS_FILE = join(BASE_DIR, "minecraft-old-snapshots.json") -STATIC_OVERRIDES_FILE = join(BASE_DIR, "minecraft-legacy-override.json") -STATIC_LEGACY_SERVICES_FILE = join(BASE_DIR, "minecraft-legacy-services.json") -LIBRARY_PATCHES_FILE = join(BASE_DIR, "library-patches.json") +STATIC_EXPERIMENTS_FILE = join(dirname(__file__), "mojang-minecraft-experiments.json") +STATIC_OLD_SNAPSHOTS_FILE = join( + dirname(__file__), "mojang-minecraft-old-snapshots.json" +) +STATIC_OVERRIDES_FILE = join(dirname(__file__), "mojang-minecraft-legacy-override.json") +STATIC_LEGACY_SERVICES_FILE = join( + dirname(__file__), "mojang-minecraft-legacy-services.json" +) +LIBRARY_PATCHES_FILE = join(dirname(__file__), "mojang-library-patches.json") MINECRAFT_COMPONENT = "net.minecraft" LWJGL_COMPONENT = "org.lwjgl" diff --git a/meta/run/__init__.py b/meta/run/__init__.py new file mode 100644 index 0000000000..1bfe4f9ac8 --- /dev/null +++ b/meta/run/__init__.py @@ -0,0 +1 @@ +"""Main scripts""" diff --git a/meta/run/generate_fabric.py b/meta/run/generate_fabric.py new file mode 100755 index 0000000000..7ca50dd6aa --- /dev/null +++ b/meta/run/generate_fabric.py @@ -0,0 +1,143 @@ +import json +import os + +from meta.common import ( + ensure_component_dir, + launcher_path, + upstream_path, + transform_maven_key, +) +from meta.common.fabric import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + INTERMEDIARY_COMPONENT, + LOADER_COMPONENT, +) +from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier +from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(LOADER_COMPONENT) +ensure_component_dir(INTERMEDIARY_COMPONENT) + + +def load_jar_info(artifact_key) -> FabricJarInfo: + return FabricJarInfo.parse_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") + ) + + +def load_installer_info(version) -> FabricInstallerDataV1: + return FabricInstallerDataV1.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") + ) + + +def process_loader_version(entry) -> MetaVersion: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + installer_info = load_installer_info(entry["version"]) + + v = MetaVersion( + name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"] + ) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid="net.fabricmc.intermediary")] + v.order = 10 + v.type = "release" + if isinstance(installer_info.main_class, FabricMainClasses): + v.main_class = installer_info.main_class.client + else: + v.main_class = installer_info.main_class + v.libraries = [] + v.libraries.extend(installer_info.libraries.common) + v.libraries.extend(installer_info.libraries.client) + loader_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.fabricmc.net", + ) + v.libraries.append(loader_lib) + return v + + +def process_intermediary_version(entry) -> MetaVersion: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + + v = MetaVersion( + name="Intermediary Mappings", + uid="net.fabricmc.intermediary", + version=entry["version"], + ) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] + v.order = 11 + v.type = "release" + v.libraries = [] + v.volatile = True + intermediary_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.fabricmc.net", + ) + v.libraries.append(intermediary_lib) + return v + + +def main(): + recommended_loader_versions = [] + recommended_intermediary_versions = [] + + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as f: + loader_version_index = json.load(f) + for entry in loader_version_index: + version = entry["version"] + print(f"Processing loader {version}") + + v = process_loader_version(entry) + + # Fabric Meta has a separate "stable" field, let's use that + if not recommended_loader_versions and entry["stable"]: + recommended_loader_versions.append(version) + + v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) + + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), "r", encoding="utf-8" + ) as f: + intermediary_version_index = json.load(f) + for entry in intermediary_version_index: + version = entry["version"] + print(f"Processing intermediary {version}") + + v = process_intermediary_version(entry) + + recommended_intermediary_versions.append( + version + ) # all intermediaries are recommended + + v.write( + os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json") + ) + + package = MetaPackage(uid=LOADER_COMPONENT, name="Fabric Loader") + package.recommended = recommended_loader_versions + package.description = ( + "Fabric Loader is a tool to load Fabric-compatible mods in game environments." + ) + package.project_url = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) + + package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name="Intermediary Mappings") + package.recommended = recommended_intermediary_versions + package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." + package.project_url = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write(os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/run/generate_forge.py b/meta/run/generate_forge.py new file mode 100755 index 0000000000..95b5ac39cb --- /dev/null +++ b/meta/run/generate_forge.py @@ -0,0 +1,472 @@ +import os +import re +import sys +from packaging import version as pversion +from operator import attrgetter +from typing import Collection + +from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common.forge import ( + FORGE_COMPONENT, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + DERIVED_INDEX_FILE, + LEGACYINFO_FILE, + INSTALLER_INFO_DIR, + BAD_VERSIONS, + FORGEWRAPPER_LIBRARY, +) +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import ( + MetaVersion, + Dependency, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + MetaPackage, +) +from meta.model.forge import ( + ForgeVersion, + ForgeInstallerProfile, + ForgeLegacyInfo, + fml_libs_for_version, + ForgeInstallerProfileV2, + InstallerInfo, + DerivedForgeIndex, + ForgeLegacyInfoList, +) +from meta.model.mojang import MojangVersion + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(FORGE_COMPONENT) + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +# Construct a set of libraries out of a Minecraft version file, for filtering. +mc_version_cache = {} + + +def load_mc_version_filter(version: str): + if version in mc_version_cache: + return mc_version_cache[version] + v = MetaVersion.parse_file( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version}.json") + ) + libs = set(map(attrgetter("name"), v.libraries)) + mc_version_cache[version] = libs + return libs + + +""" +Match a library coordinate to a set of library coordinates. + * Block those that pass completely. + * For others, block those with lower versions than in the set. +""" + + +def should_ignore_artifact(libs: Collection[GradleSpecifier], match: GradleSpecifier): + for ver in libs: + if ( + ver.group == match.group + and ver.artifact == match.artifact + and ver.classifier == match.classifier + ): + if ver.version == match.version: + # Everything is matched perfectly - this one will be ignored + return True + elif pversion.parse(ver.version) > pversion.parse(match.version): + return True + else: + # Otherwise it did not match - new version is higher and this is an upgrade + return False + # No match found in the set - we need to keep this + return False + + +def version_from_profile( + profile: ForgeInstallerProfile, version: ForgeVersion +) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = profile.install.minecraft + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = profile.version_info.main_class + v.release_time = profile.version_info.time + + args = profile.version_info.minecraft_arguments + tweakers = [] + expression = re.compile(r"--tweakClass ([a-zA-Z0-9.]+)") + match = expression.search(args) + while match is not None: + tweakers.append(match.group(1)) + args = args[: match.start()] + args[match.end() :] + match = expression.search(args) + if len(tweakers) > 0: + args = args.strip() + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + mc_filter = load_mc_version_filter(mc_version) + for forge_lib in profile.version_info.libraries: + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): + continue + + overridden_name = forge_lib.name + if overridden_name.group == "net.minecraftforge": + if overridden_name.artifact == "minecraftforge": + overridden_name.artifact = "forge" + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) + + overridden_name.classifier = "universal" + elif overridden_name.artifact == "forge": + overridden_name.classifier = "universal" + + overridden_lib = Library(name=overridden_name) + if forge_lib.url == "http://maven.minecraftforge.net/": + overridden_lib.url = "https://maven.minecraftforge.net/" + else: + overridden_lib.url = forge_lib.url + # if forge_lib.checksums and len(forge_lib.checksums) == 2: + # overridden_lib.mmcHint = "forge-pack-xz" + v.libraries.append(overridden_lib) + + v.order = 5 + return v + + +def version_from_modernized_installer( + installer: MojangVersion, version: ForgeVersion +) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = version.mc_version + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.main_class = installer.main_class + v.release_time = installer.release_time + + args = installer.minecraft_arguments + tweakers = [] + expression = re.compile("--tweakClass ([a-zA-Z0-9.]+)") + match = expression.search(args) + while match is not None: + tweakers.append(match.group(1)) + args = args[: match.start()] + args[match.end() :] + match = expression.search(args) + if len(tweakers) > 0: + args = args.strip() + v.additional_tweakers = tweakers + # v.minecraftArguments = args + + v.libraries = [] + + mc_filter = load_mc_version_filter(mc_version) + for forge_lib in installer.libraries: + if ( + forge_lib.name.is_lwjgl() + or forge_lib.name.is_log4j() + or should_ignore_artifact(mc_filter, forge_lib.name) + ): + continue + + if forge_lib.name.group == "net.minecraftforge": + if forge_lib.name.artifact == "forge": + overridden_name = forge_lib.name + overridden_name.classifier = "universal" + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) + forge_lib.name = overridden_name + + elif forge_lib.name.artifact == "minecraftforge": + overridden_name = forge_lib.name + overridden_name.artifact = "forge" + overridden_name.classifier = "universal" + overridden_name.version = "%s-%s" % ( + mc_version, + overridden_name.version, + ) + forge_lib.downloads.artifact.path = overridden_name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % overridden_name.path() + ) + forge_lib.name = overridden_name + + v.libraries.append(forge_lib) + + v.order = 5 + return v + + +def version_from_legacy(info: ForgeLegacyInfo, version: ForgeVersion) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + mc_version = version.mc_version_sane + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)] + v.release_time = info.release_time + v.order = 5 + if fml_libs_for_version( + mc_version + ): # WHY, WHY DID I WASTE MY TIME REWRITING FMLLIBSMAPPING + v.additional_traits = ["legacyFML"] + + classifier = "client" + if "universal" in version.url(): + classifier = "universal" + + main_mod = Library( + name=GradleSpecifier( + "net.minecraftforge", "forge", version.long_version, classifier + ) + ) + main_mod.downloads = MojangLibraryDownloads() + main_mod.downloads.artifact = MojangArtifact( + url=version.url(), sha1=info.sha1, size=info.size + ) + main_mod.downloads.artifact.path = None + v.jar_mods = [main_mod] + return v + + +def version_from_build_system_installer( + installer: MojangVersion, profile: ForgeInstallerProfileV2, version: ForgeVersion +) -> MetaVersion: + v = MetaVersion(name="Forge", version=version.rawVersion, uid=FORGE_COMPONENT) + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] + v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" + + # FIXME: Add the size and hash here + v.maven_files = [] + + # load the locally cached installer file info and use it to add the installer entry in the json + info = InstallerInfo.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") + ) + installer_lib = Library( + name=GradleSpecifier( + "net.minecraftforge", "forge", version.long_version, "installer" + ) + ) + installer_lib.downloads = MojangLibraryDownloads() + installer_lib.downloads.artifact = MojangArtifact( + url="https://maven.minecraftforge.net/%s" % (installer_lib.name.path()), + sha1=info.sha1hash, + size=info.size, + ) + v.maven_files.append(installer_lib) + + for forge_lib in profile.libraries: + if forge_lib.name.is_log4j(): + continue + + if ( + forge_lib.name.group == "net.minecraftforge" + and forge_lib.name.artifact == "forge" + and forge_lib.name.classifier == "universal" + ): + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + ) + v.maven_files.append(forge_lib) + + v.libraries = [] + + v.libraries.append(FORGEWRAPPER_LIBRARY) + + for forge_lib in installer.libraries: + if forge_lib.name.is_log4j(): + continue + + if forge_lib.name.group == "net.minecraftforge": + if forge_lib.name.artifact == "forge" and not forge_lib.name.classifier: + forge_lib.name.classifier = "launcher" + forge_lib.downloads.artifact.path = forge_lib.name.path() + forge_lib.downloads.artifact.url = ( + "https://maven.minecraftforge.net/%s" % forge_lib.name.path() + ) + forge_lib.name = forge_lib.name + # net.minecraftforge.forge:client doesn't exist??? (49.0.x) + if not len(forge_lib.downloads.artifact.url): + continue + v.libraries.append(forge_lib) + + v.release_time = installer.release_time + v.order = 5 + mc_args = ( + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " + "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " + "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + ) + for arg in installer.arguments.game: + mc_args += f" {arg}" + if "--fml.forgeGroup" not in installer.arguments.game: + mc_args += f" --fml.forgeGroup net.minecraftforge" + if "--fml.forgeVersion" not in installer.arguments.game: + mc_args += f" --fml.forgeVersion {version.rawVersion}" + if "--fml.mcVersion" not in installer.arguments.game: + mc_args += f" --fml.mcVersion {version.mc_version}" + v.minecraft_arguments = mc_args + return v + + +def main(): + # load the locally cached version list + remote_versions = DerivedForgeIndex.parse_file( + os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) + ) + recommended_versions = [] + + legacy_info_list = ForgeLegacyInfoList.parse_file( + os.path.join(UPSTREAM_DIR, LEGACYINFO_FILE) + ) + legacy_versions = [ + "1.1", + "1.2.3", + "1.2.4", + "1.2.5", + "1.3.2", + "1.4.1", + "1.4.2", + "1.4.3", + "1.4.4", + "1.4.5", + "1.4.6", + "1.4.7", + "1.5", + "1.5.1", + "1.5.2", + "1.6.1", + "1.6.2", + "1.6.3", + "1.6.4", + "1.7.10", + "1.7.10-pre4", + "1.7.2", + "1.8", + "1.8.8", + "1.8.9", + "1.9", + "1.9.4", + "1.10", + "1.10.2", + "1.11", + "1.11.2", + "1.12", + "1.12.1", + "1.12.2", + ] + + for key, entry in remote_versions.versions.items(): + if entry.mc_version is None: + eprint("Skipping %s with invalid MC version" % key) + continue + + version = ForgeVersion(entry) + + if version.long_version in BAD_VERSIONS: + # Version 1.12.2-14.23.5.2851 is ultra cringe, I can't imagine why you would even spend one second on + # actually adding support for this version. + # It is cringe, because it's installer info is broken af + eprint(f"Skipping bad version {version.long_version}") + continue + + if version.url() is None: + eprint("Skipping %s with no valid files" % key) + continue + eprint("Processing Forge %s" % version.rawVersion) + version_elements = version.rawVersion.split(".") + if len(version_elements) < 1: + eprint("Skipping version %s with not enough version elements" % key) + continue + + major_version_str = version_elements[0] + if not major_version_str.isnumeric(): + eprint( + "Skipping version %s with non-numeric major version %s" + % (key, major_version_str) + ) + continue + + if entry.recommended: + recommended_versions.append(version.rawVersion) + + # If we do not have the corresponding Minecraft version, we ignore it + if not os.path.isfile( + os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" + ) + ): + eprint( + "Skipping %s with no corresponding Minecraft version %s" + % (key, version.mc_version_sane) + ) + continue + + # Path for new-style build system based installers + installer_version_filepath = os.path.join( + UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" + ) + profile_filepath = os.path.join( + UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" + ) + + eprint(installer_version_filepath) + if os.path.isfile(installer_version_filepath): + installer = MojangVersion.parse_file(installer_version_filepath) + if entry.mc_version in legacy_versions: + v = version_from_modernized_installer(installer, version) + else: + profile = ForgeInstallerProfileV2.parse_file(profile_filepath) + v = version_from_build_system_installer(installer, profile, version) + else: + if version.uses_installer(): + # If we do not have the Forge json, we ignore this version + if not os.path.isfile(profile_filepath): + eprint("Skipping %s with missing profile json" % key) + continue + profile = ForgeInstallerProfile.parse_file(profile_filepath) + v = version_from_profile(profile, version) + else: + # Generate json for legacy here + if version.mc_version_sane == "1.6.1": + continue + build = version.build + if ( + str(build).encode("utf-8").decode("utf8") + not in legacy_info_list.number + ): + eprint( + "Legacy build %d is missing in legacy info. Ignoring." % build + ) + continue + + v = version_from_legacy(legacy_info_list.number[str(build)], version) + + v.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, f"{v.version}.json")) + + recommended_versions.sort() + + print("Recommended versions:", recommended_versions) + + package = MetaPackage( + uid=FORGE_COMPONENT, + name="Forge", + project_url="https://www.minecraftforge.net/forum/", + ) + package.recommended = recommended_versions + package.write(os.path.join(LAUNCHER_DIR, FORGE_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/run/generate_liteloader.py b/meta/run/generate_liteloader.py new file mode 100755 index 0000000000..2fe95fcc42 --- /dev/null +++ b/meta/run/generate_liteloader.py @@ -0,0 +1,118 @@ +import os +from datetime import datetime +from typing import List, Tuple, Dict, Optional + +from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common.liteloader import LITELOADER_COMPONENT, VERSIONS_FILE +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import MetaVersion, GradleSpecifier, Library, MetaPackage, Dependency +from meta.model.liteloader import LiteloaderIndex, LiteloaderArtefact + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(LITELOADER_COMPONENT) + + +def process_artefacts( + mc_version: str, artefacts: Dict[str, LiteloaderArtefact], is_snapshot: bool +) -> Tuple[List[MetaVersion], Optional[MetaVersion]]: + versions: List[MetaVersion] = [] + lookup: Dict[str, MetaVersion] = {} + latest_version = None + latest = None + for x, artefact in artefacts.items(): + if x == "latest": + latest_version = artefact.version + continue + v = MetaVersion( + name="LiteLoader", + uid=LITELOADER_COMPONENT, + version=artefact.version, + requires=[Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)], + release_time=datetime.utcfromtimestamp(int(artefact.timestamp)), + additional_tweakers=[artefact.tweakClass], + main_class="net.minecraft.launchwrapper.Launch", + order=10, + libraries=artefact.libraries, + type="release", + ) + + if is_snapshot: + v.type = "snapshot" + + # hack to make broken liteloader versions work + for lib in v.libraries: + if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.0.3"): + lib.url = "https://repo.maven.apache.org/maven2/" + if lib.name == GradleSpecifier("org.ow2.asm", "asm-all", "5.2"): + lib.url = "http://repo.liteloader.com/" + + liteloader_lib = Library( + name=GradleSpecifier("com.mumfrey", "liteloader", v.version), + url="http://dl.liteloader.com/versions/", + ) + if is_snapshot: + liteloader_lib.mmcHint = "always-stale" + v.libraries.append(liteloader_lib) + + versions.append(v) + lookup[v.version] = v + + if latest_version: + latest = lookup[latest_version] + return versions, latest + + +def process_versions(index: LiteloaderIndex) -> Tuple[List[MetaVersion], List[str]]: + all_versions: List[MetaVersion] = [] + recommended: List[str] = [] + for mcVersion, versionObject in index.versions.items(): + # ignore this for now. It should be a jar mod or something. + if mcVersion == "1.5.2": + continue + + latest_release = None + if versionObject.artefacts: + versions, latest_release = process_artefacts( + mcVersion, versionObject.artefacts.liteloader, False + ) + all_versions.extend(versions) + if versionObject.snapshots: + versions, latest_snapshot = process_artefacts( + mcVersion, versionObject.snapshots.liteloader, True + ) + all_versions.extend(versions) + + if latest_release: + recommended.append(latest_release.version) + + recommended.sort() + + all_versions.sort(key=lambda x: x.release_time, reverse=True) + return all_versions, recommended + + +def main(): + index = LiteloaderIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) + + all_versions, recommended = process_versions(index) + + for version in all_versions: + version.write( + os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, f"{version.version}.json") + ) + + package = MetaPackage( + uid=LITELOADER_COMPONENT, + name="LiteLoader", + description=index.meta.description, + project_url=index.meta.url, + authors=[index.meta.authors], + recommended=recommended, + ) + package.write(os.path.join(LAUNCHER_DIR, LITELOADER_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/run/generate_mojang.py b/meta/run/generate_mojang.py new file mode 100755 index 0000000000..e0068c24ec --- /dev/null +++ b/meta/run/generate_mojang.py @@ -0,0 +1,576 @@ +import copy +import hashlib +import os +from collections import defaultdict, namedtuple +from operator import attrgetter +from pprint import pprint +from packaging import version as pversion +from typing import Optional, List + +from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common.mojang import ( + STATIC_LEGACY_SERVICES_FILE, + VERSION_MANIFEST_FILE, + MINECRAFT_COMPONENT, + LWJGL3_COMPONENT, + LWJGL_COMPONENT, + STATIC_OVERRIDES_FILE, + VERSIONS_DIR, + LIBRARY_PATCHES_FILE, +) +from meta.model import ( + MetaVersion, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + Dependency, + MetaPackage, + MojangRules, +) +from meta.model.mojang import ( + LegacyServices, + MojangIndexWrap, + MojangIndex, + MojangVersion, + LegacyOverrideIndex, + LibraryPatches, + SUPPORTED_FEATURES, +) + +APPLY_SPLIT_NATIVES_WORKAROUND = True + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(MINECRAFT_COMPONENT) +ensure_component_dir(LWJGL_COMPONENT) +ensure_component_dir(LWJGL3_COMPONENT) + + +def map_log4j_artifact(version): + x = pversion.parse(version) + if x <= pversion.parse("2.0"): + return "2.0-beta9-fixed", "https://files.prismlauncher.org/maven/%s" + if x <= pversion.parse("2.17.1"): + return ( + "2.17.1", + "https://repo1.maven.org/maven2/%s", + ) # This is the only version that's patched (as of 2022/02/19) + return None, None + + +LOG4J_HASHES = { + "2.0-beta9-fixed": { + "log4j-api": { + "sha1": "b61eaf2e64d8b0277e188262a8b771bbfa1502b3", + "size": 107347, + }, + "log4j-core": { + "sha1": "677991ea2d7426f76309a73739cecf609679492c", + "size": 677588, + }, + }, + "2.17.1": { + "log4j-api": { + "sha1": "d771af8e336e372fb5399c99edabe0919aeaf5b2", + "size": 301872, + }, + "log4j-core": { + "sha1": "779f60f3844dadc3ef597976fcb1e5127b1f343d", + "size": 1790452, + }, + "log4j-slf4j18-impl": { + "sha1": "ca499d751f4ddd8afb016ef698c30be0da1d09f7", + "size": 21268, + }, + }, +} + +# We want versions that contain natives for all platforms. If there are multiple, pick the latest one +# LWJGL versions we want +PASS_VARIANTS = [ + # TODO: needs arm64 for Linux? + "8a9b08f11271eb4de3b50e5d069949500b2c7bc1", # 3.3.3 (2024-04-03 11:49:39+00:00) + "765b4ab443051d286bdbb1c19cd7dc86b0792dce", # 3.3.2 (2024-01-17 13:19:20+00:00) + "54c4fb1d6a96ac3007c947bf310c8bcf94a862be", # 3.3.1 (2023-04-20 11:55:19+00:00) split natives, with WoA natives + "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) will be patched, missing tinyfd + "235fc413bc4c76b269c207f7bca6464f1e1f1d80", # 3.2.1 (2019-02-13 16:12:08+00:00) + "deb1a436d806413207350735a00e04b54d113916", # 3.1.6 (2018-10-18 14:46:12+00:00) + "3e47f0f742fb759401754769fa59c508fd8fda75", # 3.1.2 (2018-06-21 12:57:11+00:00) + "a3f254df5a63a0a1635755733022029e8cfae1b3", # 2.9.4-nightly-20150209 (2016-12-20 14:05:34+00:00) + "879be09c0bd0d4bafc2ea4ea3d2ab8607a0d976c", # 2.9.3 (2015-01-30 11:58:24+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) + "27dcadcba29a1a7127880ca1a77efa9ece866f24", # 2.9.0 (2013-09-06 12:31:58+00:00) +] + +# LWJGL versions we def. don't want! +BAD_VARIANTS = [ + "79bde9e46e9ad9accebda11e8293ed08d80dbdc3", # 3.3.2 (2023-08-30 11:24:35+00:00) does not have lwjgl-freetype + "8836c419f90f69a278b97d945a34af165c24ff60", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, with workaround, replaced by 23w26a + "3c624b94c06dbc4abae08fe6156d74abe4a2cca5", # 3.3.1 (2022-05-04 14:41:35+00:00) we already have a nice 3.3.1 + "e1106ca765798218323b7a6d7528050260ea9d88", # 3.3.1 (2022-05-04 14:41:35+00:00) doesn't use split natives + "90b3d9ca01058286c033b6b7ae7f6dc370a04015", # 3.2.2 (2022-03-31 14:53:25+00:00) only linux, windows + "d986df9598fa2bcf4a5baab5edf044548e66d011", # 3.2.2 (2021-12-10 03:36:38+00:00) only linux, windows + "4b73fccb9e5264c2068bdbc26f9651429abbf21a", # 3.2.2 (2021-08-25 14:41:57+00:00) only linux, windows + "090cec3577ecfe438b890b2a9410ea07aa725e16", # 3.2.2 (2021-04-07 14:04:09+00:00) only linux, windows + "ab463e9ebc6a36abf22f2aa27b219dd372ff5069", # 3.2.2 (2019-08-13 07:33:42+00:00) only linux, windows + "51d8ff5a7efc949b4ad2088930e151d6b88ba616", # 3.2.2 (2019-07-19 09:25:47+00:00) only linux, windows + "854649a5bd1455b89117593ae82ff90c8132cacf", # 3.2.1 (2019-04-18 11:05:19+00:00) only osx, windows + "89fcb489261b05f622e8052fe0b588b0cfe49c24", # 3.1.6 (2019-04-18 11:05:19+00:00) only linux + "f04052162b50fa1433f67e1a90bc79466c4ab776", # 2.9.0 (2013-10-21 16:34:47+00:00) only linux, windows + "6442fc475f501fbd0fc4244fd1c38c02d9ebaf7e", # 2.9.0 (2011-03-30 22:00:00+00:00) fine but newer variant available +] + + +def add_or_get_bucket(buckets, rules: Optional[MojangRules]) -> MetaVersion: + rule_hash = None + if rules: + rule_hash = hash(rules.json()) + + if rule_hash in buckets: + bucket = buckets[rule_hash] + else: + bucket = MetaVersion(name="LWJGL", version="undetermined", uid=LWJGL_COMPONENT) + bucket.type = "release" + buckets[rule_hash] = bucket + return bucket + + +def hash_lwjgl_version(lwjgl: MetaVersion): + 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): + return library.name + + +LWJGLEntry = namedtuple("LWJGLEntry", ("version", "sha1")) + +lwjglVersionVariants = defaultdict(list) + + +def add_lwjgl_version(variants, lwjgl): + lwjgl_copy = copy.deepcopy(lwjgl) + libraries = list(lwjgl_copy.libraries) + libraries.sort(key=sort_libs_by_name) + lwjgl_copy.libraries = libraries + + version = lwjgl_copy.version + current_hash = hash_lwjgl_version(lwjgl_copy) + found = False + for variant in variants[version]: + existing_hash = variant.sha1 + if current_hash == existing_hash: + found = True + break + if not found: + print("!!! New variant for LWJGL version %s" % version) + variants[version].append(LWJGLEntry(version=lwjgl_copy, sha1=current_hash)) + + +def remove_paths_from_lib(lib): + if lib.downloads.artifact: + lib.downloads.artifact.path = None + if lib.downloads.classifiers: + for key, value in lib.downloads.classifiers.items(): + value.path = None + + +def adapt_new_style_arguments(arguments): + foo = [] + # we ignore the jvm arguments entirely. + # grab the strings, log the complex stuff + for arg in arguments.game: + if isinstance(arg, str): + if arg == "--clientId": + continue + if arg == "${clientid}": + continue + if arg == "--xuid": + continue + if arg == "${auth_xuid}": + continue + foo.append(arg) + else: + print("!!! Unrecognized structure in Minecraft game arguments:") + pprint(arg) + return " ".join(foo) + + +def adapt_new_style_arguments_to_traits(arguments): + foo = [] + # we ignore the jvm arguments entirely. + # grab the object, log the errors + for arg in arguments.game: + if isinstance(arg, dict): + for rule in arg["rules"]: + for k, v in rule["features"].items(): + if rule["action"] == "allow" and v and k in SUPPORTED_FEATURES: + foo.append(f"feature:{k}") + return foo + + +def is_macos_only(rules: Optional[MojangRules]): + 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": + allows_osx = True + if rule.action == "allow" and not rule.os: + allows_all = True + if allows_osx and not allows_all: + return True + return False + + +def patch_library(lib: Library, patches: LibraryPatches) -> List[Library]: + to_patch = [lib] + + new_libraries = [] + while to_patch: + target = to_patch.pop(0) + + for patch in patches: + if patch.applies(target): + if patch.override: + target.merge(patch.override) + + if patch.additionalLibraries: + additional_copy = copy.deepcopy(patch.additionalLibraries) + new_libraries += list(dict.fromkeys(additional_copy)) + if patch.patchAdditionalLibraries: + to_patch += additional_copy + + return new_libraries + + +def process_single_variant(lwjgl_variant: MetaVersion, patches: LibraryPatches): + lwjgl_version = lwjgl_variant.version + v = copy.deepcopy(lwjgl_variant) + + new_libraries = [] + for lib in v.libraries: + new_libraries += patch_library(lib, patches) + v.libraries += list(dict.fromkeys(new_libraries)) + + if lwjgl_version[0] == "2": + filename = os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, f"{lwjgl_version}.json") + + v.name = "LWJGL 2" + v.uid = LWJGL_COMPONENT + v.conflicts = [Dependency(uid=LWJGL3_COMPONENT)] + elif lwjgl_version[0] == "3": + filename = os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, f"{lwjgl_version}.json") + + v.name = "LWJGL 3" + v.uid = LWJGL3_COMPONENT + v.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 + filtered_libraries = list( + filter(lambda l: l.name.artifact not in ["jutils", "jinput"], v.libraries) + ) + v.libraries = filtered_libraries + else: + raise Exception("LWJGL version not recognized: %s" % v.version) + + v.volatile = True + v.order = -1 + good = True + for lib in v.libraries: + # skip libraries without natives or that we patched + if not lib.natives or lib in new_libraries: + continue + checked_dict = {"linux", "windows", "osx"} + if not checked_dict.issubset(lib.natives.keys()): + print("Missing system classifier!", v.version, lib.name, lib.natives.keys()) + good = False + break + if lib.downloads: + for entry in checked_dict: + baked_entry = lib.natives[entry] + if baked_entry not in lib.downloads.classifiers: + print( + "Missing download for classifier!", + v.version, + lib.name, + baked_entry, + lib.downloads.classifiers.keys(), + ) + good = False + break + if good: + v.write(filename) + else: + print("Skipped LWJGL", v.version) + + +def lib_is_split_native(lib: Library) -> bool: + if lib.name.classifier and lib.name.classifier.startswith("natives-"): + return True + return False + + +def version_has_split_natives(v: MojangVersion) -> bool: + for lib in v.libraries: + if lib_is_split_native(lib): + return True + return False + + +def main(): + # get the local version list + override_index = LegacyOverrideIndex.parse_file(STATIC_OVERRIDES_FILE) + legacy_services = LegacyServices.parse_file(STATIC_LEGACY_SERVICES_FILE) + library_patches = LibraryPatches.parse_file(LIBRARY_PATCHES_FILE) + + found_any_lwjgl3 = False + + 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) + mojang_version = MojangVersion.parse_file(input_file) + v = mojang_version.to_meta_version( + "Minecraft", MINECRAFT_COMPONENT, mojang_version.id + ) + + libs_minecraft = [] + new_libs_minecraft = [] + is_lwjgl_3 = False + has_split_natives = version_has_split_natives(v) + buckets = {} + + for lib in v.libraries: + specifier = lib.name + + # generic fixes + remove_paths_from_lib(lib) + + if APPLY_SPLIT_NATIVES_WORKAROUND and lib_is_split_native(lib): + # merge classifier into artifact name to workaround bug in launcher + specifier.artifact += f"-{specifier.classifier}" + specifier.classifier = None + + if specifier.is_lwjgl(): + if has_split_natives: # implies lwjgl3 + bucket = add_or_get_bucket(buckets, None) + is_lwjgl_3 = True + found_any_lwjgl3 = True + bucket.version = specifier.version + if not bucket.libraries: + bucket.libraries = [] + bucket.libraries.append(lib) + bucket.release_time = v.release_time + else: + rules = None + if lib.rules: + rules = lib.rules + lib.rules = None + if is_macos_only(rules): + print( + "Candidate library ", + specifier, + " is only for macOS and is therefore ignored.", + ) + continue + 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": + is_lwjgl_3 = True + found_any_lwjgl3 = True + bucket.version = specifier.version + if not bucket.libraries: + bucket.libraries = [] + bucket.libraries.append(lib) + bucket.release_time = v.release_time + # FIXME: workaround for insane log4j nonsense from December 2021. Probably needs adjustment. + elif lib.name.is_log4j(): + version_override, maven_override = map_log4j_artifact(lib.name.version) + + if version_override and maven_override: + if version_override not in LOG4J_HASHES: + raise Exception( + "ERROR: unhandled log4j version (overriden) %s!" + % version_override + ) + + if lib.name.artifact not in LOG4J_HASHES[version_override]: + raise Exception( + "ERROR: unhandled log4j artifact %s!" % lib.name.artifact + ) + + replacement_name = GradleSpecifier( + "org.apache.logging.log4j", lib.name.artifact, version_override + ) + artifact = MojangArtifact( + url=maven_override % (replacement_name.path()), + sha1=LOG4J_HASHES[version_override][lib.name.artifact]["sha1"], + size=LOG4J_HASHES[version_override][lib.name.artifact]["size"], + ) + + libs_minecraft.append( + Library( + name=replacement_name, + downloads=MojangLibraryDownloads(artifact=artifact), + ) + ) + else: + libs_minecraft.append(lib) + else: + new_libs_minecraft += patch_library(lib, library_patches) + libs_minecraft.append(lib) + if len(buckets) == 1: + for key in buckets: + lwjgl = buckets[key] + lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) + add_lwjgl_version(lwjglVersionVariants, lwjgl) + print("Found only candidate LWJGL", lwjgl.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 is None: + continue + lwjgl = buckets[key] + if None in buckets: + lwjgl.libraries = sorted( + lwjgl.libraries + buckets[None].libraries, + key=attrgetter("name"), + ) + else: + lwjgl.libraries = sorted(lwjgl.libraries, key=attrgetter("name")) + add_lwjgl_version(lwjglVersionVariants, lwjgl) + print("Found candidate LWJGL", lwjgl.version, key) + # remove the common bucket... + if None in buckets: + del buckets[None] + v.libraries = libs_minecraft + list(dict.fromkeys(new_libs_minecraft)) + + if is_lwjgl_3: + lwjgl_dependency = Dependency(uid=LWJGL3_COMPONENT) + else: + lwjgl_dependency = Dependency(uid=LWJGL_COMPONENT) + if len(buckets) == 1: + suggested_version = next(iter(buckets.values())).version + if is_lwjgl_3: + lwjgl_dependency.suggests = suggested_version + else: + lwjgl_dependency.suggests = "2.9.4-nightly-20150209" + else: + bad_versions = {"3.1.6", "3.2.1"} + our_versions = set() + + for lwjgl in iter(buckets.values()): + our_versions = our_versions.union({lwjgl.version}) + + if our_versions == bad_versions: + print("Found broken 3.1.6/3.2.1 combo, forcing LWJGL to 3.2.1") + suggested_version = "3.2.1" + lwjgl_dependency.suggests = suggested_version + else: + raise Exception( + "ERROR: cannot determine single suggested LWJGL version in %s" + % mojang_version.id + ) + + # if it uses LWJGL 3, add the trait that enables starting on first thread on macOS + if is_lwjgl_3: + if not v.additional_traits: + v.additional_traits = [] + v.additional_traits.append("FirstThreadOnMacOS") + v.requires = [lwjgl_dependency] + v.order = -2 + # process 1.13 arguments into previous version + if not mojang_version.minecraft_arguments and mojang_version.arguments: + v.minecraft_arguments = adapt_new_style_arguments(mojang_version.arguments) + if not v.additional_traits: + v.additional_traits = [] + v.additional_traits.extend( + adapt_new_style_arguments_to_traits(mojang_version.arguments) + ) + out_filename = os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{v.version}.json" + ) + if v.version in override_index.versions: + override = override_index.versions[v.version] + override.apply_onto_meta_version(v) + if v.version in legacy_services: + if v.additional_traits == None: + v.additional_traits = [] + v.additional_traits.append("legacyServices") + v.write(out_filename) + + for lwjglVersionVariant in lwjglVersionVariants: + decided_variant = None + passed_variants = 0 + unknown_variants = 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) + decided_variant = variant + passed_variants += 1 + continue + # print natives classifiers to decide which variant to use + n = [ + x.natives.keys() + for x in variant.version.libraries + if x.natives is not None + ] + print(n) + + print( + f' "{variant.sha1}", # {lwjglVersionVariant} ({variant.version.release_time})' + ) + unknown_variants += 1 + print("") + + if decided_variant and passed_variants == 1 and unknown_variants == 0: + process_single_variant(decided_variant.version, library_patches) + else: + raise Exception( + "No variant decided for version %s out of %d possible ones and %d unknown ones." + % (lwjglVersionVariant, passed_variants, unknown_variants) + ) + + lwjgl_package = MetaPackage(uid=LWJGL_COMPONENT, name="LWJGL 2") + lwjgl_package.write(os.path.join(LAUNCHER_DIR, LWJGL_COMPONENT, "package.json")) + + if found_any_lwjgl3: + lwjgl_package = MetaPackage(uid=LWJGL3_COMPONENT, name="LWJGL 3") + lwjgl_package.write( + os.path.join(LAUNCHER_DIR, LWJGL3_COMPONENT, "package.json") + ) + + mojang_index = MojangIndexWrap( + MojangIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE)) + ) + + minecraft_package = MetaPackage(uid=MINECRAFT_COMPONENT, name="Minecraft") + minecraft_package.recommended = [mojang_index.latest.release] + minecraft_package.write( + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, "package.json") + ) + + +if __name__ == "__main__": + main() diff --git a/meta/run/generate_neoforge.py b/meta/run/generate_neoforge.py new file mode 100644 index 0000000000..ee1e26908d --- /dev/null +++ b/meta/run/generate_neoforge.py @@ -0,0 +1,181 @@ +from copy import deepcopy +import os +import re +import sys +from operator import attrgetter +from typing import Collection + +from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common.neoforge import ( + NEOFORGE_COMPONENT, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + DERIVED_INDEX_FILE, + INSTALLER_INFO_DIR, +) +from meta.common.forge import FORGEWRAPPER_LIBRARY +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import ( + MetaVersion, + Dependency, + Library, + GradleSpecifier, + MojangLibraryDownloads, + MojangArtifact, + MetaPackage, +) +from meta.model.neoforge import ( + NeoForgeVersion, + NeoForgeInstallerProfileV2, + InstallerInfo, + DerivedNeoForgeIndex, +) +from meta.model.mojang import MojangVersion + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(NEOFORGE_COMPONENT) + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def version_from_build_system_installer( + installer: MojangVersion, + profile: NeoForgeInstallerProfileV2, + version: NeoForgeVersion, +) -> MetaVersion: + v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] + v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" + + # FIXME: Add the size and hash here + v.maven_files = [] + + # load the locally cached installer file info and use it to add the installer entry in the json + info = InstallerInfo.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version.long_version}.json") + ) + installer_lib = Library( + name=GradleSpecifier( + "net.neoforged", version.artifact, version.long_version, "installer" + ) + ) + installer_lib.downloads = MojangLibraryDownloads() + installer_lib.downloads.artifact = MojangArtifact( + url="https://maven.neoforged.net/%s" % (installer_lib.name.path()), + sha1=info.sha1hash, + size=info.size, + ) + v.maven_files.append(installer_lib) + + for forge_lib in profile.libraries: + if forge_lib.name.is_log4j(): + continue + + v.maven_files.append(forge_lib) + + v.libraries = [] + + v.libraries.append(FORGEWRAPPER_LIBRARY) + + for forge_lib in installer.libraries: + if forge_lib.name.is_log4j(): + continue + + v.libraries.append(forge_lib) + + v.release_time = installer.release_time + v.order = 5 + mc_args = ( + "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} " + "--assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} " + "--accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}" + ) + for arg in installer.arguments.game: + mc_args += f" {arg}" + v.minecraft_arguments = mc_args + return v + + +def main(): + # load the locally cached version list + remote_versions = DerivedNeoForgeIndex.parse_file( + os.path.join(UPSTREAM_DIR, DERIVED_INDEX_FILE) + ) + recommended_versions = [] + + for key, entry in remote_versions.versions.items(): + if entry.mc_version is None: + eprint("Skipping %s with invalid MC version" % key) + continue + + version = NeoForgeVersion(entry) + + if version.url() is None: + eprint("Skipping %s with no valid files" % key) + continue + eprint("Processing Forge %s" % version.rawVersion) + version_elements = version.rawVersion.split(".") + if len(version_elements) < 1: + eprint("Skipping version %s with not enough version elements" % key) + continue + + major_version_str = version_elements[0] + if not major_version_str.isnumeric(): + eprint( + "Skipping version %s with non-numeric major version %s" + % (key, major_version_str) + ) + continue + + if entry.recommended: + recommended_versions.append(version.rawVersion) + + # If we do not have the corresponding Minecraft version, we ignore it + if not os.path.isfile( + os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" + ) + ): + eprint( + "Skipping %s with no corresponding Minecraft version %s" + % (key, version.mc_version_sane) + ) + continue + + # Path for new-style build system based installers + installer_version_filepath = os.path.join( + UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" + ) + profile_filepath = os.path.join( + UPSTREAM_DIR, INSTALLER_MANIFEST_DIR, f"{version.long_version}.json" + ) + + eprint(installer_version_filepath) + assert os.path.isfile( + installer_version_filepath + ), f"version {installer_version_filepath} does not have installer version manifest" + installer = MojangVersion.parse_file(installer_version_filepath) + profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) + v = version_from_build_system_installer(installer, profile, version) + + v.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, f"{v.version}.json")) + + recommended_versions.sort() + + print("Recommended versions:", recommended_versions) + + package = MetaPackage( + uid=NEOFORGE_COMPONENT, + name="NeoForge", + project_url="https://neoforged.net", + ) + package.recommended = recommended_versions + package.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, "package.json")) + + +if __name__ == "__main__": + main() diff --git a/meta/run/generate_quilt.py b/meta/run/generate_quilt.py new file mode 100755 index 0000000000..ccf2797380 --- /dev/null +++ b/meta/run/generate_quilt.py @@ -0,0 +1,161 @@ +import json +import os + +from meta.common import ( + ensure_component_dir, + launcher_path, + upstream_path, + transform_maven_key, +) +from meta.common.quilt import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + INTERMEDIARY_COMPONENT, + LOADER_COMPONENT, + USE_QUILT_MAPPINGS, + DISABLE_BEACON_ARG, + DISABLE_BEACON_VERSIONS, +) +from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier +from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses + +LAUNCHER_DIR = launcher_path() +UPSTREAM_DIR = upstream_path() + +ensure_component_dir(LOADER_COMPONENT) +ensure_component_dir(INTERMEDIARY_COMPONENT) + + +def load_jar_info(artifact_key) -> FabricJarInfo: + return FabricJarInfo.parse_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") + ) + + +def load_installer_info(version) -> FabricInstallerDataV1: + return FabricInstallerDataV1.parse_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json") + ) + + +def process_loader_version(entry) -> (MetaVersion, bool): + should_recommend = ( + "-" not in entry["version"] + ) # Don't recommend pre releases as per SemVer + + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + installer_info = load_installer_info(entry["version"]) + + v = MetaVersion(name="Quilt Loader", uid=LOADER_COMPONENT, version=entry["version"]) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid=INTERMEDIARY_COMPONENT)] + v.order = 10 + v.type = "release" + if isinstance(installer_info.main_class, FabricMainClasses): + v.main_class = installer_info.main_class.client + else: + v.main_class = installer_info.main_class + v.libraries = [] + v.libraries.extend(installer_info.libraries.common) + v.libraries.extend(installer_info.libraries.client) + loader_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release", + ) + v.libraries.append(loader_lib) + + if entry["version"] in DISABLE_BEACON_VERSIONS: + if not v.additional_jvm_args: + v.additional_jvm_args = [] + v.additional_jvm_args.append(DISABLE_BEACON_ARG) + + return v, should_recommend + + +def process_intermediary_version(entry) -> MetaVersion: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + + v = MetaVersion( + name="Quilt Intermediary Mappings", + uid=INTERMEDIARY_COMPONENT, + version=entry["version"], + ) + v.release_time = jar_info.release_time + v.requires = [Dependency(uid="net.minecraft", equals=entry["version"])] + v.order = 11 + v.type = "release" + v.libraries = [] + v.volatile = True + intermediary_lib = Library( + name=GradleSpecifier.from_string(entry["maven"]), + url="https://maven.quiltmc.org/repository/release", + ) + v.libraries.append(intermediary_lib) + return v + + +def main(): + recommended_loader_versions = [] + recommended_intermediary_versions = [] + + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as f: + loader_version_index = json.load(f) + for entry in loader_version_index: + version = entry["version"] + print(f"Processing loader {version}") + + v, should_recommend = process_loader_version(entry) + + if ( + not recommended_loader_versions and should_recommend + ): # newest stable loader is recommended + recommended_loader_versions.append(version) + + v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) + + if USE_QUILT_MAPPINGS: + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "hashed.json"), "r", encoding="utf-8" + ) as f: + intermediary_version_index = json.load(f) + for entry in intermediary_version_index: + version = entry["version"] + print(f"Processing intermediary {version}") + + v = process_intermediary_version(entry) + + recommended_intermediary_versions.append( + version + ) # all intermediaries are recommended + + v.write( + os.path.join( + LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json" + ) + ) + + package = MetaPackage(uid=LOADER_COMPONENT, name="Quilt Loader") + package.recommended = recommended_loader_versions + package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." + package.project_url = "https://quiltmc.org/" + package.authors = ["Quilt Project"] + package.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, "package.json")) + + if USE_QUILT_MAPPINGS: + package = MetaPackage( + uid=INTERMEDIARY_COMPONENT, name="Quilt Intermediary Mappings" + ) + package.recommended = recommended_intermediary_versions + package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner." + package.project_url = "https://quiltmc.org/" + package.authors = ["Quilt Project"] + package.write( + os.path.join(LAUNCHER_DIR, INTERMEDIARY_COMPONENT, "package.json") + ) + + +if __name__ == "__main__": + main() diff --git a/meta/run/index.py b/meta/run/index.py new file mode 100755 index 0000000000..23dc2336ea --- /dev/null +++ b/meta/run/index.py @@ -0,0 +1,78 @@ +import hashlib +import os +from operator import attrgetter + +from meta.common import launcher_path +from meta.model import MetaVersion, MetaPackage +from meta.model.index import ( + MetaPackageIndex, + MetaVersionIndex, + MetaVersionIndexEntry, + MetaPackageIndexEntry, +) + +LAUNCHER_DIR = launcher_path() + + +# take the hash type (like hashlib.md5) and filename, return hex string of hash +def hash_file(hash_fn, file_name): + hash_instance = hash_fn() + with open(file_name, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hash_instance.update(chunk) + return hash_instance.hexdigest() + + +# ignore these files when indexing versions +ignore = {"index.json", "package.json", ".git", ".github"} + +# initialize output structures - package list level +packages = MetaPackageIndex() + +# walk through all the package folders +for package in sorted(os.listdir(LAUNCHER_DIR)): + if package in ignore: + continue + + sharedData = MetaPackage.parse_file( + os.path.join(LAUNCHER_DIR, package, "package.json") + ) + recommendedVersions = set() + if sharedData.recommended: + recommendedVersions = set(sharedData.recommended) + + # initialize output structures - version list level + versionList = MetaVersionIndex(uid=package, name=sharedData.name) + + # walk through all the versions of the package + for filename in os.listdir(LAUNCHER_DIR + "/%s" % package): + if filename in ignore: + continue + # parse and hash the version file + filepath = LAUNCHER_DIR + "/%s/%s" % (package, filename) + filehash = hash_file(hashlib.sha256, filepath) + versionFile = MetaVersion.parse_file(filepath) + is_recommended = versionFile.version in recommendedVersions + + versionEntry = MetaVersionIndexEntry.from_meta_version( + versionFile, is_recommended, filehash + ) + + versionList.versions.append(versionEntry) + + # sort the versions in descending order by time of release + versionList.versions = sorted( + versionList.versions, key=attrgetter("release_time"), reverse=True + ) + + # write the version index for the package + outFilePath = LAUNCHER_DIR + "/%s/index.json" % package + versionList.write(outFilePath) + + # insert entry into the package index + packageEntry = MetaPackageIndexEntry( + uid=package, name=sharedData.name, sha256=hash_file(hashlib.sha256, outFilePath) + ) + packages.packages.append(packageEntry) + +packages.write(os.path.join(LAUNCHER_DIR, "index.json")) diff --git a/meta/run/update_fabric.py b/meta/run/update_fabric.py new file mode 100755 index 0000000000..132495b92c --- /dev/null +++ b/meta/run/update_fabric.py @@ -0,0 +1,130 @@ +import json +import os +import zipfile +from datetime import datetime + +import requests + +from meta.common import ( + upstream_path, + ensure_upstream_dir, + transform_maven_key, + default_session, +) +from meta.common.fabric import ( + JARS_DIR, + INSTALLER_INFO_DIR, + META_DIR, + DATETIME_FORMAT_HTTP, +) +from meta.model.fabric import FabricJarInfo + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(META_DIR) + +sess = default_session() + + +def filehash(filename, hashtype, blocksize=65536): + h = hashtype() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + h.update(block) + return h.hexdigest() + + +def get_maven_url(maven_key, server, ext): + parts = maven_key.split(":", 3) + maven_ver_url = ( + server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + ) + maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext + return maven_url + + +def get_json_file(path, url): + with open(path, "w", encoding="utf-8") as f: + r = sess.get(url) + r.raise_for_status() + version_json = r.json() + json.dump(version_json, f, sort_keys=True, indent=4) + return version_json + + +def head_file(url): + r = sess.head(url) + r.raise_for_status() + return r.headers + + +def get_binary_file(path, url): + with open(path, "wb") as f: + r = sess.get(url) + r.raise_for_status() + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) + + +def compute_jar_file(path, url): + # These two approaches should result in the same metadata, except for the timestamp which might be a few minutes + # off for the fallback method + try: + # Let's not download a Jar file if we don't need to. + headers = head_file(url) + tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) + except requests.HTTPError: + # Just in case something changes in the future + print(f"Falling back to downloading jar for {url}") + + jar_path = path + ".jar" + get_binary_file(jar_path, url) + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + allinfo = jar.infolist() + for info in allinfo: + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + + data = FabricJarInfo(release_time=tstamp) + data.write(path + ".json") + + +def main(): + # get the version list for each component we are interested in + for component in ["intermediary", "loader"]: + index = get_json_file( + os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.fabricmc.net/v2/versions/" + component, + ) + for it in index: + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url( + it["maven"], "https://maven.fabricmc.net/", ".jar" + ) + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) + + # for each loader, download installer JSON file from maven + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as loaderVersionIndexFile: + loader_version_index = json.load(loaderVersionIndexFile) + for it in loader_version_index: + print(f"Downloading JAR info for loader {it['version']} ") + maven_url = get_maven_url( + it["maven"], "https://maven.fabricmc.net/", ".json" + ) + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) + + +if __name__ == "__main__": + main() diff --git a/meta/run/update_forge.py b/meta/run/update_forge.py new file mode 100755 index 0000000000..8fc8920bad --- /dev/null +++ b/meta/run/update_forge.py @@ -0,0 +1,397 @@ +""" + Get the source files necessary for generating Forge versions +""" + +import copy +import hashlib +import json +import os +import re +import sys +import zipfile +from contextlib import suppress +from datetime import datetime +from pathlib import Path +from pprint import pprint + +from pydantic import ValidationError + +from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common.forge import ( + JARS_DIR, + INSTALLER_INFO_DIR, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + FILE_MANIFEST_DIR, + BAD_VERSIONS, + LEGACYINFO_FILE, +) +from meta.model.forge import ( + ForgeFile, + ForgeEntry, + ForgeMCVersionInfo, + ForgeLegacyInfoList, + DerivedForgeIndex, + ForgeVersion, + ForgeInstallerProfile, + ForgeInstallerProfileV2, + InstallerInfo, + ForgeLegacyInfo, +) +from meta.model.mojang import MojangVersion + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(INSTALLER_MANIFEST_DIR) +ensure_upstream_dir(VERSION_MANIFEST_DIR) +ensure_upstream_dir(FILE_MANIFEST_DIR) + +LEGACYINFO_PATH = os.path.join(UPSTREAM_DIR, LEGACYINFO_FILE) + +sess = default_session() + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def filehash(filename, hashtype, blocksize=65536): + hashtype = hashtype() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + hashtype.update(block) + return hashtype.hexdigest() + + +def get_single_forge_files_manifest(longversion): + print(f"Getting Forge manifest for {longversion}") + path_thing = UPSTREAM_DIR + "/forge/files_manifests/%s.json" % longversion + files_manifest_file = Path(path_thing) + from_file = False + if files_manifest_file.is_file(): + with open(path_thing, "r") as f: + files_json = json.load(f) + from_file = True + else: + file_url = ( + "https://files.minecraftforge.net/net/minecraftforge/forge/%s/meta.json" + % longversion + ) + r = sess.get(file_url) + r.raise_for_status() + files_json = r.json() + + ret_dict = dict() + + for classifier, extensionObj in files_json.get("classifiers").items(): + assert type(classifier) == str + assert type(extensionObj) == dict + + # assert len(extensionObj.items()) == 1 + index = 0 + count = 0 + while index < len(extensionObj.items()): + mutable_copy = copy.deepcopy(extensionObj) + extension, hashtype = mutable_copy.popitem() + if not type(classifier) == str: + pprint(classifier) + pprint(extensionObj) + if not type(hashtype) == str: + pprint(classifier) + pprint(extensionObj) + print( + "%s: Skipping missing hash for extension %s:" + % (longversion, extension) + ) + index += 1 + continue + assert type(classifier) == str + processed_hash = re.sub(r"\W", "", hashtype) + if not len(processed_hash) == 32: + print( + "%s: Skipping invalid hash for extension %s:" + % (longversion, extension) + ) + pprint(extensionObj) + index += 1 + continue + + file_obj = ForgeFile( + classifier=classifier, hash=processed_hash, extension=extension + ) + if count == 0: + ret_dict[classifier] = file_obj + index += 1 + count += 1 + else: + print( + "%s: Multiple objects detected for classifier %s:" + % (longversion, classifier) + ) + pprint(extensionObj) + assert False + + if not from_file: + with open(path_thing, "w", encoding="utf-8") as f: + json.dump(files_json, f, sort_keys=True, indent=4) + + return ret_dict + + +def main(): + # get the remote version list fragments + r = sess.get( + "https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json" + ) + r.raise_for_status() + main_json = r.json() + assert type(main_json) == dict + + r = sess.get( + "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json" + ) + r.raise_for_status() + promotions_json = r.json() + assert type(promotions_json) == dict + + promoted_key_expression = re.compile( + "(?P[^-]+)-(?P(latest)|(recommended))(-(?P[a-zA-Z0-9\\.]+))?" + ) + + recommended_set = set() + + new_index = DerivedForgeIndex() + + # FIXME: does not fully validate that the file has not changed format + # NOTE: For some insane reason, the format of the versions here is special. It having a branch at the end means it + # affects that particular branch. + # We don't care about Forge having branches. + # Therefore we only use the short version part for later identification and filter out the branch-specific + # promotions (among other errors). + print("Processing promotions:") + for promoKey, shortversion in promotions_json.get("promos").items(): + match = promoted_key_expression.match(promoKey) + if not match: + print("Skipping promotion %s, the key did not parse:" % promoKey) + pprint(promoKey) + assert match + if not match.group("mc"): + print( + "Skipping promotion %s, because it has no Minecraft version." % promoKey + ) + continue + if match.group("branch"): + print("Skipping promotion %s, because it on a branch only." % promoKey) + continue + elif match.group("promotion") == "recommended": + recommended_set.add(shortversion) + print("%s added to recommended set" % shortversion) + elif match.group("promotion") == "latest": + pass + else: + assert False + + version_expression = re.compile( + "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$" + ) + + print("") + print("Processing versions:") + for mc_version, value in main_json.items(): + assert type(mc_version) == str + assert type(value) == list + for long_version in value: + assert type(long_version) == str + match = version_expression.match(long_version) + if not match: + pprint(long_version) + assert match + assert match.group("mc") == mc_version + + files = get_single_forge_files_manifest(long_version) + + build = int(match.group("build")) + version = match.group("ver") + branch = match.group("branch") + + is_recommended = version in recommended_set + + entry = ForgeEntry( + long_version=long_version, + mc_version=mc_version, + version=version, + build=build, + branch=branch, + # NOTE: we add this later after the fact. The forge promotions file lies about these. + latest=False, + recommended=is_recommended, + files=files, + ) + new_index.versions[long_version] = entry + if not new_index.by_mc_version: + new_index.by_mc_version = dict() + if mc_version not in new_index.by_mc_version: + new_index.by_mc_version.setdefault(mc_version, ForgeMCVersionInfo()) + new_index.by_mc_version[mc_version].versions.append(long_version) + # NOTE: we add this later after the fact. The forge promotions file lies about these. + # if entry.latest: + # new_index.by_mc_version[mc_version].latest = long_version + if entry.recommended: + new_index.by_mc_version[mc_version].recommended = long_version + + print("") + print("Post processing promotions and adding missing 'latest':") + for mc_version, info in new_index.by_mc_version.items(): + latest_version = info.versions[-1] + info.latest = latest_version + new_index.versions[latest_version].latest = True + print("Added %s as latest for %s" % (latest_version, mc_version)) + + print("") + print("Dumping index files...") + + with open(UPSTREAM_DIR + "/forge/maven-metadata.json", "w", encoding="utf-8") as f: + json.dump(main_json, f, sort_keys=True, indent=4) + + with open(UPSTREAM_DIR + "/forge/promotions_slim.json", "w", encoding="utf-8") as f: + json.dump(promotions_json, f, sort_keys=True, indent=4) + + new_index.write(UPSTREAM_DIR + "/forge/derived_index.json") + + legacy_info_list = ForgeLegacyInfoList() + + print("Grabbing installers and dumping installer profiles...") + # get the installer jars - if needed - and get the installer profiles out of them + for key, entry in new_index.versions.items(): + eprint("Updating Forge %s" % key) + if entry.mc_version is None: + eprint("Skipping %d with invalid MC version" % entry.build) + continue + + version = ForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + continue + if version.long_version in BAD_VERSIONS: + eprint(f"Skipping bad version {version.long_version}") + continue + + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) + + if version.uses_installer(): + installer_info_path = ( + UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + + "/forge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version + ) + + installer_refresh_required = not os.path.isfile( + profile_path + ) or not os.path.isfile(installer_info_path) + + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + rfile = sess.get(version.url(), stream=True) + rfile.raise_for_status() + with open(jar_path, "wb") as f: + for chunk in rfile.iter_content(chunk_size=128): + f.write(chunk) + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + ForgeInstallerProfile.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + try: + ForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = filehash(jar_path, hashlib.sha1) + installer_info.sha256hash = filehash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) + else: + # ignore the two versions without install manifests and jar mod class files + # TODO: fix those versions? + if version.mc_version_sane == "1.6.1": + continue + + # only gather legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + # grab the jar/zip if it's not there + if not os.path.isfile(jar_path): + rfile = sess.get(version.url(), stream=True) + rfile.raise_for_status() + with open(jar_path, "wb") as f: + for chunk in rfile.iter_content(chunk_size=128): + f.write(chunk) + # find the latest timestamp in the zip file + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + for info in jar.infolist(): + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + legacy_info = ForgeLegacyInfo() + legacy_info.release_time = tstamp + legacy_info.sha1 = filehash(jar_path, hashlib.sha1) + legacy_info.sha256 = filehash(jar_path, hashlib.sha256) + legacy_info.size = os.path.getsize(jar_path) + legacy_info_list.number[key] = legacy_info + + # only write legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + legacy_info_list.write(LEGACYINFO_PATH) + + +if __name__ == "__main__": + main() diff --git a/meta/run/update_liteloader.py b/meta/run/update_liteloader.py new file mode 100755 index 0000000000..383644754d --- /dev/null +++ b/meta/run/update_liteloader.py @@ -0,0 +1,37 @@ +import json +import os + +from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common.liteloader import VERSIONS_FILE, BASE_DIR +from meta.model.liteloader import LiteloaderIndex + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(BASE_DIR) + +sess = default_session() + + +def main(): + # get the remote version list + r = sess.get("http://dl.liteloader.com/versions/versions.json") + r.raise_for_status() + + # make sure it's JSON + main_json = r.json() + + # make sure we understand the schema + remote_versions = LiteloaderIndex.parse_obj(main_json) + parsed = remote_versions.json() + original = json.dumps(main_json, sort_keys=True, indent=4) + assert parsed == original + + print("Successfully parsed index") + print(f"Last updated {remote_versions.meta.updated}") + + # save the json it to file + remote_versions.write(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) + + +if __name__ == "__main__": + main() diff --git a/meta/run/update_mojang.py b/meta/run/update_mojang.py new file mode 100755 index 0000000000..52921f3e8a --- /dev/null +++ b/meta/run/update_mojang.py @@ -0,0 +1,161 @@ +import json +import os +import zipfile + +from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common.http import download_binary_file +from meta.common.mojang import ( + BASE_DIR, + VERSION_MANIFEST_FILE, + VERSIONS_DIR, + ASSETS_DIR, + STATIC_EXPERIMENTS_FILE, + STATIC_OLD_SNAPSHOTS_FILE, +) +from meta.model.mojang import ( + MojangIndexWrap, + MojangIndex, + ExperimentIndex, + ExperimentIndexWrap, + OldSnapshotIndexWrap, + OldSnapshotIndex, +) + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(BASE_DIR) +ensure_upstream_dir(VERSIONS_DIR) +ensure_upstream_dir(ASSETS_DIR) + +sess = default_session() + + +def fetch_zipped_version(path, url): + zip_path = f"{path}.zip" + download_binary_file(sess, zip_path, url) + with zipfile.ZipFile(zip_path) as z: + for info in z.infolist(): + if info.filename.endswith(".json"): + print(f"Found {info.filename} as version json") + version_json = json.load(z.open(info)) + break + + assert version_json + + with open(path, "w", encoding="utf-8") as f: + json.dump(version_json, f, sort_keys=True, indent=4) + + return version_json + + +def fetch_modified_version(path, version): + r = sess.get(version.url) + r.raise_for_status() + version_json = r.json() + + version_json["releaseTime"] = version_json["releaseTime"] + "T00:00:00+02:00" + version_json["time"] = version_json["releaseTime"] + + downloads = { + "client": {"url": version.jar, "sha1": version.sha1, "size": version.size} + } + + version_json["downloads"] = downloads + version_json["type"] = "old_snapshot" + + with open(path, "w", encoding="utf-8") as f: + json.dump(version_json, f, sort_keys=True, indent=4) + + return version_json + + +def fetch_version(path, url): + r = sess.get(url) + r.raise_for_status() + version_json = r.json() + + with open(path, "w", encoding="utf-8") as f: + json.dump(version_json, f, sort_keys=True, indent=4) + + return version_json + + +def main(): + # get the remote version list + r = sess.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json") + r.raise_for_status() + + remote_versions = MojangIndexWrap(MojangIndex(**r.json())) + remote_ids = set(remote_versions.versions.keys()) + + version_manifest_path = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE) + + if os.path.exists(version_manifest_path): + # get the local version list + current_versions = MojangIndexWrap( + MojangIndex.parse_file(version_manifest_path) + ) + local_ids = set(current_versions.versions.keys()) + + # versions not present locally but present remotely are new + pending_ids = remote_ids.difference(local_ids) + + for x in local_ids: + remote_version = remote_versions.versions[x] + local_version = current_versions.versions[x] + if remote_version.time > local_version.time: + pending_ids.add(x) + else: + pending_ids = remote_ids + + for x in pending_ids: + version = remote_versions.versions[x] + 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 + if os.path.exists(STATIC_EXPERIMENTS_FILE): + experiments = ExperimentIndexWrap( + ExperimentIndex.parse_file(STATIC_EXPERIMENTS_FILE) + ) + experiment_ids = set(experiments.versions.keys()) + + for x in experiment_ids: + version = experiments.versions[x] + experiment_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") + + print("Updating experiment " + version.id) + if not os.path.isfile(experiment_path): + fetch_zipped_version(experiment_path, version.url) + else: + print("Already have experiment " + version.id) + + # deal with old snapshots + if os.path.exists(STATIC_OLD_SNAPSHOTS_FILE): + old_snapshots = OldSnapshotIndexWrap( + OldSnapshotIndex.parse_file(STATIC_OLD_SNAPSHOTS_FILE) + ) + old_snapshots_ids = set(old_snapshots.versions.keys()) + + for x in old_snapshots_ids: + version = old_snapshots.versions[x] + old_snapshots_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") + + print("Updating old snapshot " + version.id) + if not os.path.isfile(old_snapshots_path): + fetch_modified_version(old_snapshots_path, version) + else: + print("Already have old snapshot " + version.id) + + remote_versions.index.write(version_manifest_path) + + +if __name__ == "__main__": + main() diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py new file mode 100644 index 0000000000..826981aed1 --- /dev/null +++ b/meta/run/update_neoforge.py @@ -0,0 +1,319 @@ +""" + Get the source files necessary for generating Forge versions +""" + +import copy +import hashlib +import json +import os +import re +import sys +import zipfile +from contextlib import suppress +from datetime import datetime +from pathlib import Path +from pprint import pprint +import urllib.parse + +from pydantic import ValidationError + +from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common.neoforge import ( + JARS_DIR, + INSTALLER_INFO_DIR, + INSTALLER_MANIFEST_DIR, + VERSION_MANIFEST_DIR, + FILE_MANIFEST_DIR, +) +from meta.model.neoforge import ( + NeoForgeFile, + NeoForgeEntry, + NeoForgeMCVersionInfo, + DerivedNeoForgeIndex, + NeoForgeVersion, + NeoForgeInstallerProfileV2, + InstallerInfo, +) +from meta.model.mojang import MojangVersion + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(INSTALLER_MANIFEST_DIR) +ensure_upstream_dir(VERSION_MANIFEST_DIR) +ensure_upstream_dir(FILE_MANIFEST_DIR) + +sess = default_session() + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def filehash(filename, hashtype, blocksize=65536): + hashtype = hashtype() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + hashtype.update(block) + return hashtype.hexdigest() + + +def find_nth(haystack, needle, n): + start = haystack.find(needle) + while start >= 0 and n > 1: + start = haystack.find(needle, start + len(needle)) + n -= 1 + return start + + +def get_single_forge_files_manifest(longversion, artifact: str): + print(f"Getting NeoForge manifest for {longversion}") + path_thing = UPSTREAM_DIR + "/neoforge/files_manifests/%s.json" % longversion + files_manifest_file = Path(path_thing) + from_file = False + if files_manifest_file.is_file(): + with open(path_thing, "r") as f: + files_json = json.load(f) + from_file = True + else: + file_url = ( + f"https://maven.neoforged.net/api/maven/details/releases/net%2Fneoforged%2F{artifact}%2F" + + urllib.parse.quote(longversion) + ) + r = sess.get(file_url) + r.raise_for_status() + files_json = r.json() + + ret_dict = dict() + + for file in files_json.get("files"): + assert type(file) == dict + name = file["name"] + prefix = f"{artifact}-{longversion}" + assert name.startswith( + prefix + ), f"{longversion} classifier {name} doesn't start with {prefix}" + file_name = name[len(prefix) :] + if file_name.startswith("-"): + file_name = file_name[1:] + if file_name.startswith("."): + continue + + classifier, ext = os.path.splitext(file_name) + + if ext in [".md5", ".sha1", ".sha256", ".sha512"]: + continue + + # assert len(extensionObj.items()) == 1 + file_obj = NeoForgeFile( + artifact=artifact, classifier=classifier, extension=ext[1:] + ) + ret_dict[classifier] = file_obj + + if not from_file: + Path(path_thing).parent.mkdir(parents=True, exist_ok=True) + with open(path_thing, "w", encoding="utf-8") as f: + json.dump(files_json, f, sort_keys=True, indent=4) + + return ret_dict + + +def main(): + # get the remote version list fragments + r = sess.get( + "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fforge" + ) + r.raise_for_status() + main_json = r.json()["versions"] + assert type(main_json) == list + + # get the new remote version list fragments + r = sess.get( + "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fneoforge" + ) + r.raise_for_status() + new_main_json = r.json()["versions"] + assert type(new_main_json) == list + + main_json += new_main_json + + new_index = DerivedNeoForgeIndex() + + version_expression = re.compile( + r"^(?P[0-9a-zA-Z_\.]+)-(?P[0-9\.]+\.(?P[0-9]+))(-(?P[a-zA-Z0-9\.]+))?$" + ) + neoforge_version_re = re.compile( + r"^(?P\d+).(?P\d+).(?P\d+)(?:-(?P\w+))?$" + ) + + print("") + print("Processing versions:") + for long_version in main_json: + assert type(long_version) == str + + match = version_expression.match(long_version) + if match: + mc_version = match.group("mc") + build = int(match.group("build")) + version = match.group("ver") + branch = match.group("branch") + artifact = "forge" + + match_nf = neoforge_version_re.match(long_version) + if match_nf: + mc_version = f"1.{match_nf.group('mcminor')}.{match_nf.group('mcpatch')}" + build = int(match_nf.group("number")) + version = match_nf.group("number") + branch = match_nf.group("tag") + match = match_nf + artifact = "neoforge" + + assert match, f"{long_version} doesn't match version regex" + try: + files = get_single_forge_files_manifest(long_version, artifact) + except: + continue + + # TODO: what *is* recommended? + is_recommended = False + + entry = NeoForgeEntry( + artifact=artifact, + long_version=long_version, + mc_version=mc_version, + version=version, + build=build, + branch=branch, + # NOTE: we add this later after the fact. The forge promotions file lies about these. + latest=False, + recommended=is_recommended, + files=files, + ) + new_index.versions[long_version] = entry + if not new_index.by_mc_version: + new_index.by_mc_version = dict() + if mc_version not in new_index.by_mc_version: + new_index.by_mc_version.setdefault(mc_version, NeoForgeMCVersionInfo()) + new_index.by_mc_version[mc_version].versions.append(long_version) + # NOTE: we add this later after the fact. The forge promotions file lies about these. + # if entry.latest: + # new_index.by_mc_version[mc_version].latest = long_version + if entry.recommended: + new_index.by_mc_version[mc_version].recommended = long_version + + print("") + print("Dumping index files...") + + with open( + UPSTREAM_DIR + "/neoforge/maven-metadata.json", "w", encoding="utf-8" + ) as f: + json.dump(main_json, f, sort_keys=True, indent=4) + + new_index.write(UPSTREAM_DIR + "/neoforge/derived_index.json") + + print("Grabbing installers and dumping installer profiles...") + # get the installer jars - if needed - and get the installer profiles out of them + for key, entry in new_index.versions.items(): + eprint("Updating NeoForge %s" % key) + if entry.mc_version is None: + eprint("Skipping %d with invalid MC version" % entry.build) + continue + + version = NeoForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + continue + if not version.uses_installer(): + eprint(f"version {version.long_version} does not use installer") + continue + + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) + + installer_info_path = ( + UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + + "/neoforge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version + ) + + installer_refresh_required = not os.path.isfile( + profile_path + ) or not os.path.isfile(installer_info_path) + + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + try: + rfile = sess.get(version.url(), stream=True) + rfile.raise_for_status() + Path(jar_path).parent.mkdir(parents=True, exist_ok=True) + with open(jar_path, "wb") as f: + for chunk in rfile.iter_content(chunk_size=128): + f.write(chunk) + except Exception as e: + eprint("Failed to download %s" % version.url()) + eprint("Error is %s" % e) + continue + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + Path(version_file_path).parent.mkdir( + parents=True, exist_ok=True + ) + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + NeoForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + Path(profile_path).parent.mkdir(parents=True, exist_ok=True) + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = filehash(jar_path, hashlib.sha1) + installer_info.sha256hash = filehash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) + + +if __name__ == "__main__": + main() diff --git a/meta/run/update_quilt.py b/meta/run/update_quilt.py new file mode 100755 index 0000000000..5eaa8ed0d0 --- /dev/null +++ b/meta/run/update_quilt.py @@ -0,0 +1,122 @@ +import json +import os +import zipfile +from datetime import datetime + +import requests + +from meta.common import ( + upstream_path, + ensure_upstream_dir, + transform_maven_key, + default_session, +) +from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, USE_QUILT_MAPPINGS +from meta.common.fabric import DATETIME_FORMAT_HTTP +from meta.model.fabric import FabricJarInfo + +UPSTREAM_DIR = upstream_path() + +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(META_DIR) + +sess = default_session() + + +def filehash(filename, hashtype, blocksize=65536): + h = hashtype() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + h.update(block) + return h.hexdigest() + + +def get_maven_url(maven_key, server, ext): + parts = maven_key.split(":", 3) + maven_ver_url = ( + server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + ) + maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext + return maven_url + + +def get_json_file(path, url): + with open(path, "w", encoding="utf-8") as f: + r = sess.get(url) + r.raise_for_status() + print(f"QUILT DEBUG {r.headers}") + version_json = r.json() + json.dump(version_json, f, sort_keys=True, indent=4) + return version_json + + +def head_file(url): + r = sess.head(url) + r.raise_for_status() + return r.headers + + +def get_binary_file(path, url): + with open(path, "wb") as f: + r = sess.get(url) + r.raise_for_status() + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) + + +def compute_jar_file(path, url): + # NOTE: Quilt Meta does not make any guarantees about Last-Modified. + # Always download the JAR file instead + jar_path = path + ".jar" + get_binary_file(jar_path, url) + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + allinfo = jar.infolist() + for info in allinfo: + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + + data = FabricJarInfo(release_time=tstamp) + data.write(path + ".json") + + +def main(): + # get the version list for each component we are interested in + components = ["loader"] + if USE_QUILT_MAPPINGS: + components.append("hashed") + for component in components: + index = get_json_file( + os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.quiltmc.org/v3/versions/" + component, + ) + for it in index: + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar" + ) + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) + + # for each loader, download installer JSON file from maven + with open( + os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" + ) as loaderVersionIndexFile: + loader_version_index = json.load(loaderVersionIndexFile) + for it in loader_version_index: + print(f"Downloading JAR info for loader {it['version']} ") + maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".json" + ) + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) + + +if __name__ == "__main__": + main() diff --git a/nix/default.nix b/nix/default.nix deleted file mode 100644 index a297ddd3b1..0000000000 --- a/nix/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{...}: { - imports = [ - ./dev.nix - ]; - - # Supported systems. - systems = [ - "x86_64-linux" - "aarch64-linux" - ]; -} diff --git a/nix/dev.nix b/nix/dev.nix index e753ed818a..1ca4edfc91 100644 --- a/nix/dev.nix +++ b/nix/dev.nix @@ -1,43 +1,33 @@ { - inputs, - self, - ... -}: { perSystem = { - system, + config, pkgs, + self', ... }: { - checks = { - pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run { - src = self; - hooks = { - markdownlint.enable = true; + pre-commit.settings = { + excludes = ["flake.lock"]; + hooks = { + markdownlint.enable = true; - alejandra.enable = true; - deadnix.enable = true; - nil.enable = true; + alejandra.enable = true; + deadnix.enable = true; + nil.enable = true; - black.enable = true; - }; + black.enable = true; }; }; devShells.default = pkgs.mkShell { - inherit (self.checks.${system}.pre-commit-check) shellHook; + shellHook = '' + ${config.pre-commit.installationScript} + ''; - packages = [ - (pkgs.python3.withPackages (ps: - with ps; [ - cachecontrol - filelock - requests - packaging - pydantic - - coverage - ])) + buildInputs = with pkgs; [ + poetry ]; + + inputsFrom = [self'.packages.default]; }; formatter = pkgs.alejandra; diff --git a/nix/nixos/default.nix b/nix/nixos/default.nix new file mode 100644 index 0000000000..c4aa24174b --- /dev/null +++ b/nix/nixos/default.nix @@ -0,0 +1,10 @@ +{self, ...}: { + flake.nixosModules = { + default = self.nixosModules.meta; + meta = { + imports = [self.nixosModules.metaBare]; + nixpkgs.overlays = [self.overlays.default]; + }; + metaBare = ./meta.nix; + }; +} diff --git a/nix/nixos/meta.nix b/nix/nixos/meta.nix new file mode 100644 index 0000000000..7366851e22 --- /dev/null +++ b/nix/nixos/meta.nix @@ -0,0 +1,69 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) getExe mkEnableOption mkIf mkOption mkPackageOption types; + + settingsFormat = pkgs.formats.keyValue {}; + + cfg = config.services.blockgame-meta; +in { + options.services.blockgame-meta = { + enable = mkEnableOption "blockgame-meta service"; + + package = mkPackageOption pkgs "blockgame-meta" {}; + + settings = mkOption { + type = types.submodule { + freeformType = settingsFormat.type; + options = { + DEPLOY_TO_S3 = mkOption { + type = types.str; + default = "false"; + }; + DEPLOY_TO_FOLDER = mkOption { + type = types.str; + default = "false"; + }; + DEPLOY_TO_GIT = mkOption { + type = types.str; + default = "false"; + }; + }; + }; + }; + }; + config = mkIf cfg.enable { + users.users."blockgame-meta" = { + isSystemUser = true; + group = "blockgame-meta"; + }; + + users.groups."blockgame-meta" = {}; + + systemd = { + services."blockgame-meta" = { + description = "blockgame metadata generator"; + after = ["network-online.target"]; + wants = ["network-online.target"]; + serviceConfig = { + EnvironmentFile = [(settingsFormat.generate "blockgame-meta.env" cfg.settings)]; + ExecStart = getExe cfg.package; + StateDirectory = "blockgame-meta"; + CacheDirectory = "blockgame-meta"; + User = "blockgame-meta"; + }; + }; + + timers."blockgame-meta" = { + timerConfig = { + OnCalendar = "hourly"; + RandomizedDelaySec = "5m"; + }; + wantedBy = ["timers.target"]; + }; + }; + }; +} diff --git a/nix/packages.nix b/nix/packages.nix new file mode 100644 index 0000000000..4af7b97e5b --- /dev/null +++ b/nix/packages.nix @@ -0,0 +1,18 @@ +{inputs, ...}: { + imports = [inputs.flake-parts.flakeModules.easyOverlay]; + + perSystem = { + config, + final, + ... + }: { + packages = { + blockgame-meta = final.python3.pkgs.callPackage ./pkgs/blockgame-meta.nix {}; + default = config.packages.blockgame-meta; + }; + + overlayAttrs = { + inherit (config.packages) blockgame-meta; + }; + }; +} diff --git a/nix/pkgs/blockgame-meta.nix b/nix/pkgs/blockgame-meta.nix new file mode 100644 index 0000000000..49c27b4c0c --- /dev/null +++ b/nix/pkgs/blockgame-meta.nix @@ -0,0 +1,64 @@ +{ + lib, + buildPythonApplication, + poetry-core, + bash, + cachecontrol, + requests, + filelock, + git, + packaging, + pydantic_1, + python, + rsync, +}: +buildPythonApplication { + pname = "blockgame-meta"; + version = "unstable"; + + pyproject = true; + + src = with lib.fileset; + toSource { + root = ../../.; + fileset = unions (map (fileName: ../../${fileName}) [ + "meta" + "pyproject.toml" + "poetry.lock" + "README.md" + "update.sh" + ]); + }; + + nativeBuildInputs = [ + poetry-core + ]; + + buildInputs = [ + bash + ]; + + propagatedBuildInputs = [ + cachecontrol + requests + filelock + packaging + pydantic_1 + ]; + + postInstall = '' + install -Dm755 $src/update.sh $out/bin/update + + wrapProgram $out/bin/update \ + --prefix PYTHONPATH : "$PYTHONPATH" \ + --prefix PATH : "${lib.makeBinPath [git python rsync]}" + ''; + + meta = with lib; { + description = "Metadata generator for blockgame launcher."; + platforms = platforms.linux; + license = licenses.mspl; + maintainers = with maintainers; [Scrumplex]; + mainProgram = "update"; + }; +} diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000000..28f3787a15 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,340 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "cachecontrol" +version = "0.14.0" +description = "httplib2 caching for requests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0"}, + {file = "cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938"}, +] + +[package.dependencies] +msgpack = ">=0.5.2,<2.0.0" +requests = ">=2.16.0" + +[package.extras] +dev = ["CacheControl[filecache,redis]", "black", "build", "cherrypy", "furo", "mypy", "pytest", "pytest-cov", "sphinx", "sphinx-copybutton", "tox", "types-redis", "types-requests"] +filecache = ["filelock (>=3.8.0)"] +redis = ["redis (>=2.10.5)"] + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "filelock" +version = "3.13.4" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.13.4-py3-none-any.whl", hash = "sha256:404e5e9253aa60ad457cae1be07c0f0ca90a63931200a47d9b6a6af84fd7b45f"}, + {file = "filelock-3.13.4.tar.gz", hash = "sha256:d13f466618bfde72bd2c18255e269f72542c6e70e7bac83a0232d6b1cc5c8cf4"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "msgpack" +version = "1.0.8" +description = "MessagePack serializer" +optional = false +python-versions = ">=3.8" +files = [ + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, + {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, + {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, + {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, + {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, + {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, + {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, + {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, + {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, + {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, + {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, +] + +[[package]] +name = "packaging" +version = "24.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + +[[package]] +name = "pydantic" +version = "1.10.15" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:22ed12ee588b1df028a2aa5d66f07bf8f8b4c8579c2e96d5a9c1f96b77f3bb55"}, + {file = "pydantic-1.10.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75279d3cac98186b6ebc2597b06bcbc7244744f6b0b44a23e4ef01e5683cc0d2"}, + {file = "pydantic-1.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50f1666a9940d3d68683c9d96e39640f709d7a72ff8702987dab1761036206bb"}, + {file = "pydantic-1.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82790d4753ee5d00739d6cb5cf56bceb186d9d6ce134aca3ba7befb1eedbc2c8"}, + {file = "pydantic-1.10.15-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d207d5b87f6cbefbdb1198154292faee8017d7495a54ae58db06762004500d00"}, + {file = "pydantic-1.10.15-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e49db944fad339b2ccb80128ffd3f8af076f9f287197a480bf1e4ca053a866f0"}, + {file = "pydantic-1.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:d3b5c4cbd0c9cb61bbbb19ce335e1f8ab87a811f6d589ed52b0254cf585d709c"}, + {file = "pydantic-1.10.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c3d5731a120752248844676bf92f25a12f6e45425e63ce22e0849297a093b5b0"}, + {file = "pydantic-1.10.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c365ad9c394f9eeffcb30a82f4246c0006417f03a7c0f8315d6211f25f7cb654"}, + {file = "pydantic-1.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3287e1614393119c67bd4404f46e33ae3be3ed4cd10360b48d0a4459f420c6a3"}, + {file = "pydantic-1.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be51dd2c8596b25fe43c0a4a59c2bee4f18d88efb8031188f9e7ddc6b469cf44"}, + {file = "pydantic-1.10.15-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6a51a1dd4aa7b3f1317f65493a182d3cff708385327c1c82c81e4a9d6d65b2e4"}, + {file = "pydantic-1.10.15-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4e316e54b5775d1eb59187f9290aeb38acf620e10f7fd2f776d97bb788199e53"}, + {file = "pydantic-1.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:0d142fa1b8f2f0ae11ddd5e3e317dcac060b951d605fda26ca9b234b92214986"}, + {file = "pydantic-1.10.15-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7ea210336b891f5ea334f8fc9f8f862b87acd5d4a0cbc9e3e208e7aa1775dabf"}, + {file = "pydantic-1.10.15-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3453685ccd7140715e05f2193d64030101eaad26076fad4e246c1cc97e1bb30d"}, + {file = "pydantic-1.10.15-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bea1f03b8d4e8e86702c918ccfd5d947ac268f0f0cc6ed71782e4b09353b26f"}, + {file = "pydantic-1.10.15-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:005655cabc29081de8243126e036f2065bd7ea5b9dff95fde6d2c642d39755de"}, + {file = "pydantic-1.10.15-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:af9850d98fc21e5bc24ea9e35dd80a29faf6462c608728a110c0a30b595e58b7"}, + {file = "pydantic-1.10.15-cp37-cp37m-win_amd64.whl", hash = "sha256:d31ee5b14a82c9afe2bd26aaa405293d4237d0591527d9129ce36e58f19f95c1"}, + {file = "pydantic-1.10.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5e09c19df304b8123938dc3c53d3d3be6ec74b9d7d0d80f4f4b5432ae16c2022"}, + {file = "pydantic-1.10.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7ac9237cd62947db00a0d16acf2f3e00d1ae9d3bd602b9c415f93e7a9fc10528"}, + {file = "pydantic-1.10.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:584f2d4c98ffec420e02305cf675857bae03c9d617fcfdc34946b1160213a948"}, + {file = "pydantic-1.10.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbc6989fad0c030bd70a0b6f626f98a862224bc2b1e36bfc531ea2facc0a340c"}, + {file = "pydantic-1.10.15-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d573082c6ef99336f2cb5b667b781d2f776d4af311574fb53d908517ba523c22"}, + {file = "pydantic-1.10.15-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6bd7030c9abc80134087d8b6e7aa957e43d35714daa116aced57269a445b8f7b"}, + {file = "pydantic-1.10.15-cp38-cp38-win_amd64.whl", hash = "sha256:3350f527bb04138f8aff932dc828f154847fbdc7a1a44c240fbfff1b57f49a12"}, + {file = "pydantic-1.10.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:51d405b42f1b86703555797270e4970a9f9bd7953f3990142e69d1037f9d9e51"}, + {file = "pydantic-1.10.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a980a77c52723b0dc56640ced396b73a024d4b74f02bcb2d21dbbac1debbe9d0"}, + {file = "pydantic-1.10.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67f1a1fb467d3f49e1708a3f632b11c69fccb4e748a325d5a491ddc7b5d22383"}, + {file = "pydantic-1.10.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:676ed48f2c5bbad835f1a8ed8a6d44c1cd5a21121116d2ac40bd1cd3619746ed"}, + {file = "pydantic-1.10.15-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:92229f73400b80c13afcd050687f4d7e88de9234d74b27e6728aa689abcf58cc"}, + {file = "pydantic-1.10.15-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2746189100c646682eff0bce95efa7d2e203420d8e1c613dc0c6b4c1d9c1fde4"}, + {file = "pydantic-1.10.15-cp39-cp39-win_amd64.whl", hash = "sha256:394f08750bd8eaad714718812e7fab615f873b3cdd0b9d84e76e51ef3b50b6b7"}, + {file = "pydantic-1.10.15-py3-none-any.whl", hash = "sha256:28e552a060ba2740d0d2aabe35162652c1459a0b9069fe0db7f4ee0e18e74d58"}, + {file = "pydantic-1.10.15.tar.gz", hash = "sha256:ca832e124eda231a60a041da4f013e3ff24949d94a01154b137fc2f2a43c3ffb"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "typing-extensions" +version = "4.11.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, + {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, +] + +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.8" +content-hash = "2a2fe996845675e1cdf7d80834919eabb819353f394f00a3adbaf0f42e7351b0" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..ca55558b60 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,37 @@ +[tool.poetry] +name = "meta" +version = "0.0.1" +description = "Prism Launcher meta generator" +authors = ["Sefa Eyeoglu "] +license = "MS-PL" +readme = "README.md" +repository = "https://github.com/PrismLauncher/meta" +documentation = "https://github.com/PrismLauncher/meta" +keywords = ["metadata", "prism", "launcher"] + +[tool.poetry.scripts] +generateFabric = "meta.run.generate_fabric:main" +generateForge = "meta.run.generate_forge:main" +generateLiteloader = "meta.run.generate_liteloader:main" +generateMojang = "meta.run.generate_mojang:main" +generateNeoForge = "meta.run.generate_neoforge:main" +generateQuilt = "meta.run.generate_quilt:main" +updateFabric = "meta.run.update_fabric:main" +updateForge = "meta.run.update_forge:main" +updateLiteloader = "meta.run.update_liteloader:main" +updateMojang = "meta.run.update_mojang:main" +updateNeoForge = "meta.run.update_neoforge:main" +updateQuilt = "meta.run.update_quilt:main" +index = "meta.run.index:main" + +[tool.poetry.dependencies] +python = "^3.8" +cachecontrol = "^0.14.0" +requests = "^2.31.0" +filelock = "^3.13.1" +packaging = "^24.0" +pydantic = "^1.10.13" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/static/forge/forge-legacyinfo.json b/static/forge/forge-legacyinfo.json deleted file mode 100644 index 28e45244f8..0000000000 --- a/static/forge/forge-legacyinfo.json +++ /dev/null @@ -1,3712 +0,0 @@ -{ - "number": { - "1": { - "releaseTime": "2012-02-03T03:43:02", - "sha1": "3b67ffda89f4d8c7625a00aee23c270ffef642c8", - "sha256": "090bc30701b942efcfcbca6ccc22cb16aca74e12f16d47e0c026508d1e115cb3", - "size": 385340 - }, - "10": { - "releaseTime": "2012-02-14T11:17:12", - "sha1": "b08fd9b88a7c4f2773462a501ec2a37e8a71f177", - "sha256": "a93fbce5ebf0046cec068db167ca380b207b6a2092b2487d438bf0b6c14b4509", - "size": 446516 - }, - "100": { - "releaseTime": "2012-04-26T14:52:52", - "sha1": "9107451e325dd60b21fd31db956e2cba7ad78777", - "sha256": "09e6242404f8f1d1bff77fc1a88ebc650a5db5afd61c1bcaf155a7cccbc38dc4", - "size": 535241 - }, - "101": { - "releaseTime": "2012-04-26T19:15:44", - "sha1": "1ec31c6def402042b240b78b29f62d282dda9245", - "sha256": "6ba717cbb338d02bc517026dde1046ee32b99df869ce444f2c524766cf587ac1", - "size": 539903 - }, - "102": { - "releaseTime": "2012-04-29T03:15:02", - "sha1": "7d27b1cf0bba9084ca9dd40836a591a6f549ab99", - "sha256": "b7d54a5bf528e197b84176feca4c6dfc39e7510dd2b934c01bba4d20b3fd5a05", - "size": 539984 - }, - "103": { - "releaseTime": "2012-05-01T17:41:18", - "sha1": "ff0f5ba142f93216e3414a62a35bc0ea63c04e2b", - "sha256": "035dc0c527456593aabf95e5af6a353244deba2c7dd42abc512e87877be09a21", - "size": 539984 - }, - "104": { - "releaseTime": "2012-05-02T10:40:54", - "sha1": "1267987ae92e7b33807f64cb878bd69d0237929e", - "sha256": "cfc17f996343fa607af6913804e7aee3a88ec75b70c5e95d5189b96fbadf9312", - "size": 540020 - }, - "105": { - "releaseTime": "2012-05-02T11:15:28", - "sha1": "3107da18680cc7a4c8da48a87987c6b54c1cdbd3", - "sha256": "fe79e721c75454eec6b9c4fea77f07ca5ed9ed6a5f89d7339f13bf665e9fe044", - "size": 540020 - }, - "106": { - "releaseTime": "2012-05-05T21:26:20", - "sha1": "073fe35f1465b042cc1a404ee162a78be07a3118", - "sha256": "699943f76f8eba5bece28bad466c2510513432b5916831d8eb873ba9e55f8f07", - "size": 540033 - }, - "107": { - "releaseTime": "2012-05-05T21:48:02", - "sha1": "5a94773af77831db154836b33c31b0572f906e2f", - "sha256": "450496d301b3a5929c833561ef860aa845fe42a48b7ba40628134cffd6324480", - "size": 540049 - }, - "108": { - "releaseTime": "2012-05-26T20:33:00", - "sha1": "91a5cb7e60c573c6f5700afc9a61dc987c90837e", - "sha256": "88b9d9050a889839ff260accfc1f2cb70320891b88f74f23ef7630000755e59c", - "size": 540051 - }, - "110": { - "releaseTime": "2012-05-27T05:14:54", - "sha1": "f14ac41dc2c3dfcbb31ca9625b0ddde5ee50e60c", - "sha256": "b421c75a9635633c2406779d94ac185fd907cba9e398d7f40d1397e9493111b1", - "size": 682378 - }, - "111": { - "releaseTime": "2012-05-27T05:52:26", - "sha1": "37ea7bd0a7a4643e405d1930306e0ae48eb6fa72", - "sha256": "844cf9d1a842f680c40aa64b442e08575ff14c776732bfef02fb836d7150336c", - "size": 692653 - }, - "114": { - "releaseTime": "2012-05-27T07:49:00", - "sha1": "6656816ca2a9b8ee781b21ffe397351c1cff242b", - "sha256": "7b4d0d01792533479630ec61caa056821d5faf49a94976de6809b5bc5ea6407d", - "size": 692890 - }, - "115": { - "releaseTime": "2012-06-02T17:05:10", - "sha1": "fa56c8a9ba515b4ebafa29a9d8b463844d8cefbf", - "sha256": "28376c420dc439a2972aee59fbf5369e4662abb9f4255f215efbc07aa43103f5", - "size": 699345 - }, - "116": { - "releaseTime": "2012-06-02T19:29:02", - "sha1": "a0bc1631878d6c82e90cc8c8428d531e616d0b4d", - "sha256": "3689d1c1d54d408872909b6864b91c16822f13b6c000aa6d4b7c50fc0ee103a5", - "size": 771433 - }, - "117": { - "releaseTime": "2012-06-03T00:39:56", - "sha1": "fad26f06303d49516f30bd9787c60254b9d64832", - "sha256": "0f6ab352cbdde133519af2446cb1e95596ee83bd7862d0396ce176fe6f58a289", - "size": 793622 - }, - "118": { - "releaseTime": "2012-06-03T01:06:46", - "sha1": "2417311461424c258b1ae75b3c2aca5ed8a93212", - "sha256": "750ce4702906336213c8cebf38f51f42ab32a5097b54850b8a9c2da6cba4f165", - "size": 795988 - }, - "119": { - "releaseTime": "2012-06-03T11:46:04", - "sha1": "9a729ba30e68d06dc1299bf7e2c11f0df2014076", - "sha256": "9eee8d3488c055f54741c865dba925ed0f20fc0fbc93beee930137dff6524099", - "size": 795981 - }, - "12": { - "releaseTime": "2012-02-15T07:01:32", - "sha1": "7a5585b8d63e14d27550a0caa326da98842ba75b", - "sha256": "bff27ad5c4370e4f1b83766f57f193cd69e9ee4918fec123230144f36fd0779d", - "size": 446491 - }, - "120": { - "releaseTime": "2012-06-05T00:26:38", - "sha1": "e46ce772d92952ed79f4dfc4ab3a401855f9ac45", - "sha256": "ac7b487bc153a2d0de283e644e5c573c4937d5c2ee436751d2e5d3f99a91bbbc", - "size": 795970 - }, - "121": { - "releaseTime": "2012-06-06T02:03:28", - "sha1": "4106e1a59253e2cc4ba3c553e1bcfd9363838215", - "sha256": "bdcc1bfa0bf290592de5da011b998b30b88b911a4e1d00ff4a2bd882eb1e1b96", - "size": 796825 - }, - "122": { - "releaseTime": "2012-06-06T07:11:36", - "sha1": "5e9dc2ee5aae4b6dbebc2d03200f0a2e36dfc6ef", - "sha256": "002c98545240753ae60a8e9f0d6067056332b02ab313e5da11749e2c68ab82c1", - "size": 796287 - }, - "123": { - "releaseTime": "2012-06-06T08:16:50", - "sha1": "b8e119c79d6c45a1f8b9816f916426b5015b2a03", - "sha256": "b7ebbaf7f9f6d8070746cac75659bfa55fe7007ec5f8297d7ea7ab4578a48dea", - "size": 796331 - }, - "124": { - "releaseTime": "2012-06-06T09:12:32", - "sha1": "cd06a21016af921260658e2bb72bac0278bd19f1", - "sha256": "3510025daeab7f07afe9f8c454d201c21a0256c00ce5944472291bd6986403b1", - "size": 796364 - }, - "125": { - "releaseTime": "2012-06-06T10:39:50", - "sha1": "730910dbf2756723b0bda64b23d1b86e6e2e360c", - "sha256": "00488c996a010a6544b0c9567cbf52576a09ca960a5071f0d0c96ed3610a3fa1", - "size": 796361 - }, - "126": { - "releaseTime": "2012-06-09T18:07:04", - "sha1": "f936f629b58aa9a26423e7d31fac1016df2ed43e", - "sha256": "c43a7b4dfd7fdf9ce1de709568323933d195ce5d091076183023221ea7868e9e", - "size": 798733 - }, - "127": { - "releaseTime": "2012-06-09T23:23:20", - "sha1": "277b3a9e14efb646541225de6fdb4ac22439a6c0", - "sha256": "8e6bda4d4c0b323729a158f11c8b384429eeb37c5edc770ded4d54c35a8e9345", - "size": 805738 - }, - "128": { - "releaseTime": "2012-06-10T01:57:00", - "sha1": "cf44068b9c694278dc56bf3e912bfb42915a0910", - "sha256": "cfa22e39605b31af73f9dcce17d26c575a5e11d878afaf27dc50b6237f5c05c4", - "size": 805907 - }, - "129": { - "releaseTime": "2012-06-11T14:16:08", - "sha1": "25c1928a77454207548479ed3365b9ac5b6cb724", - "sha256": "a346c164275e470e84e02547c5b78c1ecb9e7a5c273340f7f5722f3639a6cac7", - "size": 806759 - }, - "13": { - "releaseTime": "2012-02-16T20:12:54", - "sha1": "7d833787cd732c36183e83078d5059abf9d2d86f", - "sha256": "c2f2f379cc9eb550eb3db1eb36ecaf2f99fefa0ae34a6db3e565beedfddf7f79", - "size": 446490 - }, - "130": { - "releaseTime": "2012-06-11T14:45:56", - "sha1": "646de970a77cecb90cb4e95a0f20dcd6836ea427", - "sha256": "21e8559b168e199d00a8d107c89ed683b7e430690c2682abc0d510e850084b23", - "size": 806775 - }, - "131": { - "releaseTime": "2012-06-11T15:50:10", - "sha1": "e52706d1ffa3958da1d1ca7dbb4c98c6a91c00c2", - "sha256": "2a90471ccb7636fb65fe3604490c24e1dcb412236883a5d691586146636029c8", - "size": 806773 - }, - "132": { - "releaseTime": "2012-06-12T15:51:22", - "sha1": "c74ac5310eb0459799bc5916564b595f9c8a0558", - "sha256": "1610df104d38406d0f241918a893210503202d1a28f6510029ba612efa5abb1f", - "size": 806787 - }, - "133": { - "releaseTime": "2012-06-13T21:54:32", - "sha1": "9a765110a452eb1c729cd9d1dd72b75ac46a9cc5", - "sha256": "855ecc4c169efca986dea547ba94aeb52d6c8ca696aa94ef727351f92350ea23", - "size": 807737 - }, - "134": { - "releaseTime": "2012-06-13T22:13:02", - "sha1": "3859eb4e96ad8b596648c654603be8c7a2880aed", - "sha256": "237814d9e0f086c066659578fe42ff7cada5dd93b9a2fb9076551d5cac7ae22d", - "size": 807730 - }, - "135": { - "releaseTime": "2012-06-13T23:11:14", - "sha1": "7ca221567a9b8be19ed242cf3027ef85cb5831b5", - "sha256": "ca358444aca70dd229688f4f9aa5c69f6f54362f232f1ff745a15055137e6a72", - "size": 807734 - }, - "136": { - "releaseTime": "2012-06-15T21:13:22", - "sha1": "351d8168796136b453ff07ca3498d079005eecf2", - "sha256": "123c1e3e77f6709bf1074ff8186793ab1574ebb8c137d829a44757b46e1e593e", - "size": 820929 - }, - "137": { - "releaseTime": "2012-06-16T01:31:16", - "sha1": "43b5cedd31124e38d9ac45278f49c3c1b760bc91", - "sha256": "17380821b55e688afe499cd58e1ffa8d08ad1c5a6d0d709a0323a1ee8d615be7", - "size": 820938 - }, - "138": { - "releaseTime": "2012-06-16T13:29:30", - "sha1": "bb06fb63150c309298b5d13fd1386f815a8cb58c", - "sha256": "e7f981301aa518465c22530b8987ca64fc8ef732037ef1e868c7a30effee8303", - "size": 820935 - }, - "139": { - "releaseTime": "2012-06-18T20:20:22", - "sha1": "fa14db691e5caecf901bc03db26f62a41398f0bf", - "sha256": "3745c6f8ec04beb978d3ffefab8093233160fa16c44a14c77ec3ce23b4f864f4", - "size": 824101 - }, - "14": { - "releaseTime": "2012-02-18T10:59:08", - "sha1": "a2e9d478829c8eeef907a2e9fb026b7f7b06d503", - "sha256": "4d8639e623029834b8facb5e773a099ec9b5137e9b5c66acf8d38f9cf08213b1", - "size": 446490 - }, - "140": { - "releaseTime": "2012-06-19T13:54:46", - "sha1": "0393025b622c1963789de2de8cae76bb80a9a40c", - "sha256": "4aa5efe6548af749acdf3805fc6dbbcd78c1dd12f19bbff89e2bab84662242fa", - "size": 824100 - }, - "141": { - "releaseTime": "2012-06-19T14:33:18", - "sha1": "172f03f6df59bc600a325e2eed9252f1466218ca", - "sha256": "3b256df597d86d8650e808846d363e667dce2f467db84576397944fbc4d83522", - "size": 824099 - }, - "142": { - "releaseTime": "2012-06-19T20:50:12", - "sha1": "9bb6c62055657637755ebdfb2c01f1d5be4eb86f", - "sha256": "43661e039a129d00f44ccef4a383c134ba5bb8f66e22252576fd5ae8e91b349b", - "size": 742043 - }, - "143": { - "releaseTime": "2012-06-19T21:35:44", - "sha1": "55aae8a09af8275044e83731e160490e3f96e4f0", - "sha256": "16a65c0fc67a7b52df3bc09924ab9bd860f716d5134e3ec843779d2e2c833441", - "size": 742047 - }, - "144": { - "releaseTime": "2012-06-20T02:27:20", - "sha1": "7af758710c159b940e1a1acce61752b769b9c8c0", - "sha256": "e49b93b985344c3eb5fc0fdd84a3a410c271c713188a969585b2c30f8b1632b2", - "size": 828804 - }, - "145": { - "releaseTime": "2012-06-21T04:10:00", - "sha1": "4574a57cd18f729f3783569dda3414af955a5a7c", - "sha256": "ee338a711e8fdd938813ef85aac9018e510dcfda142e01af2c4d48f66de266f2", - "size": 833053 - }, - "146": { - "releaseTime": "2012-06-21T05:12:52", - "sha1": "a9434adf87ddbaaa0ee766a681796ec2c6baaa3c", - "sha256": "922fb4f5ea0d6c143a2fd7d0ec5b0e816239ada14330553d874bb82832608497", - "size": 833072 - }, - "147": { - "releaseTime": "2012-06-21T06:14:56", - "sha1": "e34ab34210f9ba2ef911a9d8261bee46e58d1181", - "sha256": "cd90d2fb96fafaebbd8832b82996718b2ce6687867c98b9b8b10131e5da0e6e1", - "size": 833263 - }, - "148": { - "releaseTime": "2012-06-21T15:33:06", - "sha1": "269b4dcf1895eb1c861a45596fbdf03a7d952b03", - "sha256": "e8553aebad4aba8f4a3501b7c66ca9ba9e1a72bcce1653943da2b5fdc02be2d1", - "size": 833383 - }, - "15": { - "releaseTime": "2012-02-21T00:08:16", - "sha1": "0c288624b936ae51e74849185db9456b0f6eaecf", - "sha256": "839d7cd8f71501ee7bd2f8bcbd05f9be15f1d28223ea92a7715e59e38f30ef37", - "size": 461232 - }, - "150": { - "releaseTime": "2012-06-22T17:50:02", - "sha1": "69992524b6dad50b7a1f134084d6723941600178", - "sha256": "b377f8001a182855709ef08f002d6426d3d1704b04a3abce7162f688628411bc", - "size": 834008 - }, - "151": { - "releaseTime": "2012-06-22T18:53:06", - "sha1": "390e254050b5d437c52fd3372a9bf5e7af82d190", - "sha256": "8ebc2bf8dd8afd0d17607df892276827cee6accfefe02ddbcdcc0d1fa622cc37", - "size": 834136 - }, - "152": { - "releaseTime": "2012-06-24T14:51:06", - "sha1": "3457f99c4572e65c0c453825131cafce62a403a3", - "sha256": "606e7e860725a3beac211c8814377be05fce2f0d4d31e6591a08a56124883e68", - "size": 834135 - }, - "153": { - "releaseTime": "2012-06-26T12:14:12", - "sha1": "a02b59b5eba868c9ef653e6372dabacff0d7c185", - "sha256": "f71fa6baf922ed05cf02d47dd55eed16e9d351b7aa9cd75be92623d278c2c6e2", - "size": 835486 - }, - "154": { - "releaseTime": "2012-06-27T14:38:54", - "sha1": "1aab062c85fea0f607b34a9aae213de23d557219", - "sha256": "aa20ffa2bc0395657185a58c32e51d23c6485fe9a11e49a6488d5db7c52474a6", - "size": 836032 - }, - "155": { - "releaseTime": "2012-06-27T17:24:36", - "sha1": "072165b010760b236cd60d9270e0ca691a0a1eb4", - "sha256": "e77a492dfd41732cd31ed066419247a12bbdad81a5035f082cbe559c3ee3904e", - "size": 835994 - }, - "156": { - "releaseTime": "2012-06-28T12:47:50", - "sha1": "e65ddb0a00327cc3042977dfb4b3cf7d2c3f9141", - "sha256": "69cffff633cf417d15def003152b1219deeac932905331e1e355a579de8d6610", - "size": 835993 - }, - "157": { - "releaseTime": "2012-06-29T14:06:30", - "sha1": "875565aa589b1c56332f3732f1830b5ada72f353", - "sha256": "b93a825687291259d9ecee57f861a92f876b85c974ef596498b25f27e2f82209", - "size": 835994 - }, - "158": { - "releaseTime": "2012-07-01T06:58:20", - "sha1": "a6d07ec81f663969efdefdb0da0a01c3bd7e61a1", - "sha256": "af68569fcabc2f46331e296e7ce6f4a38d664245dee702827c6f301f00f767b9", - "size": 835995 - }, - "159": { - "releaseTime": "2012-07-02T20:30:34", - "sha1": "1902fd2cee020fb0cc37323df70123c9f1ef521f", - "sha256": "8e95e919e287c486745da1abb4f4f514790dfa4e03a7cd667ff6dcad3b7ea950", - "size": 835994 - }, - "16": { - "releaseTime": "2012-02-21T01:08:40", - "sha1": "e122dd4424507cb886cfaf17d74d32f0b5c27976", - "sha256": "73913abfd6fc33e5fda8d42ed3877e1d6c7ebf693add23727450411ac48aeee8", - "size": 461230 - }, - "160": { - "releaseTime": "2012-07-03T22:13:38", - "sha1": "ffce964d80f804b44f41f9445720cca889df82e3", - "sha256": "428e96518a844bab63f7b7baaddd47fc83596a161827d0776ab95a3cf5e87c97", - "size": 840432 - }, - "161": { - "releaseTime": "2012-07-09T13:47:08", - "sha1": "9b577c7c90c075345c9edbbbf1e9e1b04d526a5e", - "sha256": "159f2f456214b343e12aebfd5f4c6a2aa25534f2de04ef1518c058d736a6dbcf", - "size": 840533 - }, - "162": { - "releaseTime": "2012-07-09T16:06:48", - "sha1": "0c2899851e84610ff9f68178d8982feb2994e30e", - "sha256": "addc741a97b22b20521f1155437215b04318e6a66bd5a65c8c132283b66efd1b", - "size": 841554 - }, - "163": { - "releaseTime": "2012-07-09T21:41:18", - "sha1": "75d6ec38c6ab0667583a5a7253004c739b8e628d", - "sha256": "1a5acd0213bd0e915b83b995ecdd99c0de9d1ecb1c1e732eb044fb79363a1059", - "size": 841544 - }, - "164": { - "releaseTime": "2012-07-10T17:05:40", - "sha1": "93be0a3149c333402a7696a23a45f4ffdb901ae4", - "sha256": "00e8168f96459964e97a37bcfe6c6f83f46d0825f00fbf96b8fec6d2439292eb", - "size": 841547 - }, - "168": { - "releaseTime": "2012-08-01T02:52:16", - "sha1": "1297549223eb2fcf39228b2ef9f572d8fb843dbe", - "sha256": "fed79cb7f26711043db245577f0b826b948cc2184219380b37277782604049f9", - "size": 841565 - }, - "170": { - "releaseTime": "2012-08-01T03:06:10", - "sha1": "b5076149dc1890bdf7df986d77b2a9f78b3873db", - "sha256": "ee62fb09ceebd3a73642a6ba9218f2323fb6f450246355d3a7dfd74b62e0d0b8", - "size": 841564 - }, - "171": { - "releaseTime": "2012-08-03T16:59:00", - "sha1": "65fe624282d24b03e2a35212f9ab6c5e3e10a5e0", - "sha256": "dd6f66865bf04b89fd80a5041c6f9e81e0caefd266097447c73d7e924f67875a", - "size": 841570 - }, - "172": { - "releaseTime": "2012-08-11T02:06:04", - "sha1": "c965a2b9ec9b32ca0570248c99bc1536cf264be9", - "sha256": "16b6cc8b3479318b8a4f438536622852fd553c191fe4a327f0db5d6568c1d48d", - "size": 1056844 - }, - "173": { - "releaseTime": "2012-08-11T04:15:12", - "sha1": "27de803e547a20deb519d1f4a46bda7b639ac0d3", - "sha256": "0e66efa38a4da2e2455701a6107116269c3c5a8110609c05ca54b95035480a52", - "size": 1062629 - }, - "176": { - "releaseTime": "2012-08-11T16:25:50", - "sha1": "c7dc3e0b343c0be64fe7158b05d48ded492c1c90", - "sha256": "dab06042d5fa6737c106d573c3f7ae7392674c1b955d9bf65964fa362692ddb7", - "size": 1068704 - }, - "177": { - "releaseTime": "2012-08-11T17:20:10", - "sha1": "32cfe2f9b93ee0d4cd02089f573a12dcbeb37fa4", - "sha256": "627cd1d8fcf661457cb55f96b83221051159d0ecd7423baacb7432c1893ba7f2", - "size": 1068703 - }, - "178": { - "releaseTime": "2012-08-12T06:19:28", - "sha1": "eb19f25f008fd60e23db74eb5fbae1fbcca48dbf", - "sha256": "bc4b85d4d1f1a828dbce1ad9a46e0dc4a258f32ae463007328802a4d9f959c7a", - "size": 1071601 - }, - "179": { - "releaseTime": "2012-08-12T15:37:14", - "sha1": "aee8717d6781530b2e311b89a0a71fcca58b71fb", - "sha256": "6ee6271971e179158f232104c7a6c804661d71b09633a58229bfa6e4ac733da2", - "size": 1071601 - }, - "18": { - "releaseTime": "2012-02-21T17:14:26", - "sha1": "e348ff6d988c61d98b8a560d7cddc965e2d81482", - "sha256": "a639c9d4f68aefc3c6fe8ed32081e41c67fb6a489a87bcf6a42030c24a1bd136", - "size": 461226 - }, - "180": { - "releaseTime": "2012-08-12T21:46:22", - "sha1": "10dcdc2ea96ba2b86836e67f5569f0f1b895cb9a", - "sha256": "2a48a0d307111333f0030f1799f7e6a79c0efdb30b214060b3bf290d26e77f4b", - "size": 1072919 - }, - "181": { - "releaseTime": "2012-08-12T23:01:26", - "sha1": "f42f43f5562789b2da8eda6598b3d5cfd63720af", - "sha256": "f930595914b8ec50f5e8d9a6bd2842455017fa0802e0a7e09a03a1464b4fefe6", - "size": 1073492 - }, - "182": { - "releaseTime": "2012-08-13T14:20:16", - "sha1": "649fb921f3209dee50991bb8785b245d33e878a7", - "sha256": "f488e3d262d9445b853c8560035d303b03099fe562c0401313e403a913eb628a", - "size": 1073493 - }, - "183": { - "releaseTime": "2012-08-13T23:33:08", - "sha1": "6b278b91c68e8b013ae58c5796c4e2cb9cec7c37", - "sha256": "abccf353a3626161ccb6efd34c93fa1bb3d388ef28662524fbe2841f531b7ff4", - "size": 1106697 - }, - "184": { - "releaseTime": "2012-08-14T00:09:52", - "sha1": "6ce09190d2660c7ca25f60bba02a3ea70072cc60", - "sha256": "d1786b21227630227fa0db5dcc451b690e8e4522dc8f5b108d30dd13728bfd77", - "size": 1106701 - }, - "185": { - "releaseTime": "2012-08-14T04:44:38", - "sha1": "5e2cba3e9e81c1ab11b10c2c47b5b010a06e921d", - "sha256": "324d235979e59bfcaf1a2573b921231357d00940c83c1346b926fbde9e90c19c", - "size": 1106693 - }, - "186": { - "releaseTime": "2012-08-14T06:41:56", - "sha1": "89b4118b59459c9643b3de32373303d04a27e5df", - "sha256": "e0f4a04188d3950e3de4131a394b354d551b657d1fadfd0297b16d708a8156e2", - "size": 1106707 - }, - "187": { - "releaseTime": "2012-08-14T16:07:58", - "sha1": "a9afc5ba72b8224a91cdedc4f10f47ae5eecbe3e", - "sha256": "cc52a1c5cdf0539e86fb83535e30ac21d14d2bd2083c3667edd177101cbec94e", - "size": 1106910 - }, - "188": { - "releaseTime": "2012-08-15T01:04:26", - "sha1": "a8526b0b84ba5d853cacdb25a568a926e90f5674", - "sha256": "6f378334e5aff66e48d727e640db7c49067c932cccac018b333a8061870b1409", - "size": 1108814 - }, - "189": { - "releaseTime": "2012-08-15T02:00:36", - "sha1": "4ee137f2a60010981a021cd39705b773a86a342c", - "sha256": "999c0cda3d1f98cf1cb1ac3eea80ef2029d44d0ab7f200971453415c26383a6f", - "size": 1108815 - }, - "19": { - "releaseTime": "2012-02-22T12:45:24", - "sha1": "a543b0d8607847ab739ad0b4bc109d8b5eb9e36d", - "sha256": "9863223a74fb8b09a6de07818708c52113b951852b8354de2139fe24689a900e", - "size": 457000 - }, - "190": { - "releaseTime": "2012-08-15T03:59:52", - "sha1": "7c8e296dd20d0a099d4ffc0ed6aa2f528844c098", - "sha256": "32b390a19cafc75c66292c547fde2349326a93e0df4db261a26ce34745a77c00", - "size": 1114702 - }, - "191": { - "releaseTime": "2012-08-15T04:20:00", - "sha1": "35c3abea886ffc85f00234638953b24c52feabc8", - "sha256": "9c93b994cf3627833efc96d0b659aa11e4d65389f5cb03966a3c564a336799e0", - "size": 1114733 - }, - "192": { - "releaseTime": "2012-08-15T05:32:22", - "sha1": "3bfce4ff38d083e21ac7565435e11de73a1355b3", - "sha256": "6ee2d016c435d16d5025f50cf2fb37a6ef849627f8cf88d9df498a2591ffd15b", - "size": 1114783 - }, - "193": { - "releaseTime": "2012-08-15T05:41:58", - "sha1": "6f9560278fbf8ba6448aae4e9e314bfdd95f66d0", - "sha256": "437689a1bdd935a29ba5dcbc9883e1c0c014a8686fa40672115a4699dd3c7c3c", - "size": 1114790 - }, - "194": { - "releaseTime": "2012-08-15T17:07:10", - "sha1": "15506c8f8035238775e48c7f2b1c9604a7237567", - "sha256": "30cbe1c1aa0ae1c694765f044801cd9e041078f4e47938c26a8d4e4f5d174e68", - "size": 1116652 - }, - "195": { - "releaseTime": "2012-08-16T04:18:30", - "sha1": "8591aea55c6452626abdfef9a710f2912b071496", - "sha256": "078ddbbad79ea0a9c8fd4d83560a24b27fd14dbc0253b15811c6db3954517d21", - "size": 1117510 - }, - "196": { - "releaseTime": "2012-08-16T04:26:12", - "sha1": "4dc7d314e1d7e815745298d9849f16326d98a4cc", - "sha256": "82a2747bea9aa044ddd384e40229f4380e66544a27c77ff8611f0796571db3d2", - "size": 1117510 - }, - "197": { - "releaseTime": "2012-08-16T04:39:20", - "sha1": "06d558e96e443cd20f28890f60bd846b24a89345", - "sha256": "3bf063bffccc8203c8bb9b16410e38b73d7d061516fabe0d55d8ebec9b3d8341", - "size": 1117510 - }, - "198": { - "releaseTime": "2012-08-16T04:45:46", - "sha1": "ad7c3988568eba9b0a6fb28008fcc2ae7d492baf", - "sha256": "9a06b85b20fe04ce9dee8ddcdcb2984631f97dc277158cdd7dc00a7399d8fdf2", - "size": 1117510 - }, - "199": { - "releaseTime": "2012-08-16T06:51:58", - "sha1": "a43116a04d2653b21cf1482ab3127f5f2e1350df", - "sha256": "cd3f5e0c8052b1323f02f6fe95caecc0001faa1e4b7197e47d7938870c23697a", - "size": 1117518 - }, - "2": { - "releaseTime": "2012-02-07T03:25:24", - "sha1": "17729ac3f56a9c6b19884b0b9f6176c01b6577c9", - "sha256": "ac32701e81a26d81bde327648a11238bb252852fe47ebf5f1f1ba7d2e89732bd", - "size": 410393 - }, - "20": { - "releaseTime": "2012-02-22T16:59:28", - "sha1": "825fce2c50b8982ff8dc55c1726f809b355dbac0", - "sha256": "8435098217c1525f78fd0d496e7297925a3f19a0e3a5b1cdcac228ac4287f3c7", - "size": 460010 - }, - "200": { - "releaseTime": "2012-08-16T14:50:56", - "sha1": "13cd134bd2c71e8559485cf1f3ffb1bd6fe8db36", - "sha256": "7623739f26a54d6921459194e09019e5f0a1697aa84f6a73360dfd81f89aa179", - "size": 1118509 - }, - "204": { - "releaseTime": "2012-08-17T08:15:06", - "sha1": "44a706ddf785343411c042e1117b2514e6bb81a0", - "sha256": "02be25f1ffdcef9d1df61f4a5b7c72a2801c485b092f218be0fe534bd5f34df6", - "size": 1118645 - }, - "205": { - "releaseTime": "2012-08-17T14:36:38", - "sha1": "2dcd664c9f3d49e775139059def2fd34f473b500", - "sha256": "cc7341808da6852fe8f911faae63eb3fc15f29a0041be3054d719cdf0fd94c49", - "size": 1121958 - }, - "206": { - "releaseTime": "2012-08-17T15:11:38", - "sha1": "9dd3cd02e41d6ebdd4f4e6a27b8c623f1669f15a", - "sha256": "ac6522e7e98fbd1b3434d8cf017b6c99b410d2d9e9cebcaa21eccd22f41014c1", - "size": 1122529 - }, - "207": { - "releaseTime": "2012-08-18T00:54:36", - "sha1": "cabf2158a95d36514ac42877df9b324ff82cc692", - "sha256": "54554e8040ac82a63177c3c3f06b037076a1c4a74acf9dae8fbe143d5ab36726", - "size": 1122552 - }, - "208": { - "releaseTime": "2012-08-18T03:20:28", - "sha1": "6bc793175417d57ee6d8fe2953e80b622e51e30a", - "sha256": "0d4c2c845f26f03d05465ecc9d4dfe89e645d7915ae09d380724b8aefd4ad73e", - "size": 1127644 - }, - "209": { - "releaseTime": "2012-08-18T18:31:40", - "sha1": "1e2a7d448a81df1b87b92df5d7654c3b773ce3cb", - "sha256": "0a60f96c58726818a01b3e12d34ee2e64eaa52ab891be28b27319bffa3b25f24", - "size": 1128219 - }, - "21": { - "releaseTime": "2012-02-24T02:44:08", - "sha1": "a26524032331f99cc199c949845d9c21f7ca6220", - "sha256": "a763eaed63cc63795e147ed7fc0e718d50ae884daa0fe6344e2eadae04532716", - "size": 461387 - }, - "210": { - "releaseTime": "2012-08-18T19:06:16", - "sha1": "fb8a39877182075057ab635988a716779ce3c1df", - "sha256": "6e960c40d5ae23921b57dbfde8c90b3b3837219baf046aa110e35041f0922d0b", - "size": 1128955 - }, - "211": { - "releaseTime": "2012-08-18T22:11:36", - "sha1": "8bac076be4e2b1ca18bbc4a5a6dbf428ffe8a000", - "sha256": "de42413d21d609322a5601d5d461f9814bbf04142035a38035af614eede96bcb", - "size": 1128948 - }, - "212": { - "releaseTime": "2012-08-19T00:24:18", - "sha1": "660b131b8c7b5847928325495107d2bf18fc6252", - "sha256": "f4cc8b5a713a14e5712f5e981e9cdcebe1aa79b2f83719a67851d088a19dd176", - "size": 1131604 - }, - "213": { - "releaseTime": "2012-08-19T09:40:06", - "sha1": "a343280c7a069b665ad4892f1fc3efc0204ba273", - "sha256": "3068b0a7e105b7a3bcc40b04836735295c4932bf4e3f41671b00876523111fc6", - "size": 1144787 - }, - "214": { - "releaseTime": "2012-08-19T18:45:34", - "sha1": "9c7461c292717660c860c9dde3a998f80c9db3f9", - "sha256": "df7e911eca3b02cdb53f20bc25e91ff64df2b74e6485703a00834c4ac87949c8", - "size": 1144823 - }, - "215": { - "releaseTime": "2012-08-19T19:03:28", - "sha1": "772542b3aa274c40494aec474a9801e86e832bf3", - "sha256": "4ce688bcebd13c5b3ab37ed9a4ff3f8a8c315f2ddf3495e226e3f1edb9e757f7", - "size": 1144429 - }, - "216": { - "releaseTime": "2012-08-19T21:48:20", - "sha1": "34b05962c8aa58a60420d3276598a3e236ff5faf", - "sha256": "b01354ffa8e7b6f09ba4b8d6b37e2ede984e8bea64af23dbf44ab0905083e710", - "size": 1144496 - }, - "217": { - "releaseTime": "2012-08-19T22:10:42", - "sha1": "1abb0fac2833326264ca74c84b781e7044d52c26", - "sha256": "98ab579eb3ff4253770b676106619a542b27ddc526111bc956dc48d0bcff2339", - "size": 1144596 - }, - "22": { - "releaseTime": "2012-02-24T10:53:16", - "sha1": "f4f11608f49cbfeb025afbb938081540415fc9fd", - "sha256": "078689fbc3fac7d8f5496a1d8a22176d7637e9df7bd11a330727cd7879fff304", - "size": 461389 - }, - "220": { - "releaseTime": "2012-08-22T11:11:14", - "sha1": "0909743af1123f6fe96e01bbf67e4117dd2bb6a4", - "sha256": "d15f10ef045f95d18b7d3dbdcda06cc92148ddae9b21f5e949fa5666bc7ab7f9", - "size": 1156840 - }, - "221": { - "releaseTime": "2012-08-22T14:47:48", - "sha1": "17d16a72551dafcdb66cd8a2c2f1fd7ce5d9b202", - "sha256": "d84a778ddcfd327d3bb91ea80ad8b06c155659380d840e70dc2e4a4ad145c489", - "size": 1156896 - }, - "222": { - "releaseTime": "2012-08-22T14:51:48", - "sha1": "9134a4885e0dbd08d7a9c1b12f5900d1f3f5f7fd", - "sha256": "5b293663cfd379dee0941000331095230b77268bd0a930aee2ea91afacd309cd", - "size": 1156900 - }, - "223": { - "releaseTime": "2012-08-22T16:18:02", - "sha1": "dd89de55a4a0eadddd93a16a67eeab8d2c8e9d00", - "sha256": "8c838d0962c35b7b21dba8ba153241b7dabd30b6202a428f8763eb9951b3e991", - "size": 1160119 - }, - "224": { - "releaseTime": "2012-08-22T19:08:34", - "sha1": "7cbef6b2618c7b05af1327a0dc9d83205ddb47f2", - "sha256": "62348b5f57a64a386387f229f7ff43fc5ba28f3e3fdc0827d84404e3f680a19e", - "size": 1160691 - }, - "225": { - "releaseTime": "2012-08-22T19:38:16", - "sha1": "60d5a20dce93496201aabe29eab2cbd6e1ce7697", - "sha256": "9f587e629d1f68a92c2e908999a08f892bf8082e31a68dd3fabd01fbd93a718e", - "size": 1160681 - }, - "226": { - "releaseTime": "2012-08-23T07:24:58", - "sha1": "45c32c24fa82f2fdc58137ea2f0f91859bd99d02", - "sha256": "ace28642c14b394070c3a56069e67e380fe2374faf830953144ff820f34a8a89", - "size": 1167077 - }, - "227": { - "releaseTime": "2012-08-23T11:58:40", - "sha1": "efe8252c1f118e6dab54ddd3f718270dddfc7fab", - "sha256": "67c9b58b826939fd6d77f2f16a83df317dc2625aa43dd896dbd4bfb56ebf933c", - "size": 1170150 - }, - "228": { - "releaseTime": "2012-08-23T12:13:40", - "sha1": "8657c475ea0eaeda5c16af9098d07d26fa5780df", - "sha256": "0338dab67d7e77926d9e7ce407243f9b534798b83d6e57e17c57d25195888ced", - "size": 1170172 - }, - "229": { - "releaseTime": "2012-08-23T17:57:20", - "sha1": "7d706d763865779048b5cb612617f77947089c41", - "sha256": "1b98bf38c67a37797565caa5199921a50d3a516688fd5bc888ba9e4ea3b8363c", - "size": 1172234 - }, - "23": { - "releaseTime": "2012-02-24T12:49:32", - "sha1": "eb953b9fa97348e07e073b9013ac8c077f3af32c", - "sha256": "368ebff3d647b3d815395e1cb2ff6517414cb692bd25fa47d9f52cecbf80b0ec", - "size": 461398 - }, - "230": { - "releaseTime": "2012-08-24T15:09:36", - "sha1": "1d31483af924041f9737f21323152328a8ada6cc", - "sha256": "b41b781d5c9fcf05798790ae20ae593dc33f588975b8db88be13b0ff09d2bebb", - "size": 1172239 - }, - "231": { - "releaseTime": "2012-08-25T01:34:06", - "sha1": "398aa064fac7a8711bb611f34abee9450be7e426", - "sha256": "9f157b203662140d71384be689c3fadbfcc2bdeb8887085f3a0eeeae17c497e0", - "size": 1172327 - }, - "232": { - "releaseTime": "2012-08-25T07:15:30", - "sha1": "ab0fd12b1ce77ffb6ac24b1ebadb883087200e52", - "sha256": "c39d6d53e2ce7608f0c4263d23a0ffa59824ad767a4df0faf34f5ea4af525ecc", - "size": 1172236 - }, - "233": { - "releaseTime": "2012-08-26T11:34:16", - "sha1": "807402e42a377050fdc551e021ddd3130a6a3eff", - "sha256": "00a042267454a09179b30569dd2da4ae715d7d7f695a34afdb6cf34e5ab8b214", - "size": 1176543 - }, - "234": { - "releaseTime": "2012-08-26T20:35:54", - "sha1": "0bc0f8f52db177d403cc6aa7f74ae8ab341bc6c4", - "sha256": "b4e952468b1c690213d95885ee0c71c5c0323d135158fbb1e6ecc54565ceeae7", - "size": 1181438 - }, - "235": { - "releaseTime": "2012-08-27T21:50:54", - "sha1": "9406efb776d6317ab2c99a686d9eb32c724bdf45", - "sha256": "6eda7136f7c8c4c29fab4e0bf91989712f84cd5c5d5bf6512efbff5d2de9027c", - "size": 1181419 - }, - "236": { - "releaseTime": "2012-08-28T00:59:14", - "sha1": "40a2c71e07d6c108f4e70ed2f5e80669c03fb549", - "sha256": "302ec33f3f3e7a7101a8d60558d1cd43e491324056a46bd097b69d5281e7141d", - "size": 1181495 - }, - "237": { - "releaseTime": "2012-08-28T01:10:16", - "sha1": "8a9651513e473b3e70e13e14b44cdc799523a5e0", - "sha256": "8f4a4eaed30fa8b8bb9a9d83954fd33e8914a09f8c01202c38055286c995da88", - "size": 1181512 - }, - "238": { - "releaseTime": "2012-08-28T17:40:02", - "sha1": "3b5931dfa33f19686e14dff03e2851a7f6bfc8bc", - "sha256": "fee9770baa979f27a089d9608cfd60624000725290af9fb24108f8b26b22b756", - "size": 1181524 - }, - "239": { - "releaseTime": "2012-08-28T20:46:12", - "sha1": "e5d8cb507f2beeb472e966e8a117a3f28f38fe91", - "sha256": "4e99138dd45dd037fef09cc7f0116d82c771b3c9b6dad9d0796c0e9dc73f8b29", - "size": 1188988 - }, - "24": { - "releaseTime": "2012-02-24T22:19:12", - "sha1": "a3296fef41cf016dfe4133c5f284d88218897c6c", - "sha256": "f285d1a5c6f500ca137bcd34ab95453798400c65b429354b24efdfe6102fc9c7", - "size": 460666 - }, - "240": { - "releaseTime": "2012-08-29T13:46:12", - "sha1": "e7a49134aaa40d28432616a9ae1c216489403a9a", - "sha256": "230c37e867963112a9b4202d91bd0ce3dee6bc30d4d528e35eca81d9d35b3d72", - "size": 1189119 - }, - "241": { - "releaseTime": "2012-08-30T13:14:40", - "sha1": "cc37f754904050111c21a85d5554ee8032329c9e", - "sha256": "2d04f456b42c2c748f27baf2bda69bda316ed3a750eb501818736545b3057bba", - "size": 1189119 - }, - "242": { - "releaseTime": "2012-08-31T15:29:00", - "sha1": "27dc3883f07f26237a77372388b549efde958fc8", - "sha256": "ce40adcbbada923db4b7df1ee4d3a9145f83159945df97218b418a2dff903975", - "size": 1190637 - }, - "243": { - "releaseTime": "2012-08-31T15:40:00", - "sha1": "2846ba941a4e2cf5fe46f56e2fa465bb8eec7d2c", - "sha256": "93d67db0f8afbcdf9bc2d17e16a912925c578b1ccf52924a76a110e2ee6a290b", - "size": 1190764 - }, - "245": { - "releaseTime": "2012-09-02T11:15:32", - "sha1": "02e1248f238bbfc8e96be69adbd1213ae64cb595", - "sha256": "94d80d34a4f7ba7586c9f5e41cc846d6d9ccc8fa4c04a0abc7fc12ca7995cdb7", - "size": 1191348 - }, - "246": { - "releaseTime": "2012-09-03T20:30:50", - "sha1": "b8beb94f7491aab93a7227567c1a9fbfdf6b20b3", - "sha256": "983bfa9e67de68e8cb1a691075efef777e5c44e738d0e9a46869d4b84bf84f6e", - "size": 1192956 - }, - "247": { - "releaseTime": "2012-09-04T17:29:10", - "sha1": "4512823cb1bacd1e973e17c89e5cba03c1154fa3", - "sha256": "96727df14ddfe9a115490fe6a94c35848c1ca5019fe8929f676af1b6000aab4a", - "size": 1197219 - }, - "248": { - "releaseTime": "2012-09-05T23:25:52", - "sha1": "fba13830753463a40593edd07ca73c3eb1710cdf", - "sha256": "f01717142dbe7d2c09baab684c937b8c665df6f7d7f47c98f0b68eca0e3aeb7d", - "size": 1197218 - }, - "249": { - "releaseTime": "2012-09-06T21:09:10", - "sha1": "9123f06fc28d3d9d1347a012a1f490265384f70d", - "sha256": "fba2dec051596362f8a32bf6ec571b158f3363ad1fc1c10add548e529a2d4f56", - "size": 1203819 - }, - "250": { - "releaseTime": "2012-09-08T19:23:28", - "sha1": "64f1ebb51653de5e8c43851d58d760511076d283", - "sha256": "47442a0d27aca2e560329369e1c3c451868b9b3de6cb7c2a56c0198dc5dd2c37", - "size": 1207099 - }, - "251": { - "releaseTime": "2012-09-08T22:53:32", - "sha1": "47842089e4e19de881446c452fb7c13a4870756b", - "sha256": "d50d6b69d6124fa9fa75204a8dedcc761bc5331ffa721b59b24e0229974d0ac5", - "size": 1207098 - }, - "252": { - "releaseTime": "2012-09-09T11:39:20", - "sha1": "ad02718c6ca50313953afd8943ba8ccd8b61030d", - "sha256": "6584a2719b4e67ff3dc6b967730d10dff698b7ed50900c6a47331bda1d632a50", - "size": 1207177 - }, - "253": { - "releaseTime": "2012-09-11T13:51:04", - "sha1": "d224df2f61e8492cb8bc4cb6bd7f5b182ca75892", - "sha256": "285422a2b343cc0357b2bba12d6cdf934ac99aaaa2bbe82522598fcd81ce4434", - "size": 1207304 - }, - "254": { - "releaseTime": "2012-09-11T16:30:52", - "sha1": "48c4dc2d0d599bf586ec3631a73194bfcd760cf9", - "sha256": "4f6d04fe16a1bc1ae7fa0b9e5cd85627c72373682e7ae10ac43e8ad835b74c15", - "size": 1220519 - }, - "255": { - "releaseTime": "2012-09-11T16:55:22", - "sha1": "86cc35abd26f0e51e1f75c0cf5df7afe2fa37619", - "sha256": "eae12bb6dee60dc7522046e01d1483fd53cab07cd6b31cdaf12fec31e2204074", - "size": 1220564 - }, - "256": { - "releaseTime": "2012-09-11T17:13:10", - "sha1": "31736f46042ed8d674f4a5b6d07381cdf416f29f", - "sha256": "38f8d4a6132342bb263631bdb6e4e917321ab110d6b9ab14d889205e4c1f1bf5", - "size": 1220577 - }, - "257": { - "releaseTime": "2012-09-11T18:39:00", - "sha1": "c24ca8adb810e4ded4fb3a5a8e96c5dafe36b5a7", - "sha256": "c1d924bd6379b514a78ba1d6e6730d4c40ac4d6c7600acc79f1a1cab1a06fab0", - "size": 1221666 - }, - "258": { - "releaseTime": "2012-09-11T19:33:50", - "sha1": "c3bcb792058b55f7c4fc2d1bf08bc56eefe7a502", - "sha256": "62db5c51dee86894e5695c277773f03a1df4d5f8a228a71122e18ef21cf8a221", - "size": 1222130 - }, - "259": { - "releaseTime": "2012-09-11T20:20:30", - "sha1": "f5f059fa094272cc57a37b29e1f497d7b160723e", - "sha256": "493e697ffdddf636f072d7278c71fad04010a5a30b0aae18190bb27de37b986b", - "size": 1222138 - }, - "26": { - "releaseTime": "2012-02-25T15:44:56", - "sha1": "2f32d8d4fe7ff21a1134cd2336d292e44e3df4b2", - "sha256": "7af8a2d502bea9ad6e5559006a1e92a08401f2dcbdeeb7ddfc10c651c191139e", - "size": 460674 - }, - "260": { - "releaseTime": "2012-09-12T16:02:58", - "sha1": "d94a9fdd3695659255dd56efdf28971526befdbf", - "sha256": "37e34c0b3ad569cc11e9ec9d55b82bdf78e9306df78180379af1f0c03dc32719", - "size": 1305620 - }, - "261": { - "releaseTime": "2012-09-14T23:15:18", - "sha1": "de533442b141f1c250b17b93e111a30d057c02e1", - "sha256": "ea5593702bf95ac0373b9e926208aad24e05c947bc92c6cd7b9e1cc059063f9a", - "size": 1308626 - }, - "262": { - "releaseTime": "2012-09-15T20:51:08", - "sha1": "a28028cfb93f2616090a6dcbbfa16c8b96c140a6", - "sha256": "091a2a3a14353ec147b802052061477e82b96bb493b98499318b2c207aea0b30", - "size": 1313382 - }, - "263": { - "releaseTime": "2012-09-16T21:40:46", - "sha1": "30a7c5124f1d0a4f5f4bfaf6a8777c3247a220ff", - "sha256": "9286c9e90aed43ccc94ea88b61ded3fcbfcd09fd5b27b37cf4aa7ed1a58602de", - "size": 1314342 - }, - "264": { - "releaseTime": "2012-09-17T05:44:06", - "sha1": "6c785d1017bee9dcac4239749f7ac96495885365", - "sha256": "bbc74e6e951e68c94637a3a26a28e7a67883e91e5baecb82f50a0225aeef8f02", - "size": 1314347 - }, - "265": { - "releaseTime": "2012-09-17T05:59:50", - "sha1": "145240e8eef335df7765a42eb7433d7e9fe442f9", - "sha256": "779049bc88685d694db6d63749f34182211741918b0fd2730a91ac5d29467bad", - "size": 1314351 - }, - "266": { - "releaseTime": "2012-09-18T20:27:34", - "sha1": "3f346ded27f95dd013744fe3cd6e0c2d96c10b3c", - "sha256": "ce136d679ff863568703972c10dfe9d1d75160d4f26e01d7e8bcad0604a4fedf", - "size": 1316175 - }, - "267": { - "releaseTime": "2012-09-18T20:51:16", - "sha1": "8d73f34e62b70f7a88613a0308515cfbd77bfb34", - "sha256": "153609a14494ec17e74d914a9ef4a6a94a242fbb9e03b8dccd2bee4387333513", - "size": 1316171 - }, - "268": { - "releaseTime": "2012-09-18T21:03:10", - "sha1": "b9e7741f51d647af6de525c671270a636f8da77a", - "sha256": "4a982c7fc6181a26a846226152ff8db1b7fb3c716cd8523afb3e1e9a01370373", - "size": 1316170 - }, - "269": { - "releaseTime": "2012-09-18T22:35:02", - "sha1": "6025e36e12dfdc67aa5d5679fe43fdbb31b5a992", - "sha256": "6ed3322fdc785f23cbc32cf38a66301629bbd9fc21254ecccd6633cd3ffe5f6c", - "size": 1322458 - }, - "27": { - "releaseTime": "2012-02-28T18:57:58", - "sha1": "2d31fe2db3a0a1d3e4112b8a7593799b0000508b", - "sha256": "91df022c75d4ad218ff54bb397c8202da1b2c55ab0c75675f2e59502e197d0d2", - "size": 464730 - }, - "270": { - "releaseTime": "2012-09-20T19:50:52", - "sha1": "0c405297d5e32d30edc90eae9b1284d4e93758b4", - "sha256": "ce3814fafdc9e8f1d3c9ed2a3d8695c572d3b12c89de75596f4f9cf962ac6b91", - "size": 1343909 - }, - "271": { - "releaseTime": "2012-09-20T20:59:58", - "sha1": "6ccfb512d6f87bd37b6e85199d3789f548c53cba", - "sha256": "84d316aba81569e4fed43dc1831c32eda9d626471d22f1f04374b49ca3a5dec6", - "size": 1359878 - }, - "272": { - "releaseTime": "2012-09-21T06:40:22", - "sha1": "4557fa3fce875085402a53f74bd1b05bc0efad7f", - "sha256": "15d585a5dd3c667e33d18134115f223a5ec2c151fc25b968abf1e7d635ed83ec", - "size": 1359876 - }, - "274": { - "releaseTime": "2012-09-23T17:58:06", - "sha1": "6ec0b6f483df744accc5dd091a80b5948e63b8ff", - "sha256": "194acd06120c5669d440e7276b36bd30c1370d00118e9a389c801b92b800f069", - "size": 1359855 - }, - "275": { - "releaseTime": "2012-09-23T21:14:34", - "sha1": "e1da8d4fbcfb21627ad727e486e5fc176226567e", - "sha256": "797ca0b72c9405424e9cdb9079994ecdc94165b452fa3770ff1b404a607ef7b0", - "size": 1378357 - }, - "276": { - "releaseTime": "2012-09-24T19:17:42", - "sha1": "c8e7be4ed777f9eceac85775df2931a6e3930566", - "sha256": "fb39f7a37af11c00ec79c1c50f9cd0356f49c3886c03a3a85e0d84db5cdde3dc", - "size": 1379400 - }, - "277": { - "releaseTime": "2012-09-24T20:13:30", - "sha1": "14c6ec0bfff30f2a64c4be8c08fa19362e41e791", - "sha256": "31af93738a346fae8a8eb545625d57ef39939987dc04b2f0fa0782abe091d7c9", - "size": 1379499 - }, - "278": { - "releaseTime": "2012-09-24T21:20:46", - "sha1": "cb49775fe4c7e4b3ad8cbd0e545465d4554da3b5", - "sha256": "04c066b977f7abbe0c9a5b615de5c6cfc4bc8a59f701fe37f7b20f980e95b7de", - "size": 1380176 - }, - "279": { - "releaseTime": "2012-09-24T23:38:40", - "sha1": "7d61712d0a659e852ac966948dee1c9096437584", - "sha256": "e269294f5399aba12dd8bc55b0e14dd3397f7024e4c568f9de1389f74d80f14f", - "size": 1382733 - }, - "28": { - "releaseTime": "2012-02-29T02:33:32", - "sha1": "35151035d6694f7e58f2a38b86ad41605ba9eead", - "sha256": "29de2673b5b22b782d8cef432883f651ca295613fed51d1d96ff22a337ed0a66", - "size": 486646 - }, - "280": { - "releaseTime": "2012-09-24T23:52:36", - "sha1": "47743796a00274d650c48426e8a1cd4e7974717e", - "sha256": "5848521978f5967a995d16844ce50e5e260abfbab0311fd6f02f2dd21f1197d5", - "size": 1382958 - }, - "281": { - "releaseTime": "2012-09-25T06:09:10", - "sha1": "1138df5823018374c2805f381007002568812deb", - "sha256": "aa009dc61289bf4cd4616974ba15e2246ed562391952e925fc4e4d3a3290d61b", - "size": 1382960 - }, - "282": { - "releaseTime": "2012-09-25T07:37:12", - "sha1": "b9204db9e55c707c123ef96c34bce982cf6ac6eb", - "sha256": "8560e9cfa84ebd08812e6c81774103074c8db8bfb371f1b8fa7b52a5994a40bf", - "size": 1382961 - }, - "284": { - "releaseTime": "2012-09-25T19:51:46", - "sha1": "d041d3886bcdb568b96852fdc5cedcfcfabfd2ca", - "sha256": "57ef413d7562f44ad3125755ab31b3c9c60d909d0b90a89140ce6dedf6cb4a5b", - "size": 1383332 - }, - "285": { - "releaseTime": "2012-09-25T21:10:46", - "sha1": "1f7ab01768059ce5928fb0b6f1a527aafa4fc8d7", - "sha256": "f251c87ed68ae655567900f9e960eeca02daa1bf3aabe7bbb342093608824c5d", - "size": 1384679 - }, - "286": { - "releaseTime": "2012-09-26T02:49:22", - "sha1": "728b7e377c5f9bd0ef9ec66b382665f9b83340bd", - "sha256": "282808cb91384574aae591926cc778ed3a91eae18923eacfde99f3bb1ea31c48", - "size": 1384692 - }, - "287": { - "releaseTime": "2012-09-26T06:56:34", - "sha1": "fd68f31ce6d9e798d39eda31bc8a6ed3840bf036", - "sha256": "daf830444ab50cb61393843d6f489f7d358e09cb4dca5da72e5faa28bc66d416", - "size": 1385394 - }, - "288": { - "releaseTime": "2012-09-26T13:23:24", - "sha1": "f9943e9a126373b4afa55664f3ef882c8b02e4c3", - "sha256": "fbc87e2b5e473841cc5227856f71fdacfe76ace73fbf69ce003df8de322bae3d", - "size": 1385418 - }, - "289": { - "releaseTime": "2012-09-26T18:59:40", - "sha1": "1b91b9786878ac44121db168bd6163faa005be02", - "sha256": "fd1c33323f1202c5010c586091bd6dc5a4fca7718547b6475bddc17cc7227813", - "size": 1387742 - }, - "29": { - "releaseTime": "2012-03-01T09:43:22", - "sha1": "24afdde48a82edef65f089d7e98844444d6f368d", - "sha256": "deff2dee5718547a537148eb24f6130e6b145a360d3fbe82ab4c52d59d72ad6f", - "size": 486658 - }, - "290": { - "releaseTime": "2012-09-26T22:23:24", - "sha1": "038de0718c800c605deda3cc1ea63f1467cc0d85", - "sha256": "47118979ecc3f2c36d36b9d70bf96a5881837008b05aaa45a63c5206b203c6c2", - "size": 790109 - }, - "291": { - "releaseTime": "2012-09-26T23:17:06", - "sha1": "065b1fe40b67ddd5d8bcf14ae9f1c5596f75713d", - "sha256": "073b76291ab2507af08eafb1b61b4e9faf6d22ad62e3bac396f95b9aed68a216", - "size": 1395063 - }, - "292": { - "releaseTime": "2012-09-27T21:42:56", - "sha1": "a679d1084c73429a77c4ffb50b97ce777b4609b4", - "sha256": "3acd92ea7648db24593c114ce5686a943461febc01201ce5b9d7ee23cdfb524b", - "size": 1396837 - }, - "294": { - "releaseTime": "2012-09-28T01:06:32", - "sha1": "64f6f140b33e9e5f19875173fdd320287797e684", - "sha256": "0cc8414d0a807bfede8f5795b42e45bf841da38a52124335fda658403f75acfb", - "size": 1399300 - }, - "295": { - "releaseTime": "2012-09-28T22:40:30", - "sha1": "93a98657e5bcdfd5649f01f692f58c22da0e47bf", - "sha256": "94fb922756e6d65dc1f33b0ba3d55cc1a7b1164ff288be326459e710f859054d", - "size": 1403212 - }, - "296": { - "releaseTime": "2012-09-30T01:53:04", - "sha1": "fad0d621171c99f9caa0f41e123a58024f0e35ee", - "sha256": "024878d93bc75e2da4ead3658a1d100f613f6c9db5f453b31804b4f9826334cb", - "size": 1403299 - }, - "297": { - "releaseTime": "2012-09-30T02:05:30", - "sha1": "47e7ff030762ffe8e6ed354a119a08123a9173e5", - "sha256": "b11d5af17c75405368034f8e25e0a6f5e8ee8cd51002ceea0d6325b9e40bd880", - "size": 1403379 - }, - "298": { - "releaseTime": "2012-10-01T20:00:02", - "sha1": "4916d49e40f4fa54166886bac140355aef3566c4", - "sha256": "4950ddbed97db5e1c206117360ebcc5476d8766de01ff81a14d8bc721b6b1b2b", - "size": 1403428 - }, - "299": { - "releaseTime": "2012-10-03T01:15:02", - "sha1": "2ccd5e67834ed7398d9ac2640e099b62b5abca9f", - "sha256": "2110109759eecbc0620332d36da3f563928417e110d174f6dad5b7ea7f8ac706", - "size": 1424943 - }, - "3": { - "releaseTime": "2012-02-07T05:17:42", - "sha1": "3fe54181614b768989c3c7bf7511e155e6951b50", - "sha256": "58bece6eacb2ac1f1620cfb933a28091e29a54011b833bf4e237020ae5f7410a", - "size": 410382 - }, - "30": { - "releaseTime": "2012-03-05T13:41:18", - "sha1": "595e36215d90f21453aa9341229e912f24e34270", - "sha256": "7cc4d8665a7e53eebe8b464268aa87279e50fb72018a1a13b390a044d550ccb0", - "size": 491830 - }, - "300": { - "releaseTime": "2012-10-04T17:54:54", - "sha1": "86cd379f205b276f8c0324f68d2f2e8937385e9d", - "sha256": "ef233640f7f1355f1e75ee17028d25c907c0b6ee349e3b9627ca1399eba377f4", - "size": 1425269 - }, - "301": { - "releaseTime": "2012-10-04T18:13:16", - "sha1": "a2be7a5a53937cd1e9ba52d5c96000d65dc5dcd0", - "sha256": "1bab552c7fa6ec7e2b081a1588d4c52644e6af4704ec2e01e53fec4f6135cf23", - "size": 1425270 - }, - "302": { - "releaseTime": "2012-10-06T21:08:56", - "sha1": "f13bf3a018b054802e3a392d06f4fb4119ef9b20", - "sha256": "00292036a9eb6f604047712d63e11ee4b6fd6b3ed78ebea87ce0681c0047faa1", - "size": 1425356 - }, - "303": { - "releaseTime": "2012-10-06T22:33:42", - "sha1": "3889893893cb42d3a6152e776e9f6a180066dcaa", - "sha256": "e4a2b58ed312225e2695454736891bb41827ca554c84827023d33485656f0521", - "size": 1428414 - }, - "305": { - "releaseTime": "2012-10-07T19:21:12", - "sha1": "efd0fbfb3485a70ed9fb2af461a8ee2c5049fb3d", - "sha256": "2999f5efacaffc97feab6ac34d9fc912dd62f485afad14a712e0b88b42f4fcbc", - "size": 1428418 - }, - "306": { - "releaseTime": "2012-10-11T20:37:20", - "sha1": "ba1430d974407ef00969214c4390217b5ec64273", - "sha256": "2cd545363aac02da88b7885cec17523cf8b86daf6137cfbb465ea3c30477fa10", - "size": 1428541 - }, - "307": { - "releaseTime": "2012-10-12T07:06:42", - "sha1": "4abca56246431b36c149cd313e4835763ce8fd18", - "sha256": "a74f4c9a9fbfa40ad32cf1a80ad5440dc69742507746c1186b8c7cb93caedeea", - "size": 1428536 - }, - "31": { - "releaseTime": "2012-03-05T15:11:10", - "sha1": "4bb8573263e2d3e44fa5c6ef43f3e18ab5262562", - "sha256": "f8bdcc0c6024d76ea9e5e0e1344ac7241781afc3a231ce02da00906389880c90", - "size": 491816 - }, - "310": { - "releaseTime": "2012-10-14T13:21:20", - "sha1": "8052486df828c7cc6489d1f8a9ff0616c4d1d4fc", - "sha256": "7e530302923567d8e67dee84dea6495372a9fd583cfeb615410733f851598ce2", - "size": 1428709 - }, - "311": { - "releaseTime": "2012-10-14T21:04:00", - "sha1": "a040f2961a9f80d213dd63fc524a43c97a80ff81", - "sha256": "f85f541a15f45eec0e2d1729f723eec8d4aa4f61be174f7018385625baae58d2", - "size": 1432897 - }, - "312": { - "releaseTime": "2012-10-15T17:26:04", - "sha1": "b0cf805b556bab9117143b4a98a3858627d41e09", - "sha256": "2eac4812f955dfc247f10f2505e5ad571479ff073b8956f34d6f7ef2410ff987", - "size": 1440667 - }, - "313": { - "releaseTime": "2012-10-18T18:03:14", - "sha1": "fef9dcf979edcc958e88b6df81ef3c6389e8b337", - "sha256": "37bd8e7bd982b43b88e1812940e5b5dbd815da6a7ef0e497bd715e2d665512d1", - "size": 1440713 - }, - "314": { - "releaseTime": "2012-10-18T18:23:34", - "sha1": "0e6d656ad19cec0212bde20ab007aebfe307524f", - "sha256": "e2c45046b943ad8a0fddd1459f859c8f11daf55ddae79ee5bc915fab73ad9b71", - "size": 1444706 - }, - "315": { - "releaseTime": "2012-10-18T19:36:54", - "sha1": "d73efe944b56af1dec736a2841bf90b982fdcfda", - "sha256": "6a84beaca35ff12697c463325aac82047122d992ca30945689c735b81357c905", - "size": 1444954 - }, - "316": { - "releaseTime": "2012-10-19T07:33:54", - "sha1": "c6523c32c76347f4e524f2a62ffb818c1be100a0", - "sha256": "50c3dc888d807a521e159506439df28e9d1f607b51f9aa6f5e3351eeec37282d", - "size": 1445006 - }, - "317": { - "releaseTime": "2012-10-19T09:52:58", - "sha1": "953bcb1d58c2936bb09de2865087969a4c477b97", - "sha256": "301624aaf307f788af93c31d9a78a924fcd606c516f8250803594e413ca30794", - "size": 1455076 - }, - "318": { - "releaseTime": "2012-10-19T20:01:02", - "sha1": "a9aca7b4697197542b6d5af11a4f54aa4b052cb7", - "sha256": "5209fa33513733ea5466166354db2004c9b5373da59d45ecfa390f8870341b39", - "size": 1455002 - }, - "32": { - "releaseTime": "2012-03-05T20:08:08", - "sha1": "22acfcd17c076eb0d421c4dd3b954aeaaa9ac541", - "sha256": "ebe9955b45a3b57b9729ddb39cffefc84fac133df5b4faf5a16e8772e7643ac7", - "size": 491816 - }, - "320": { - "releaseTime": "2012-10-21T19:03:58", - "sha1": "2458eed5baf11e6cad3dd20cd1597eb21e6619da", - "sha256": "bfe7f3d609aabb8ef140ad7e440f3a5889d651a970076acfe3b418dd60ef544d", - "size": 1494316 - }, - "321": { - "releaseTime": "2012-10-21T19:10:42", - "sha1": "3cfbfacdb3187808752b41fc05281c10479d1d49", - "sha256": "ef596b1ad38833c2fa296f4f6ea0bc48e0ba477c1f7486daa8540674a6e98c41", - "size": 1494344 - }, - "322": { - "releaseTime": "2012-10-21T19:25:06", - "sha1": "7267e92a88bdc02609fe505498ef04ebab34e1b9", - "sha256": "73ad5c2751b5d582bb450b2803e3e3410bb71503b3a89e548f1f66995eff7789", - "size": 1494344 - }, - "323": { - "releaseTime": "2012-10-21T21:13:26", - "sha1": "609edfe719164418a648702d0d4886cfecae0af9", - "sha256": "62321c8a8ba3c75592929cb9b6f85093a53140066c77c44c1dfb3099a797f63c", - "size": 1494585 - }, - "324": { - "releaseTime": "2012-10-22T00:06:58", - "sha1": "1bc48563a4863659b9f4a7db7556bc34fbd759f6", - "sha256": "d4ba7ee24d4c96459f9ddac17f9ccc6f2b1cf1fa3f9db2ff35b2305664693f0f", - "size": 1494640 - }, - "325": { - "releaseTime": "2012-10-22T01:33:04", - "sha1": "c4fdc58df5f7fef44f1fc56c8e21b4c7eeed2e36", - "sha256": "42cb64e70fe45866f53fd1042a9ae547cc1b93f6ccc7c2f4ab7d2d0756514723", - "size": 1495067 - }, - "326": { - "releaseTime": "2012-10-23T07:33:54", - "sha1": "951d5d3be6a187f7d8083ab272490b611b83178d", - "sha256": "a3eb35d9315cb30dce07064eeddcdb501db6714248ee1275e1952f1705364fee", - "size": 1495169 - }, - "327": { - "releaseTime": "2012-10-23T17:11:18", - "sha1": "206f653b01decb7ed59856d8e5918aa2e29d7de7", - "sha256": "9b3b2f418c36341abb1772c58c2fb469b9791ec17d633f15f05299df360982a5", - "size": 1496510 - }, - "328": { - "releaseTime": "2012-10-23T19:58:42", - "sha1": "1f0adeb2906c5b36ea2e9aa38ffae6249fcc4fc4", - "sha256": "4117b0c4a84004bbd00707726541c554daaa7ae47d5c64756c4c2566a3d8f4f4", - "size": 1496526 - }, - "329": { - "releaseTime": "2012-10-24T04:58:42", - "sha1": "fdf61e473c34f7273962370da9a40dfac2554d28", - "sha256": "c10ffa5d4bd63737808d8273097678c256d961bf556f6f5f8bc2c283e95ab230", - "size": 1496508 - }, - "33": { - "releaseTime": "2012-03-06T00:33:56", - "sha1": "e0c02879e9986488810f4f54d4b7c3d71700daba", - "sha256": "6d28858969c5aa5b1151c73708d9996e154c0dbda3d7f526c503df5c7cd40f7a", - "size": 493289 - }, - "330": { - "releaseTime": "2012-10-24T15:06:52", - "sha1": "7b7c77d36bef706f655acac4507a1a731282c342", - "sha256": "b6215a0814bc50465b47d00497bf29a0d87e7b296470f532238208af5b5d00b1", - "size": 1503248 - }, - "331": { - "releaseTime": "2012-10-24T16:22:08", - "sha1": "6e943173b9889fb97d86a0dd27f2a4e85777aa92", - "sha256": "e34fe78f021948511a9ebf4fdaeab63e1095278ba61c3cb9d7e1d9f43591a191", - "size": 1498731 - }, - "332": { - "releaseTime": "2012-10-24T20:19:58", - "sha1": "65355d7e60accf48e78e9fa011bdbd9c90a57f9c", - "sha256": "0bb6f6d7b832fb02010711638be3c94ef9b7c305e720127353f7df9c0927f801", - "size": 1502361 - }, - "336": { - "releaseTime": "2012-10-25T12:50:48", - "sha1": "770038a5a35f4d615fa8329f2ce86e2244555295", - "sha256": "504a206d83df78ca2e0c1d4d2ac73a352bdbb95e10f23d85f6e1ab6cc67cda46", - "size": 1510583 - }, - "337": { - "releaseTime": "2012-10-25T14:06:30", - "sha1": "8ef4b1ee1783e504c963850e0388d7841a07d9f5", - "sha256": "1e384bd63602ae7c72e508869874d48479b4b84dde060eb0d421110a4ed29607", - "size": 1510581 - }, - "338": { - "releaseTime": "2012-10-26T22:14:56", - "sha1": "66639c2142007e828ace0e073e8bb6cee331b9a5", - "sha256": "03cf9db17993d4f7f65ca35f8417af1fc9009d89e915312c77c6770c9d9c823d", - "size": 1510621 - }, - "339": { - "releaseTime": "2012-10-26T23:42:06", - "sha1": "2b7c222c546aa1fb4970158cb73a3c7ee1a8752f", - "sha256": "066bb3a7e85f79956b1d63a05669f5341cd3bed037c82b51979e00097ef2eb4f", - "size": 1511938 - }, - "34": { - "releaseTime": "2012-03-06T12:16:10", - "sha1": "026c986f32243ea3717ef5588078cb24e205dc3f", - "sha256": "fa01b7da584bb1bd82ff172b7a0c20f0cc331cdedc8147ca73f4242650ba92d6", - "size": 493315 - }, - "341": { - "releaseTime": "2012-10-27T17:16:34", - "sha1": "e4803f22cd8658dad3d9fcfb0e1000d64a6d23bf", - "sha256": "1ec9689844eb2f0622b4b2202eda95be209d46e52b2974c0d209710a3d123fa6", - "size": 1512068 - }, - "342": { - "releaseTime": "2012-10-28T05:21:52", - "sha1": "5ed309d34f886909d155c2a9ce4ecf0c5773dd2d", - "sha256": "f619ad665ff333142023ad40f711aa1fecaa90be3fc441fbe26c88db60453f15", - "size": 1513794 - }, - "343": { - "releaseTime": "2012-10-28T05:56:26", - "sha1": "7e75505b38d43d8ddba72ca54a80a05d3f8421e0", - "sha256": "a05a4d0b1630434f8101b7e719e4234064bac07c051c69fc54c86649dfc427c7", - "size": 1514653 - }, - "345": { - "releaseTime": "2012-10-28T16:40:54", - "sha1": "3ea15e52020b3e2293ef51c0e94a6f9e7a5126f3", - "sha256": "1064de17fc5d2f395020da84cb14e590abf35874dfed266bcd270e44f24fb400", - "size": 1525523 - }, - "347": { - "releaseTime": "2012-10-28T20:10:44", - "sha1": "0b1205eaf6f091a06f340259f6f249ee76787e6e", - "sha256": "783555feb06393b22fa6639e40018ae647a50baec7bce2aa4aacd0827626e312", - "size": 1525525 - }, - "348": { - "releaseTime": "2012-10-28T22:58:56", - "sha1": "bc79e870e11fef61ddfba2c82eb4268af049a44a", - "sha256": "12d3bc2efd574c691c5cd1304be113605dc585157c2f9dc9759a36a5605d38ba", - "size": 1525392 - }, - "349": { - "releaseTime": "2012-10-28T23:11:02", - "sha1": "1cfb5f54ce72ddb174031b64d04c158f98892a51", - "sha256": "e47f59822872eca8e85a9fc5f5a3eed512109afc595201b245987b5ec4f32806", - "size": 1551747 - }, - "35": { - "releaseTime": "2012-03-06T14:22:22", - "sha1": "ba295b9285cc6be48d3dfa7fd37ea86213c45578", - "sha256": "28a1f00312db22a4cf21e8a2f44738816a86ae4f20ddfa722399539834436155", - "size": 495444 - }, - "350": { - "releaseTime": "2012-10-29T00:46:24", - "sha1": "5d9a4661d55b93221d6363a58dd5376474351c01", - "sha256": "6ef74924226dc59a37a3d718caeb152490de0f32caf06b832a5717b324fa57af", - "size": 1551798 - }, - "351": { - "releaseTime": "2012-10-30T07:34:28", - "sha1": "116fbdbc70e3dd7905bc5c591cf6a4969c126da1", - "sha256": "93d3daf31960dc9ed863037f02d078c2f52f3ebbc22ab16f91b3691834722a0a", - "size": 1556458 - }, - "353": { - "releaseTime": "2012-10-30T20:14:42", - "sha1": "dae9da6a5f388913fafb99f9c99fcf4b60e22f80", - "sha256": "565d5b12e452affca7965d1d0b6b7208bfe06522a1bd82002f416278d0f90cff", - "size": 1556757 - }, - "354": { - "releaseTime": "2012-10-31T11:20:58", - "sha1": "629cbcecc84e21703fee50093402da51573b073e", - "sha256": "75407b1dfe61f9a0722377f80eef7734c2567750c43b2950fcabf86995c7a77f", - "size": 1556800 - }, - "355": { - "releaseTime": "2012-11-02T12:52:28", - "sha1": "f7885f3ae3436d452a8bef4d9668f95298f7da7b", - "sha256": "b35d3cbe3a4e6a967fd97791be9e03014531aba1b2df6e365981436cc2dfbc6c", - "size": 1558322 - }, - "356": { - "releaseTime": "2012-11-02T23:37:06", - "sha1": "3f617c12e53ba1e3bb572e80d1b7665bae78baa3", - "sha256": "086d80575e3d80afd7f2eea8ec16f16b9f8c13ab3da7193c0c9f2f28792bcdce", - "size": 1568644 - }, - "357": { - "releaseTime": "2012-11-04T16:48:28", - "sha1": "eb0ae9e2504070958b6189483986e9104496b851", - "sha256": "befbd54a2a2d330d3023b43f680de88048d4ed9619ab271e5a94cb170ddc2aeb", - "size": 1568710 - }, - "358": { - "releaseTime": "2012-11-05T17:19:40", - "sha1": "04031bf441d7a634a85cc42013944a9210f38417", - "sha256": "7ed938631edfb68e4154b210246eaee2152d692e4dfc19aab14a241dbda26a9b", - "size": 1571298 - }, - "36": { - "releaseTime": "2012-03-06T15:09:00", - "sha1": "8ea8e6acd46548bd44e4065fcd298c6c8fe45bfa", - "sha256": "065e78e6c66fcc12ee0739ade8bc6c4de458d6146b2aa0268a27726846a27822", - "size": 495443 - }, - "360": { - "releaseTime": "2012-11-08T21:48:34", - "sha1": "39be64e9c2150f4fabc0b935f89d7eb4e98e768d", - "sha256": "93df1c8f6ef9df7a8a720498fc1d99c13a1d8d782425b4e1763e5465216c8a1d", - "size": 1570985 - }, - "361": { - "releaseTime": "2012-11-09T17:25:36", - "sha1": "f398db2d8385a3fd219bfe6c9497592e4d4c2e22", - "sha256": "cfd5bacca0ac58763208f506afd5a99ed729c73675adca26f9e5854bed620840", - "size": 1570879 - }, - "362": { - "releaseTime": "2012-11-09T19:04:06", - "sha1": "e87fbfea41cb8c1d45ed826d38ff7b956bacf080", - "sha256": "01b69b8250676214c6d6d4ec8750569cece3393925482b2cfe349b6e5781c17f", - "size": 1570970 - }, - "363": { - "releaseTime": "2012-11-09T20:56:32", - "sha1": "1771762757ed9d42f0037edb3676e77739a7a771", - "sha256": "4c05f84231bf150ba275f086857278b39bead1ace381553cb18bac4ccb61b93d", - "size": 1571054 - }, - "364": { - "releaseTime": "2012-11-10T19:33:58", - "sha1": "94e582f9b55f032a6acedcec16c78adf8dc5d491", - "sha256": "cbc34b9f02573e14a910d8a6dde8c99a7099da75a4be2ab096e6c5d5d81576e9", - "size": 1578038 - }, - "365": { - "releaseTime": "2012-11-12T18:44:30", - "sha1": "8777440f4e187005c0897b0210c927b9657334e7", - "sha256": "5ee66f082387f88eb932d1bdfce8d6d2c9fff7d062f28f76c3da9c08285c3254", - "size": 1559401 - }, - "366": { - "releaseTime": "2012-11-12T18:53:48", - "sha1": "ab553f5143e540886bef8f84d34fbc7fefd48db5", - "sha256": "a5ec60b85c40f16c282aa0c4148f2da10f404e27903be7a5f81418988e549a3c", - "size": 1559399 - }, - "367": { - "releaseTime": "2012-11-12T19:47:18", - "sha1": "496ebd0e668fe2d8d6407c3a451dc85822a5c542", - "sha256": "c91589bd1bde3969a2aac31aae08b9f66e1955c454eaadc204ff1094f8a02024", - "size": 1559438 - }, - "368": { - "releaseTime": "2012-11-13T05:16:32", - "sha1": "4a6ce155d69a0e77172bd33e8542843ba2fb5557", - "sha256": "936ea8b61d2569e41e18e9f1cf6e3f6bf62e96f3458f01bbde7035694b27b69b", - "size": 1572991 - }, - "369": { - "releaseTime": "2012-11-13T12:34:36", - "sha1": "ba531896a52058369d867a96ad471c33b196fbc8", - "sha256": "2465f0cc6bfc3a6ce1f1e7c4792ea3378d095c80feb7022dc7f34789e7b1ffd7", - "size": 1560273 - }, - "37": { - "releaseTime": "2012-03-06T19:04:38", - "sha1": "0fe737b9df40cab28f02c37590e424f67df083c4", - "sha256": "7262bf12856ad4843ba79af6b87893890da228afad5ef864ee8caad45d4f7630", - "size": 495444 - }, - "370": { - "releaseTime": "2012-11-13T13:09:52", - "sha1": "b2076adfc54efc8ae825730a64ed01279d44c211", - "sha256": "0c1744dbc69b89a48751270fb564eb6f4309da6bde626e1372d2d50e25e5f98a", - "size": 1560358 - }, - "371": { - "releaseTime": "2012-11-13T14:07:42", - "sha1": "b183e618cb2e48527f7a29b708fff9d58295f1e6", - "sha256": "13e8021d23a2d2fcb5ca9fc3df96b3455818069266587fb341843600467b1b8f", - "size": 1560418 - }, - "372": { - "releaseTime": "2012-11-13T19:58:58", - "sha1": "027d47d7976d01ccc3599e041dfcded3ec15eb2a", - "sha256": "1b844c29cec43e00e82b65e258f71f61c1cce5ca0d2b8356f50b47d9d6ef7932", - "size": 1561761 - }, - "373": { - "releaseTime": "2012-11-14T19:27:58", - "sha1": "fda4fbf2916207d55e98ec27ea61549c1826da54", - "sha256": "a0c437ddd2cc6c7be270fc6b88d6539829679b79bd01aff7f90e79a3bbfc148e", - "size": 1562217 - }, - "374": { - "releaseTime": "2012-11-15T04:49:52", - "sha1": "9de2d89f0531bcb1adc8267ee0a8baa008f33e85", - "sha256": "fa82a63bbd85cb7ae31956b637e735a8cc2febd981ee68b400a999691e1b0a7a", - "size": 1562900 - }, - "375": { - "releaseTime": "2012-11-15T15:28:26", - "sha1": "0d8966170b6962601e5a91b19b2d50e341712823", - "sha256": "4d13ace48459183ce6787de75d60b878a2af9953b62a613a54f3bfc46a65cb3c", - "size": 1563025 - }, - "376": { - "releaseTime": "2012-11-15T19:51:02", - "sha1": "e1b8b7bace6918a37d4d514cfc7fda2d52ed8026", - "sha256": "c9747e1904f643348284bd0a84f69fc39466f8cf294eb7e8bbb8dfa38fff3da0", - "size": 1563055 - }, - "377": { - "releaseTime": "2012-11-15T20:06:00", - "sha1": "780c95faaa1ba67abad4f3337400608c447cc58b", - "sha256": "6933de9c37497ddddbe75c097dec6bfb6cc2952a0b1f677395484b90246b3205", - "size": 1563101 - }, - "378": { - "releaseTime": "2012-11-15T23:33:32", - "sha1": "dce5007bd59c08b094a83f1f35b64e25f1996f78", - "sha256": "8530d8205c99537ed71b7252ed34f05326e88e901ac8950d34da36142619a9a5", - "size": 1566485 - }, - "379": { - "releaseTime": "2012-11-16T15:47:20", - "sha1": "b201f6af733fbfb0bd2c11c68774b31588257217", - "sha256": "0f4714124c33ee1d7531a385da2ca59bea742c668e8420eafba85cd1481cbe5c", - "size": 1566514 - }, - "38": { - "releaseTime": "2012-03-06T22:49:30", - "sha1": "d254fec60aafefafcb399790a28f27f69e67d56c", - "sha256": "f946b0050a736e47a115da5cc5a23a4cf80a8a54cf1adeb16afb21da332bbf37", - "size": 495443 - }, - "380": { - "releaseTime": "2012-11-16T17:12:00", - "sha1": "2307ad742e748fd12a8565bd5da3cb751a6432a9", - "sha256": "c3521e6ec808aae8d459ad0851d5888e3146aa934920ce2b7c3c9877a14f2689", - "size": 1569305 - }, - "381": { - "releaseTime": "2012-11-16T21:14:30", - "sha1": "4dda566adf78076414db2c141940e6aaaa41dbd5", - "sha256": "701a668032d4d621221caeb0a24d4f244394afa128e7f392679f9737e21acfb6", - "size": 1566513 - }, - "382": { - "releaseTime": "2012-11-17T18:56:40", - "sha1": "1f944700b9a13ac67691968da20f2535e3d77bca", - "sha256": "0bf4fbad7b07e72fba6f858fc115ebb8d0c9622f13b110f2d750a2aab70aae69", - "size": 1566687 - }, - "383": { - "releaseTime": "2012-11-17T22:21:40", - "sha1": "65e67841ce18c66bc1cde1ba97df287983a83bf8", - "sha256": "b6ba49202676310a9510ce41181edc018cfa373ee83d033692d4b00d53c4bcac", - "size": 1566646 - }, - "384": { - "releaseTime": "2012-11-18T00:03:10", - "sha1": "3c6adeef6acfc9b7abb0f199b395b98f711cb93d", - "sha256": "647d75ae381c37af8c025ef68f08da0722995785dde35df5f3f3da2a6b7818ed", - "size": 1566769 - }, - "385": { - "releaseTime": "2012-11-18T02:42:22", - "sha1": "a15a6f757d97b8f0eb8ad8d4ac7d3124c0321746", - "sha256": "c177bc64a849afcf08f47a1b840ac8374a97c282f5a36e5901beec293ad02b4a", - "size": 1566949 - }, - "386": { - "releaseTime": "2012-11-18T09:16:58", - "sha1": "99e1ab64ce488b7232c73208b16eb04f470fd9f5", - "sha256": "c9cd3f00e1f80eed295e5630a0be0074813f9d17f1113c1cc78bad733c43e556", - "size": 1567017 - }, - "387": { - "releaseTime": "2012-11-18T17:32:38", - "sha1": "2d91b92f77c2decd351b13e5d50019c2bc4af3e5", - "sha256": "68b80e96f6f9a346c1b15ee4fe169a5b2fcc2fae413b897dca8a5073b3f9a6ac", - "size": 1568405 - }, - "388": { - "releaseTime": "2012-11-18T19:26:58", - "sha1": "876479361328ed724181a07a30a1a103b600fb2c", - "sha256": "762580a61284d0c3740e577e1b76038fcb7866170f03eafd268a8b62f8d00a37", - "size": 1568457 - }, - "39": { - "releaseTime": "2012-03-07T09:49:42", - "sha1": "dde19ec058b2f6628763f1bc72648844155a67b8", - "sha256": "a321c4314b2cca490d977c37ef1fdb183e3a5371abc68aa01a3587e6ccdadd42", - "size": 495506 - }, - "390": { - "releaseTime": "2012-11-19T17:07:02", - "sha1": "c71d7e28ae162d29eb8806040f6f7fbf21708d14", - "sha256": "542cf72c16c210875f6eb55097165e7af472b306817506f8d5ab3778ff06f6cb", - "size": 1568504 - }, - "393": { - "releaseTime": "2012-11-19T22:03:40", - "sha1": "fed5072a6499574348eb2e1726fbb4599bd0a3ee", - "sha256": "21060ed45ea15c48c35c4977b9cf08b76a69ba26846b087df29a693f7378d090", - "size": 1568255 - }, - "394": { - "releaseTime": "2012-11-20T07:12:44", - "sha1": "66e56c512a992b0bb903a75ae84d06de354b5c28", - "sha256": "da4530a3d6587165c1a40f8fdbd2507d65b26d7c3793c3725abd1ea1aa331a34", - "size": 1565762 - }, - "395": { - "releaseTime": "2012-11-21T17:10:54", - "sha1": "5be9167d38845adbaf24e58e9171d582b1e9d612", - "sha256": "a29de2d2303298967ef3c3eeb0b0abe5d35c543cb4b885c77e82997e52288b35", - "size": 1565838 - }, - "396": { - "releaseTime": "2012-11-24T12:17:28", - "sha1": "3efd96ec4115072fc8ad5b5a202d27cf8ad56ac3", - "sha256": "571f1ead1b918d6326844c34e1f529007d890c30ad4831aab092b1d7b1c6007c", - "size": 1564970 - }, - "397": { - "releaseTime": "2012-11-26T22:28:56", - "sha1": "2f1a2fd2a5f9bbb7a39490bb4c029b39db80ce48", - "sha256": "7378bc6b9d96c22d277fe99c6f4ba0e9b8b72ee3c7ddb84e5f27ec640904b243", - "size": 1564930 - }, - "398": { - "releaseTime": "2012-11-27T00:49:16", - "sha1": "f5bc769ba675895c657804c7aa1574e993cedb39", - "sha256": "74141455ecb4964d04c19ac4c59b0fa4d3064121968d5249a3a914f1f1c3a9c3", - "size": 1570364 - }, - "399": { - "releaseTime": "2012-11-27T01:31:16", - "sha1": "3f81754b6649761afcc5f9ce17ac92a078ebc713", - "sha256": "563a12fb5c7a82974aeb427928fd3f2a4a77d58421d62519ee5640a3de57110f", - "size": 1570525 - }, - "4": { - "releaseTime": "2012-02-10T03:10:24", - "sha1": "0e36def24134f9ea0262d650d757a37375eb03a3", - "sha256": "e6cb1ccf475de90bc7455bfe7d3b22c48474d8f2f779ce15869b5f12aa97991a", - "size": 417875 - }, - "400": { - "releaseTime": "2012-11-27T03:09:46", - "sha1": "ffce011510bac3b35a704cba8bddad4ff77ac8b0", - "sha256": "234d9950ff347a9636f93a7e2ca5c13100a25c944fcb0e3d3575fccec207f8d9", - "size": 1571980 - }, - "401": { - "releaseTime": "2012-11-27T03:18:54", - "sha1": "d20d4215257451427feac211b007881c57e1259c", - "sha256": "6a849378fe84c62d2623b363a30686f16bfcf3cfccbe3ed0b0a35b02525a1b23", - "size": 1572151 - }, - "402": { - "releaseTime": "2012-11-27T13:28:34", - "sha1": "25889ddffbade3e9c467ffb0c5fab27f36078dd2", - "sha256": "66ef433a2c80bd59a874e9a3850247358a7b4dd2eca082eee86e721841d7ee87", - "size": 1572142 - }, - "403": { - "releaseTime": "2012-11-27T15:56:04", - "sha1": "3836f55df5e5b0ef820273d7eaef7392126fcb3a", - "sha256": "f25db24661de5f1bab385bba2552fdb6cb6ab000d43d27bc12524580d2c181f1", - "size": 1572392 - }, - "404": { - "releaseTime": "2012-11-27T16:06:34", - "sha1": "e958182912c91fe4c77fbab7fdb60148ff4efae8", - "sha256": "d9f855ef98c546e7213c1ed863909131a12ed20ffca479949009b7faaea6272a", - "size": 1572624 - }, - "405": { - "releaseTime": "2012-11-27T17:21:26", - "sha1": "78e964e525fdae2339787d5063c14668e4de18a7", - "sha256": "f8032efd8fbcd2c25a657b567934358e98557d92895e1d0094c5fb638ce68230", - "size": 1572753 - }, - "406": { - "releaseTime": "2012-11-27T17:55:00", - "sha1": "191d3a0768b892f4af6aa256639f0267cc4177b3", - "sha256": "88f276290ad3b4505e1c6a3486c6ce69a96db9416498e13d21886d948d05b60a", - "size": 1572983 - }, - "407": { - "releaseTime": "2012-11-27T23:46:16", - "sha1": "7b50df5d5782bf5568074836ee87342273d2c9d6", - "sha256": "5f11b6194292fecebea4ee1679c3ff8733d6111175f12a8abfe6b86b8dda55fc", - "size": 1573097 - }, - "408": { - "releaseTime": "2012-11-29T05:08:18", - "sha1": "3559c418690e0634bf2ef375d4356304f227620e", - "sha256": "be355580f79b976008c60abc11a1aedfe34b5409d852b6ab92e87f3c677a4e9a", - "size": 1573136 - }, - "409": { - "releaseTime": "2012-11-30T21:26:38", - "sha1": "632e8c6c84fcc6abe47cebff567a772c55ef6ab8", - "sha256": "4f52fef86901c8f1df14cdd1c388f0466f86c010fddae94f3b1f1b4bf5ba217e", - "size": 1573285 - }, - "41": { - "releaseTime": "2012-03-08T22:37:54", - "sha1": "464bda507ea2b70a27a168dceb26511fab3e97d3", - "sha256": "46df091f2436c079a881de6a7cfb8dafe8e79872bcedc21e4a6fe88ede672141", - "size": 499564 - }, - "410": { - "releaseTime": "2012-12-01T23:01:20", - "sha1": "a771d3f3823f2698477fcf09e695bfe2b85dab43", - "sha256": "243382beb46dc0092604dfba1ed518e0beeaca26d36287524646360428e596da", - "size": 1574333 - }, - "411": { - "releaseTime": "2012-12-02T20:10:38", - "sha1": "a07de9f69faf2403a0020cf02434b73ff661e19c", - "sha256": "d80d56f8a6c1d2064763fc9c073f07471e3c8d168784fa75f324b0aea8b979cd", - "size": 1574484 - }, - "413": { - "releaseTime": "2012-12-05T03:55:42", - "sha1": "b8c267d5e9490a08fa4200180a89f2dd6c0da65c", - "sha256": "a0dc646aafc7230d7257dfe5340c26d6dd960155b01a7663800d35fdd1c40808", - "size": 1574140 - }, - "414": { - "releaseTime": "2012-12-05T20:15:24", - "sha1": "6716fb10e4c917036f213b566031097b54c2a73c", - "sha256": "922da5ea5571d02c55d26e438ad8cb06642bc55c668e2bfc4929e8dead7a0066", - "size": 1573934 - }, - "416": { - "releaseTime": "2012-12-05T21:06:12", - "sha1": "4294dd76051274853c92390277f0ee6a449d4ee3", - "sha256": "9786265a6ffd025fa31dfc87d3f9d3d5f3740c670426bea6542b9170c41379c6", - "size": 1574377 - }, - "424": { - "releaseTime": "2012-12-06T07:18:32", - "sha1": "3086e9a8484bad60e86dc0493efaf578b6a56dd0", - "sha256": "fb709c1dc458ecfb06870da123c0ec1d59dca5578ad215d3a9dff4ec14fc3a8b", - "size": 1576166 - }, - "425": { - "releaseTime": "2012-12-06T14:19:06", - "sha1": "4fccda18239a1876f3d62f5c965d60b82dc91468", - "sha256": "7bb5e4b9c1aed20331b78635f15a2e801865490a1e5fa6f6a8f537349e39d700", - "size": 1576317 - }, - "426": { - "releaseTime": "2012-12-07T12:29:54", - "sha1": "8026a34475e6872234ac979b6a2c8099d423b7ea", - "sha256": "2938e6d0aa31b4e681815592f90ea49b433617be15cb4e50a4087c94c55e0dfe", - "size": 1576395 - }, - "428": { - "releaseTime": "2012-12-07T14:25:52", - "sha1": "4c352824ffec9ed14461d582f7329132a1c8df14", - "sha256": "e82d4cc3bb08a8dbe2d88bb4a9edf71350065861de4a19c72f74be949fab3c71", - "size": 1576422 - }, - "430": { - "releaseTime": "2012-12-07T14:46:08", - "sha1": "cf80d6a0ee80b8906c495eeea1def139a40a4987", - "sha256": "b86373c66c61b79b7f9e87be9ad1da33eef18dff6726f496d815e37adbb237bf", - "size": 1576422 - }, - "432": { - "releaseTime": "2012-12-09T15:13:24", - "sha1": "70b8b82c7ed7ec46c98db96762949e2671ba920e", - "sha256": "6d6539b0c4cdb5b342b4cbd68da0a3e6059fcac7ee6d3199efbfb307fb54a284", - "size": 1576278 - }, - "433": { - "releaseTime": "2012-12-09T15:19:16", - "sha1": "27f1997fc815e04b0f56f0015b078bf2c84fa7ec", - "sha256": "59271f90f8a6071fac3b934493c08524ecab56c8679b666ca242644482fd6fe4", - "size": 1576330 - }, - "434": { - "releaseTime": "2012-12-09T19:48:28", - "sha1": "8748888abd3d3c2adcf4d4313414c6295ec3e706", - "sha256": "0395f5aca0707016c9ec6a4e237ccdb5346b73c72f9e653934c29e6ad2f893fa", - "size": 1576349 - }, - "435": { - "releaseTime": "2012-12-09T20:01:56", - "sha1": "a1b84b450226f355d8dec28a3e8c1103cd9b37af", - "sha256": "bbb10267af0fcfadb9c5d7e1fe843394c4fe301eef0ef41068d31ead86dfb9a5", - "size": 1576377 - }, - "436": { - "releaseTime": "2012-12-10T16:59:08", - "sha1": "8c4b90d40e9793c3252c3f88c730422fb64669a9", - "sha256": "2073d3ab32a6aaa868b96d3980157c23952f78c8b6ec593e44dc57cf34660a8d", - "size": 1590738 - }, - "437": { - "releaseTime": "2012-12-11T22:46:36", - "sha1": "832c44b5e1c6e85d35ed566e4f123ed67e4b9778", - "sha256": "6cceba7d45ad61c1bc5c9bfbcdae0d24f2c268c2417724ccc701c5c7c8167a42", - "size": 1590956 - }, - "438": { - "releaseTime": "2012-12-12T03:55:14", - "sha1": "24c3852556e4a2172bd37de1cad18d4243a0b308", - "sha256": "f7a3057bdee5d5e48d1dd4231e53fb94e7fc6d679cbd6912b908e5a92baacd28", - "size": 1592071 - }, - "439": { - "releaseTime": "2012-12-12T15:35:04", - "sha1": "380e5ed60de266795ef3dee3c936621141cf0186", - "sha256": "e4ecef94ad2362bbbf3698603eb8a8326e6593b37561c68af568c5019eb57006", - "size": 1592612 - }, - "44": { - "releaseTime": "2012-03-09T14:31:00", - "sha1": "b52292f98704566d55ed5fbd4dc0405d8edb6e0b", - "sha256": "4d87f84695eec54608719f0eaaadb9cab0d552d73df6d3feab69a7ef3bfa512e", - "size": 499566 - }, - "441": { - "releaseTime": "2012-12-12T18:22:44", - "sha1": "bae8c4e99b9e2c0617550db52ad8eecc06ba2f6d", - "sha256": "6f6410d465f289369450fdcf3742f1f0c905272cdac58b6fee8f079dc54a41f6", - "size": 1593778 - }, - "442": { - "releaseTime": "2012-12-12T19:17:38", - "sha1": "a542808264f7a5f0d915c33e2cc3f2142f1fcc0b", - "sha256": "b2439f523dfcb813856fc862a4a3a1e6f8f6d803694b80f2a1da395982f0650c", - "size": 1660053 - }, - "443": { - "releaseTime": "2012-12-12T19:38:34", - "sha1": "ac0e17501a2925505c2e1ffa44a0f8eee0b9b845", - "sha256": "ccbc7994ab79325e5b591911f747e7ec58083f01794f3c865aee60e9d51ae2da", - "size": 1660189 - }, - "444": { - "releaseTime": "2012-12-13T00:54:08", - "sha1": "a1451b128695094b6b5cca335449e1d620de06fb", - "sha256": "ad3040529aa031dd3bc1fa6cbfe7d8f315205ba9c5df8a06bb6a3bbdd474c26e", - "size": 1669622 - }, - "445": { - "releaseTime": "2012-12-13T01:37:06", - "sha1": "b034cbad3f93b4dc7da0d1afbbe8541d53ab98a5", - "sha256": "c4ae11bc38717108e01dca4ca64f8649c64dbf471016c89859baa126421f1e21", - "size": 1669620 - }, - "446": { - "releaseTime": "2012-12-16T19:08:40", - "sha1": "21b69f42306a5a27cadfe6d80c334e0733ab52ac", - "sha256": "efcd28ce76ec40846e291476a3e9155cad3edbd838a40ff4a4f3074deb2d7ea8", - "size": 1669607 - }, - "447": { - "releaseTime": "2012-12-16T21:13:04", - "sha1": "8ea8676eff9c3c27cc98c1a713ef58e65744e765", - "sha256": "7e08e0f7b54d67f6f26c35336a629f724455856822441507649224689d28ec98", - "size": 1670780 - }, - "448": { - "releaseTime": "2012-12-17T09:01:44", - "sha1": "13a9f80d41adf293179a39e5b6a484871d14ac44", - "sha256": "0189e4a7f4a9c41924f2a52fffad0e40657b5442743ee4e4f43098d72adf25e8", - "size": 1670806 - }, - "45": { - "releaseTime": "2012-03-09T17:26:54", - "sha1": "801c29b3682f1af358166a262ff882085709e050", - "sha256": "025d932795079e1f305cdbcad4e2144334ccc91f1d028b619d71ef844e29373a", - "size": 499542 - }, - "451": { - "releaseTime": "2012-12-18T01:35:54", - "sha1": "421993ef8f69c3a9409eb4d5ed7fc2c425066c9b", - "sha256": "c9e195b010bd0e1c721e58270e7d3cb6beb5ceb18e95be60a5a04fccc19eb3f4", - "size": 1726000 - }, - "452": { - "releaseTime": "2012-12-18T06:33:42", - "sha1": "2a2c3d7656179a3576c68ef05593241cab30dc89", - "sha256": "894c384a989e22d644708a18dd4b2873c2d8d1a344a46fa268efb8453d6907a2", - "size": 1726210 - }, - "453": { - "releaseTime": "2012-12-18T07:25:04", - "sha1": "4efb68e5ba7e83f30e69e4e6417d937140a37843", - "sha256": "36c23bb5e8c524e4633b17feac709f499c7d4d44178f4fcfcf1e75a9f7034792", - "size": 1726167 - }, - "454": { - "releaseTime": "2012-12-18T07:59:58", - "sha1": "6a37494bc27f2a931ad7a55071d799b0c14d322e", - "sha256": "f52e50343683b49c102f25a595cb9298bf38d6bbb431d66b2d25edbb68f41875", - "size": 1726248 - }, - "455": { - "releaseTime": "2012-12-18T09:05:42", - "sha1": "a6769078d9dbeda08be78d1ff98e8398948db030", - "sha256": "fba9f76b198b90acff4b1e73ff313d13c6b7282aa40baf9b782bad7d65f8380e", - "size": 1726503 - }, - "456": { - "releaseTime": "2012-12-18T11:37:00", - "sha1": "0a04ca649837a9254daa96691d51011bb25da139", - "sha256": "b68b9b26db586479608c0b76054e345832d4e697933662664b7d26edfb9183a9", - "size": 1726508 - }, - "457": { - "releaseTime": "2012-12-18T12:23:28", - "sha1": "32815602e585fa49d469911f7afbc9477af3dd14", - "sha256": "f8ddcaacf7b1eec6d564608fd3a127e71ad50430fe00a9a689aea25ba9798d44", - "size": 1727433 - }, - "458": { - "releaseTime": "2012-12-18T15:13:42", - "sha1": "41ad6776ef46795e9d3fb219f0cc70deacc322fd", - "sha256": "47964bd168713ec45d60d0909ac004970d01acabb5f117d93bb67e2c36970064", - "size": 1727457 - }, - "459": { - "releaseTime": "2012-12-18T16:06:36", - "sha1": "a75f08410a16f34504503464fac3585d1cef9dad", - "sha256": "f05ca5f2e4e507cf1e9d117dfaf7f06a0c96cbb2ced0de2ad99b16421dae945b", - "size": 1727472 - }, - "46": { - "releaseTime": "2012-03-09T19:00:00", - "sha1": "249650d67d67be25f72835ab5ef7524f488f1804", - "sha256": "7c1b57a1e1297aa0766bd3a52dbe18f5d38d17e013622af681a11e3e8958014a", - "size": 499542 - }, - "460": { - "releaseTime": "2012-12-18T16:45:26", - "sha1": "82d3f2945980277af4e5562283b46d5c99c33192", - "sha256": "01c47f5cc5326ba08b1372abde90598e8fc47b557fe737f04db021f0607a5972", - "size": 1727478 - }, - "461": { - "releaseTime": "2012-12-18T20:15:42", - "sha1": "736ea6a5de8a8631f179958c727af63cde2534c3", - "sha256": "e772575ec613c557ed7e83e1fb55c855d9cc0cc3396636287e1609c63a78977f", - "size": 1733216 - }, - "462": { - "releaseTime": "2012-12-18T20:22:02", - "sha1": "c5870d3b28063d0e2c2e1320d47d1cd883953d27", - "sha256": "29b5e43ac1ebf8572cf8a426c51fc8eac132ebe62937b8297bb6a0bebe6495ed", - "size": 1733220 - }, - "463": { - "releaseTime": "2012-12-19T14:47:42", - "sha1": "8964d7dbdf6db684371b79f31f2708daf26a3d65", - "sha256": "61d212a885d5d9903fa3653246e492ad243afb191353c74fc5cf3e4ae02649cb", - "size": 1733227 - }, - "464": { - "releaseTime": "2012-12-20T06:29:08", - "sha1": "8f3649a5743184c0b1b09653749cff1aa2a817d3", - "sha256": "14206ed1f73ba0b305637a0870ef70ac7ad52d3b44961effca54ec36dc065753", - "size": 1733293 - }, - "465": { - "releaseTime": "2012-12-20T06:55:52", - "sha1": "2f8b54e20bd0968be3e54e2d6a160f325acd6b11", - "sha256": "e26f8e433197a05ec0e7e8d663bd0ed8ffba274c9c462af727275ea03f5e067f", - "size": 1733394 - }, - "466": { - "releaseTime": "2012-12-20T08:55:54", - "sha1": "a3aadc9017870b125e86aa174151f2f8e6c4bad0", - "sha256": "29ccb3022faad84e868df4d7106699c4ec04cc2aa042dc7e77a105e632d5ba6d", - "size": 1733369 - }, - "467": { - "releaseTime": "2012-12-20T16:07:14", - "sha1": "ebfb8b5a38998ac3d15a49ac421270399a35e9e6", - "sha256": "a8a1ea57487d9074247eacf61cf12ea62ff1de07e6bbe10a87492a54da4495a5", - "size": 1733972 - }, - "468": { - "releaseTime": "2012-12-20T19:45:14", - "sha1": "872cad36bf9fbd8b570c8839786665476d3d37e8", - "sha256": "4f1a56fc643c96fed83187c4c9caebd7c7ecd1e1abeae8eb2c4f20e04f341c39", - "size": 1734950 - }, - "469": { - "releaseTime": "2012-12-20T23:53:48", - "sha1": "7426aac26d35e178b3d2663b4d506a82d00a3f85", - "sha256": "7bfc916af6e0754c2cb8fa7775e22883af8766d1586d1214b9f88f0c47c5d237", - "size": 1734950 - }, - "47": { - "releaseTime": "2012-03-10T17:12:54", - "sha1": "658451d143a3e9acbfdb405bbb7e6a9d0cfd6bea", - "sha256": "201c8e614888d675355a780ba7e14ee630bc199b6ad5a7d0e4dae18f85236e01", - "size": 499538 - }, - "470": { - "releaseTime": "2012-12-21T01:20:06", - "sha1": "9df25c7d137cac8bb6f01fa947fa6f7cb1ed5730", - "sha256": "dc7585b24d6c54025f373908af901f63b2d460832c036ad4ee68f410b4c5cb6a", - "size": 1735047 - }, - "471": { - "releaseTime": "2012-12-21T07:29:44", - "sha1": "4efb1b18519a23f5c00f9067f2391b6d08d3a5f0", - "sha256": "090c3a55b08e8ad91b9b77cb85a53234687c9a94259557dbb723966cccb8cdb4", - "size": 1734974 - }, - "472": { - "releaseTime": "2012-12-21T13:51:46", - "sha1": "e6e08713a05d0848b69de728aee4657f3a3c5efe", - "sha256": "11d7bd50322b63c8dadb6b6b0b3b57c0e077fd1a62d08f18c4141466598e49ff", - "size": 1737294 - }, - "473": { - "releaseTime": "2012-12-22T05:13:46", - "sha1": "5c729491f944ae248bbbbfa4c3538ab55d8e3ad3", - "sha256": "45f164a5433be75743a271aa7ddd2489d2c2acaa11b39edd687c2c319ee22969", - "size": 1744124 - }, - "474": { - "releaseTime": "2012-12-23T13:37:12", - "sha1": "999bbcd15fa79c272a733b0cf66cbb894a1b3f68", - "sha256": "953721125acc90d1ba8e1092508b9dc844956a412d47c4448ce5150a5aca8c7d", - "size": 1744238 - }, - "475": { - "releaseTime": "2012-12-23T22:54:44", - "sha1": "3a1f3803a43b2e7c506a344b88c7832c808462ab", - "sha256": "3c18c13011d4274e56353e4ba04c1295e7a0d41f4f5dd2bb779df8ddea566862", - "size": 1741653 - }, - "476": { - "releaseTime": "2012-12-24T00:34:20", - "sha1": "2daa310149da3edcbb7d08faa58760a21c26a8c5", - "sha256": "9e7e4d1cbdc912c31c114e129217ddf97346e0be91fbf82c3ea5cc5832a800d8", - "size": 1741664 - }, - "477": { - "releaseTime": "2012-12-24T00:40:32", - "sha1": "bba7b620d135e62ff4158ab41252bcf9174b4110", - "sha256": "34f421c1a173ae1afe7cad37eb326560919c176e3b67031b698546e9707c40f8", - "size": 1744371 - }, - "478": { - "releaseTime": "2012-12-24T02:33:06", - "sha1": "e9a4f006c0bb89e12c6653d336441746e10ec0e1", - "sha256": "7ae27b002491dea6ce4563582a52da6c559a17896af281ad2a87e9dd6b87e72b", - "size": 1744491 - }, - "479": { - "releaseTime": "2012-12-24T02:42:26", - "sha1": "48678d934b09e484b66cdedd5ea02e8a34891418", - "sha256": "5ccd19915392c33809f26334f2bbc8c0c40dfcd221abea01f56efaaa00f83df1", - "size": 1744492 - }, - "48": { - "releaseTime": "2012-03-12T12:23:28", - "sha1": "9c64c3b621f2d2d3e0b9a45aeeb0c81e6994508f", - "sha256": "3cebc5d52ea6595868522a3643cb1b75067e86b6831ba69056aa0dae6ab202b1", - "size": 499538 - }, - "480": { - "releaseTime": "2012-12-24T02:58:50", - "sha1": "3d760ec785b329dc04fa59342b381dd357336811", - "sha256": "d06834960396f393714a92afcdad10a53ae774d086d6b03139e057905d28124f", - "size": 1744429 - }, - "481": { - "releaseTime": "2012-12-24T10:18:58", - "sha1": "1ff2196efd74a559216860a70b85f09e3e63de9d", - "sha256": "73dcf5b3f1744c61a43c0f9c676b3092dc1167687f3870ec8e49ed8e4c2692b4", - "size": 1745086 - }, - "482": { - "releaseTime": "2012-12-25T17:20:24", - "sha1": "699a44e90e186283858c06c26ae61591c0930ccf", - "sha256": "477e063f1ad9bd5bb82e373bd592d834d4379283f58e3c3add051c5381adcea5", - "size": 1745156 - }, - "483": { - "releaseTime": "2012-12-25T20:16:10", - "sha1": "3058f414ed26f7a17716dbfc714059634814af7a", - "sha256": "63ed21d141b96509b487741a9ee8b8eb91c5ae107737f813bc56037cd8a51920", - "size": 1745409 - }, - "484": { - "releaseTime": "2012-12-25T23:08:44", - "sha1": "22917af8817870ec59c31b47f444e3f3775f8dcf", - "sha256": "36be7238426914c4d6146d58c1961070d49cf69fb6ca5077fdd0f094e56dd36e", - "size": 1745586 - }, - "486": { - "releaseTime": "2012-12-25T23:32:22", - "sha1": "da305a3cea5057bf8ba153fd066631c11b05addc", - "sha256": "483741ff2cac45c6e4a18784b3940420af399598c4efd467dc73b9235dc891d3", - "size": 1745580 - }, - "487": { - "releaseTime": "2012-12-27T14:56:32", - "sha1": "610de83860eec1991f86c9965a76f87b89b08d12", - "sha256": "ff4b78cb32de1a57e7beb6fe6134033cce0defa90272dbc449745f224ad821a8", - "size": 1745542 - }, - "488": { - "releaseTime": "2012-12-27T21:24:56", - "sha1": "473485ee42c5a18ab47994bceff362da0a1bea55", - "sha256": "01f13df19856643460dc7cf95c57769ff34f1413187c6f88b858f43be28bb55e", - "size": 1745935 - }, - "489": { - "releaseTime": "2012-12-27T23:17:08", - "sha1": "ad4b1579edf9053d7c213fadcb7d10538c88a1ac", - "sha256": "241c88f0eec5b75d49a6a9561ef8af6dbe1caa3dac7977141fdc60fade59e758", - "size": 1745975 - }, - "490": { - "releaseTime": "2012-12-28T10:15:24", - "sha1": "12af97cacd54e55593e5879d5c214abe6ddd898c", - "sha256": "07ae2b7d06ef4c80c7d19e7bddf3ea610257f8989cd87016f6fc5135b49c9a57", - "size": 1745974 - }, - "491": { - "releaseTime": "2012-12-28T22:36:56", - "sha1": "5ab9a4f78adfb6b345bbca0cf8c92effee616f67", - "sha256": "17ddd3251dad9359d624fa5cd2e198561cafaa341ceb37c37a57f83f3ffbd66c", - "size": 1746029 - }, - "492": { - "releaseTime": "2012-12-30T21:03:42", - "sha1": "24dc432e3d6a7c1ff28900cfab9c7168c6e51530", - "sha256": "585981eac33151616981789662507f1019072c9891da48880e5ed48300d62e5f", - "size": 1746383 - }, - "493": { - "releaseTime": "2012-12-30T21:30:20", - "sha1": "01cf4d59115b3bf2b8cbe2e54d6703200016d2ec", - "sha256": "faef915c0307bfafb20f21db5e606a155470381e98c53f8de0f3748c859ab150", - "size": 1746349 - }, - "494": { - "releaseTime": "2012-12-30T22:09:10", - "sha1": "06b2c1905ca8de001b823b0f397d21b4b8c45dfd", - "sha256": "91d5fe316e253992c5c6b7be88e8f353bce4cbe8958a314a4c6242c6e5581828", - "size": 1747746 - }, - "495": { - "releaseTime": "2012-12-31T09:26:20", - "sha1": "90b567013a6cd3abd28f6acef8da13be80139309", - "sha256": "367de6a4bc90ad1cbf1fa4503cef59da1b00f46e9ae98c54dbca50d9a6a3039a", - "size": 1747783 - }, - "496": { - "releaseTime": "2013-01-01T22:02:56", - "sha1": "ec5da86e1eb98345401f289a677e22d9ff39b677", - "sha256": "036cfa78ffdced3f8d1e9d07a9a4cad8bfe6106ee6a2f323e0f46f7bb75cdb59", - "size": 1747767 - }, - "497": { - "releaseTime": "2013-01-01T23:23:56", - "sha1": "6734cd7a2de6fec77c0745a4fd054f56547f1b45", - "sha256": "b46dee407c06cf73bacd12a7d2ae3be48b6745f2b160c5d3853fe0c9d94914cb", - "size": 1750532 - }, - "499": { - "releaseTime": "2013-01-12T21:48:34", - "sha1": "3853b9b6c90063764d9cbcb7ff95c2bfbc2e40d3", - "sha256": "4afccd945b9536a3432136086b32e2383505bfe595a5a1e446eae032bdd98f8d", - "size": 1750887 - }, - "5": { - "releaseTime": "2012-02-10T04:05:56", - "sha1": "14c5933f019a36c72ac21447223922d225d8ca12", - "sha256": "65d74f1abb6bb748cc42f8e959974e768bcf4acc828122abf37b2c2cf8f3922b", - "size": 418025 - }, - "50": { - "releaseTime": "2012-03-12T17:00:18", - "sha1": "493cacd2e0fd442d22bf602ee630f662a94a09e9", - "sha256": "1e0b71714d6b755bb8b88833774ccf512119e4011f176921343bed43772bf0e2", - "size": 499533 - }, - "501": { - "releaseTime": "2013-01-20T09:04:36", - "sha1": "71e3564d1dd45c032f863f91ced3c5e0b31adb97", - "sha256": "f1152a34c0cfd6197a51e2ab11e0e9d792335d44334c7d4fd76b895d6d9bd5c4", - "size": 1751447 - }, - "502": { - "releaseTime": "2013-01-20T09:47:06", - "sha1": "9b5f5d1bde50cf315c59ac505b344598d31503ae", - "sha256": "f2fbe43bf2931d1c9ad60e44186c9246d3d62ed83b571faafb2662a4b5ad3ca3", - "size": 1751313 - }, - "503": { - "releaseTime": "2013-01-20T13:28:28", - "sha1": "2862ddfb1247e3fa63feaf75bb6eb89619641555", - "sha256": "4c7f9472f6ed96859baaa602f5d93a033066e6e584245bae85d44b884cd1c016", - "size": 1753210 - }, - "504": { - "releaseTime": "2013-01-20T16:53:24", - "sha1": "207a042ae365d8c57c8edca3116ade1b04ed558b", - "sha256": "eb99b88ceaf65b6090c5d1d2d8ebbacd17f363988ebef764639e038f5cde1f03", - "size": 1755376 - }, - "505": { - "releaseTime": "2013-01-21T20:03:18", - "sha1": "039029b9d3c5bca4459a2133d48488763b435391", - "sha256": "f2e15042fa418e6ac9380399a755739a4f9f8145e9f6d616516d5c0e6a594e87", - "size": 1755366 - }, - "506": { - "releaseTime": "2013-01-22T08:14:22", - "sha1": "5f3d3cba6c563334f585a0d3f2d1c1d3bfb673f5", - "sha256": "e36aa8cf1dd69e504ed58caabf140b804a172288b58b4dc343551f5d8d20af01", - "size": 1757249 - }, - "507": { - "releaseTime": "2013-01-22T11:59:02", - "sha1": "df4a34e476f7ee94a435ef8f26513b926afa770d", - "sha256": "3a2c6b8904c605c028465e4e64e71e0cb24121c705a7f271909b56b254af2de7", - "size": 1757663 - }, - "509": { - "releaseTime": "2013-01-23T21:44:32", - "sha1": "e7d8ea9367667e29a6fe3e0b56b888e34a7c6c2b", - "sha256": "6351f2bebfa1f5255f8310c06c274bcdc42ede5e262674bf7df7ef00c1a5b3ae", - "size": 1757812 - }, - "51": { - "releaseTime": "2012-03-14T11:57:34", - "sha1": "19428f0e666c4050a5f0d6ba066471fdd10a4e95", - "sha256": "b09b008c025b1a8ea35821c653fbb16aeb74a2b68a0113d5d46012c8fcd0d169", - "size": 499534 - }, - "510": { - "releaseTime": "2013-01-25T19:25:36", - "sha1": "bdbb8003de83e6c136e1ce523c12de6109726e54", - "sha256": "0b20a127a2d61edeec71ee1baba52aa92a35d82880e6c660c47cf750d0d83b32", - "size": 1758064 - }, - "511": { - "releaseTime": "2013-01-26T08:29:26", - "sha1": "37e54676fe4db1dc8cfb2b56f3d5344024aca44d", - "sha256": "06a0d1ebdb10344a1949d03cac65f73e88e59f364b4de7728dedf5e8e749221e", - "size": 1758076 - }, - "515": { - "releaseTime": "2013-01-26T12:16:40", - "sha1": "d09d5267e419bc6f35e065789eb87780bc69c767", - "sha256": "15a1c1b749c840e55ca27a2bef419f710d334351284b20526c3caab6730bfde4", - "size": 1758042 - }, - "516": { - "releaseTime": "2013-01-27T08:49:18", - "sha1": "c02c0f5e08e7c975b9b7685fb43ee41f992386c7", - "sha256": "6a7c899130ba3be06f421df8b5874f5347d28944ac2304ac321f8553345797a9", - "size": 1758848 - }, - "517": { - "releaseTime": "2013-01-28T19:23:52", - "sha1": "85730f2eab50431f06074f56fd45ac52f35e7888", - "sha256": "bdba524fdafb87e57b8c8e1beff2ae2d577a16518092198c49f4201fb8851539", - "size": 1761462 - }, - "518": { - "releaseTime": "2013-01-29T04:17:02", - "sha1": "2cd88ccf1af60465380efec07e0a3cef13f4c922", - "sha256": "05736dd9d54e6a92298a1e945da8319d88e0949bb4088b23c0575e87c0a5fa4f", - "size": 1761405 - }, - "52": { - "releaseTime": "2012-03-14T16:56:06", - "sha1": "a7a92d24b575d901506285511817bce22302bedf", - "sha256": "58dcce37e0a45cbbc79ce0efa5f19fb1f0cce4fed70fa1e34061c37c949bb32f", - "size": 500306 - }, - "521": { - "releaseTime": "2013-02-04T09:25:46", - "sha1": "087bdb006cd96f6ba343901cb49b62f10c3c1bcf", - "sha256": "648a9d61659d83d49e0f054913bd945b0d78493e5b3f939c71725e48fbd2b435", - "size": 1769480 - }, - "522": { - "releaseTime": "2013-02-04T12:03:06", - "sha1": "386872fe1744a35dec7e0311335977d9595bf2a7", - "sha256": "6550ed6b0828e93525b3186f7de2e90cf865c37fb308d9e48bad7d96ef91dcc6", - "size": 1769519 - }, - "523": { - "releaseTime": "2013-02-04T15:58:18", - "sha1": "cfe19e7ac7c15b6be821d5af5fd75beac7f1914f", - "sha256": "c8426060eb8bee5020afb0fbf029a4a2f45d2db8a6293d93d8e82cf73f144d8d", - "size": 1769094 - }, - "524": { - "releaseTime": "2013-02-06T18:36:06", - "sha1": "d86aded1f0e1cf6e6fac264be9ac3d26c1b0700f", - "sha256": "92a1c6faa1770fb2c785619834832e3a5825177206afa91d4c55a1b01d6a9622", - "size": 1769480 - }, - "527": { - "releaseTime": "2013-02-15T06:39:20", - "sha1": "6fbf800c40a7ae21cafd5355a7b8b4d8b46bf95f", - "sha256": "5dff0742023186542bdabd8019bbe58b8741328c9f88399fc4d808663781ae41", - "size": 1770314 - }, - "528": { - "releaseTime": "2013-02-22T16:12:28", - "sha1": "c81b6fbba954448137846b9b920203c7260a070c", - "sha256": "48e4bee76f2106ff36adc225c699f28d4ab7c72f420f3c3f97be5fbbb98dd38c", - "size": 1770590 - }, - "529": { - "releaseTime": "2013-02-23T12:27:12", - "sha1": "275c135f5f0617b6f5ace20d7a00f0668697d770", - "sha256": "216cce520e834f6e6239fbd0f3d5eb06344870d575115b680cbd1433814fda45", - "size": 1770653 - }, - "530": { - "releaseTime": "2013-02-23T13:23:34", - "sha1": "04a7307ba922860718b4700ca6c7858d24148f98", - "sha256": "675b7e15378c3b69483208065edace129ed313a4104c0e9a420241ac8a0e45da", - "size": 1771375 - }, - "531": { - "releaseTime": "2013-02-23T14:11:28", - "sha1": "932b3ced33034df13662f18994afaff9900c385c", - "sha256": "98fb1a46e54611e4829bf3c1434e44f4234949fc059fee564db78bc620e808c0", - "size": 1777234 - }, - "532": { - "releaseTime": "2013-02-23T15:00:26", - "sha1": "bcac19ccf60bfd4b13f6f20dab638c58cc043146", - "sha256": "36c55d2d17ac830fba3de5594b7f38c686a5f54933f0ea08aaeb9f95319c2d36", - "size": 1778535 - }, - "533": { - "releaseTime": "2013-02-23T15:25:20", - "sha1": "c3886f37a70edf593fd643db522afa1d1cbd9137", - "sha256": "3408ff09133b41cb2b3e7a667c9cbc79a4b201f30f98b889fffea8af55ce1f8b", - "size": 1778541 - }, - "534": { - "releaseTime": "2013-02-25T00:00:20", - "sha1": "bd0f40a78c18140265ff042a96d73f01c4f60906", - "sha256": "7ae860d3f7423b97b1fb5343a65fcc6866242fde23e1aa00c113dd9b61fa8187", - "size": 1778669 - }, - "55": { - "releaseTime": "2012-03-17T19:58:18", - "sha1": "4a921565b941fd8883513b79d27767622fd7440b", - "sha256": "d5baa47e296c2f18b2b69f5acf525bb3635bb728ba5c0e278c58fe71057d809b", - "size": 500341 - }, - "559": { - "releaseTime": "2013-03-09T10:59:20", - "sha1": "7cefe2301914b7859cd8282630a9a17f6c27d433", - "sha256": "7d7ab7709fbd637a51250aa2d8ee9a2eb6c6f62843d089bd90aed6b3a7ee71eb", - "size": 1799274 - }, - "56": { - "releaseTime": "2012-03-18T23:43:50", - "sha1": "21181f018ad9aad7bb173126fee729b3fb1bf51c", - "sha256": "7a64787f1c09dddbe48a3f61b283e3b2fa82b832b6a329561f45904a94547102", - "size": 500331 - }, - "560": { - "releaseTime": "2013-03-09T11:16:06", - "sha1": "513348c4938d80fcac62b8fcbfbf802671fb374c", - "sha256": "a0a3967f4371154520b5904630f51cb6eefd489c2df6aa6a5ada21f82df6c7a4", - "size": 1801695 - }, - "561": { - "releaseTime": "2013-03-09T12:20:34", - "sha1": "b64dbb4a6e5721354070ed43cc8e565f004f983c", - "sha256": "9f6a313add3dc0035bca35e227701b10df8bc3de48765c519c0ab8c324bdef6b", - "size": 1801871 - }, - "562": { - "releaseTime": "2013-03-09T13:02:44", - "sha1": "753e3a080941052cccd7375df5f63564a86b7fc3", - "sha256": "a3a65288216568e04c1195dc232fd469d0cf40a1ea65c085f5c4499076d72fc6", - "size": 1801898 - }, - "563": { - "releaseTime": "2013-03-09T13:35:42", - "sha1": "a3ac851d0aa5cd19b4f5015cf9cc1f0ccad1c3ea", - "sha256": "f3434b432994d59c16f3a73a432211a1a8064df619970f765e1d30541c0bf985", - "size": 1801948 - }, - "565": { - "releaseTime": "2013-03-09T16:04:34", - "sha1": "cccb6bf2733a4cda8b05d4a9176ab15deaa29b25", - "sha256": "0c5d591dba0d5a7589a953cb0c6e14b2a2b2f245f110f1afec909ad41bcad81c", - "size": 1802067 - }, - "566": { - "releaseTime": "2013-03-10T10:19:34", - "sha1": "471051946714e5a831d608d40f34ad09a0e81da3", - "sha256": "1c7fee319ec0bf88ad77c7ceb8f6d38095d8af9009bccdade5de1ad07ab9da69", - "size": 1802209 - }, - "567": { - "releaseTime": "2013-03-11T14:42:34", - "sha1": "85d19c0406314b6a1c931b905c8abd991342af53", - "sha256": "ea006ce61b4585283237e27995a3d5486fa26e4b0c221716ae9f320f6e2f6f4c", - "size": 1802207 - }, - "568": { - "releaseTime": "2013-03-11T15:48:22", - "sha1": "d49f2abbf3d4471d8039707e80df85d4f1a858dc", - "sha256": "e3759b326137fc5426dbc4f5606781641ed0f93266671fa653911a11cf7db770", - "size": 1802260 - }, - "569": { - "releaseTime": "2013-03-11T17:33:56", - "sha1": "895318254c2a15f84c31a4066a0c7e1d013f2bd5", - "sha256": "2ace28caa0c6bb929bf1c360699feeaef299d69ec5590d02a387e7fdfa585d81", - "size": 1802373 - }, - "57": { - "releaseTime": "2012-03-19T10:36:28", - "sha1": "3821f7764661d74ab8b84acd41c3145f595c9dd5", - "sha256": "cfb87dbd958a9cd46e1bd312a10df884f813fa738edd1db34a6a340563c50fa2", - "size": 500324 - }, - "571": { - "releaseTime": "2013-03-12T16:27:20", - "sha1": "256a746fdca6952208588476c8c1a67e214fcb5a", - "sha256": "20e49414075e9c980de3e9889eeb760b33d7696cdfff730bca8e4abd2b17fea3", - "size": 1802132 - }, - "572": { - "releaseTime": "2013-03-12T19:11:22", - "sha1": "5421a1e7613ec0c54dfe29fe78747dd4c3ed4ded", - "sha256": "e3e2cfdeb8f92d0b2961caed878ebfe8e3783a64539b03c016596ac9b90e5384", - "size": 1802718 - }, - "573": { - "releaseTime": "2013-03-12T19:22:56", - "sha1": "c4e36dfe96db003635afd8f5d0dd1ee9c9330b23", - "sha256": "dc403bfc35df2bd0ceaf91d3f33bff1f50e0fa51c01758f46a5bf61765ea543f", - "size": 1802799 - }, - "574": { - "releaseTime": "2013-03-12T19:48:20", - "sha1": "970862c9cbd70b7e31b52426ddd0cf948c9a9ce8", - "sha256": "04a7b09abd5a21eb5d75627d892b4b6971bf12f8dd1267fb902df46c35002bf1", - "size": 1803367 - }, - "575": { - "releaseTime": "2013-03-12T20:50:38", - "sha1": "0e727130e6492c26fcdea9866b91f2af8d0ed9e6", - "sha256": "13a50326c5d78cb3aea9f5fed7f415bc4499e33acb9bd41c7d30fd3e90ea3d17", - "size": 1803644 - }, - "576": { - "releaseTime": "2013-03-13T12:02:16", - "sha1": "88524debaac98b4a7e81713789a33278fe3b1dbb", - "sha256": "09ed456116397421fe20ecda9fd73e252ce953e5c9712f9ba3af5a1b5f7bb662", - "size": 1801710 - }, - "577": { - "releaseTime": "2013-03-13T12:57:32", - "sha1": "ff91a570c54f10922727007f1d89e83f73210d79", - "sha256": "7653623ab8f74478ffdfb422c5d021cc7a18906c96fd356fd90d7b0fef2d5988", - "size": 1801735 - }, - "578": { - "releaseTime": "2013-03-13T13:10:30", - "sha1": "e0cef279c9a067955e9519aaf5c28cb38c9fd45b", - "sha256": "ade4e84a7eaa1f5d5f7f9af945862ce7817f32628b800f9f86973eeb39ef343f", - "size": 1801793 - }, - "579": { - "releaseTime": "2013-03-13T13:22:36", - "sha1": "1249b4843235da3782d98d917c90d309b91bc4ca", - "sha256": "d4d4bb20f765c5c8e16f6ed9d32aa90c35c7f2c0e740b37396568c36a68f6ba6", - "size": 1801812 - }, - "58": { - "releaseTime": "2012-03-19T22:42:46", - "sha1": "9985d536259cebbb8f139f8ce3176b22039270ca", - "sha256": "06e87b5a04c7ff02c481195175d0a198e964285a9aa637e72eda0421c6018a9c", - "size": 501964 - }, - "580": { - "releaseTime": "2013-03-13T13:34:08", - "sha1": "d756a4fa056fb7b2f6768f7d0fe2d912c28b4c8f", - "sha256": "a7dc5fffffa88e4f8d0318ba7a844c63913a127926b9844104085d5450097527", - "size": 1802410 - }, - "581": { - "releaseTime": "2013-03-13T13:45:54", - "sha1": "3b3bed47c3f1779c5d2080310a20cef2474cf7c2", - "sha256": "8d3e539e593ccc4cb25845ef6901e64f309ace1072bfe43676c16afbc5827bf6", - "size": 1802422 - }, - "582": { - "releaseTime": "2013-03-13T14:20:52", - "sha1": "d38d55e839820418b8597a4c20a27926094da29a", - "sha256": "bcad9e4bb77021662a9934d03055a90d373c48e995f6a37ef09f74c984553015", - "size": 1802412 - }, - "583": { - "releaseTime": "2013-03-14T14:06:14", - "sha1": "2cbe8b97154514dbdda74c96118672356596c59c", - "sha256": "e59ec936b65388d4c757dddbe918410ef3628b406993e407d348e31ff1619b57", - "size": 1802447 - }, - "584": { - "releaseTime": "2013-03-15T21:35:12", - "sha1": "cc83161006e3001a0b6abbff6d5866c5997f122e", - "sha256": "cf35a38f6eb00d0b5939ffb6eb749f0bd0bc7efd7a5da129cca94b5bd052964b", - "size": 1802450 - }, - "585": { - "releaseTime": "2013-03-15T22:28:24", - "sha1": "67851281cd6d7300cfa4f6ed40d36ec91b3a93cb", - "sha256": "fe2ee5a25849e6772c37dab140a3025733145872bfc44048d0fa85bbe671d75f", - "size": 1802442 - }, - "586": { - "releaseTime": "2013-03-15T22:42:18", - "sha1": "28a200368e5e57b42b81515c665d547714e75feb", - "sha256": "c94fde4b5256d311b51f9a2b5df88e0f637baf7b600664f9303d43304dfdec8f", - "size": 1802483 - }, - "587": { - "releaseTime": "2013-03-16T11:52:38", - "sha1": "2cf449d932668dc49da5ceec7fd12b0bd0588670", - "sha256": "426c3326e475e5603311db05cf785809b6ea99597cf5fba9edbd718cdeaacb0b", - "size": 1802487 - }, - "588": { - "releaseTime": "2013-03-16T12:35:28", - "sha1": "9fbe0dbdf36173a5c2d873790148c533957af2c1", - "sha256": "c5d033bd0d05fef758c23a6374f1f628fba6c0102d88d0d2dcd2a313c81ec685", - "size": 1802499 - }, - "589": { - "releaseTime": "2013-03-16T13:59:58", - "sha1": "07cb240272a941a01b1314a99e3ea5dcf093a8df", - "sha256": "f23fb37f45c28e246c461fcedd135ce473d0aa3da62141408a759ce164a7c475", - "size": 1802541 - }, - "59": { - "releaseTime": "2012-03-20T06:50:10", - "sha1": "c22cb4824886aa26a95700f38768083cc84a0b70", - "sha256": "b00bdbdae11e16016759850278a79da857b7c19e91762b15b5cef2022834f532", - "size": 503801 - }, - "590": { - "releaseTime": "2013-03-16T23:21:04", - "sha1": "3c5c525447f98d3abeeceab5b68e3318273c25a8", - "sha256": "1f1e552ee329f4fbc9bec71060406dc52375aeaf0f4d25b8b585aa7268670e6e", - "size": 1806206 - }, - "591": { - "releaseTime": "2013-03-17T00:16:14", - "sha1": "75817e473b6f290c881e5de9ff7084c3807247d3", - "sha256": "3e9f5ddaebb29ee4c43f0b54b1859054b43dea5a9c4cc487f0f1706525e33e56", - "size": 1806210 - }, - "592": { - "releaseTime": "2013-03-17T13:11:16", - "sha1": "b6b44424f0c57a36d0b4d2fe38b3ddc837e0bc24", - "sha256": "978578203b4490875b4781511b0ce70f987a5c370c61b597c33aeb8168135f2a", - "size": 1806617 - }, - "593": { - "releaseTime": "2013-03-17T21:15:24", - "sha1": "868f3bd54310b460d99aa4fc948d814904834b6c", - "sha256": "3c05e042f959aa93de758811ba5c4fd6fcf2b1f8f88d014e3e4679f04bec7a33", - "size": 1808804 - }, - "594": { - "releaseTime": "2013-03-18T06:19:08", - "sha1": "05dcca538da1ba41ac5e59e74eb862121cb5be88", - "sha256": "6c6d1fbcdf7d7afd8ba6bdd085517b06c17f19122ed471505c9e87b2e27a7857", - "size": 1810025 - }, - "595": { - "releaseTime": "2013-03-18T15:37:20", - "sha1": "10fe3da7c4f5c5897e7dc1bea826529e9c6cd240", - "sha256": "9f3eee1df41b9de671fbd5ea43537d303be4c86366678b1fc2423ae1072fcb97", - "size": 1810024 - }, - "598": { - "releaseTime": "2013-03-20T19:59:44", - "sha1": "51fa60cdafaa9497465e792d3ec884c2fb411bd1", - "sha256": "ee98f47baa521a317f361ad44d3f62677343a8aa46605a949d8eac2c5a297f3f", - "size": 1810101 - }, - "6": { - "releaseTime": "2012-02-10T07:00:32", - "sha1": "469c7532e6e92ce5be68e850643a2b03b305c9df", - "sha256": "a1c33cb061da2fe86fdb7d46c8744f52b9661832de7422f22e64228eef4b323c", - "size": 421298 - }, - "60": { - "releaseTime": "2012-03-20T22:13:54", - "sha1": "3fb0ca0321285a9b7ec52bfe173ce905c45f6ef5", - "sha256": "c1bec94a7d15a2d761ca132b3191836a9cbc57df1757ac89778494699f45f63b", - "size": 502757 - }, - "600": { - "releaseTime": "2013-03-21T05:58:52", - "sha1": "f100c13093c7cbcc647d01db0e06b033857ecc44", - "sha256": "3490da99bf1a9d02ab3723b806ea4b2544df3ef760f4d3f3716e28d125f617d8", - "size": 1812847 - }, - "601": { - "releaseTime": "2013-03-22T00:00:40", - "sha1": "65b86fdcaf4f0d3ae39f4ef6060df038c0246a4d", - "sha256": "6b828b19a733beb784689c651f31576d49a4828a4bd1ab6d326028f8c75db4e0", - "size": 1812890 - }, - "602": { - "releaseTime": "2013-03-22T07:38:02", - "sha1": "02c4747b8f443a6baabd42808641901c7316d10c", - "sha256": "e992506a04eea308de41e0440acfcc2c5862aa815192864de874511213772ce2", - "size": 1812888 - }, - "603": { - "releaseTime": "2013-03-22T10:43:46", - "sha1": "035a390467f9f8fee7109ed68261b97ba4d3b4df", - "sha256": "87fa43b1060b04aedc0c51896605cb5218abe9286ec8213312e860da86abf782", - "size": 1817618 - }, - "604": { - "releaseTime": "2013-03-22T12:14:54", - "sha1": "d08a3ffc03ebe236906205dad90a172f6170eabe", - "sha256": "b88c74203121c64ec61db3b5c80ba684ce72ed9b81dbe30fe4c965c3a6bde6ca", - "size": 1823680 - }, - "605": { - "releaseTime": "2013-03-22T15:03:40", - "sha1": "4f500cf41d5c988df867232ca366f329b1bd59e7", - "sha256": "1ae4763067a05b6774ae49929f2f003ab239fdd8e8e63bbcb0d7eae2b25af426", - "size": 1823687 - }, - "608": { - "releaseTime": "2013-03-23T21:30:56", - "sha1": "decac58077e666780177384985f01079c4e2bab6", - "sha256": "01db87c37d61ea353d92edf8f97fba8b1cc8100f59e79208b2fd7ed7a57ba01f", - "size": 1841717 - }, - "609": { - "releaseTime": "2013-03-26T12:14:08", - "sha1": "487e2e3d063d55b585d0358822b7b62bd3f457de", - "sha256": "190a33807674e2d0f4d9ba40ecdc11efb99fd42582283d0c5b5ed0598757c57f", - "size": 1841499 - }, - "61": { - "releaseTime": "2012-03-22T20:01:10", - "sha1": "d0ba974da976e9348c3b8497a606d888839034ac", - "sha256": "0074d9e139b79f4f1bddcef86fef87b79c28cfc1fd7caa421a76fd66d8ed6ca9", - "size": 503013 - }, - "610": { - "releaseTime": "2013-03-26T12:32:10", - "sha1": "f19d03346de350b600a1485e3736ea722feec731", - "sha256": "8474514cfc245e9c9c7429552cf09ba80b5ed4a8b4eb04d37c76f9a86fa25d98", - "size": 1841597 - }, - "611": { - "releaseTime": "2013-03-26T21:59:42", - "sha1": "2b5c9e928b14eba5985fdf99141e0b4f36f4919b", - "sha256": "a10a3303eb45fb206fc86dca357cc6414b5de313882f34f5a9d7446e85b5bcd4", - "size": 1841630 - }, - "614": { - "releaseTime": "2013-03-27T17:34:36", - "sha1": "ad15e8ff0469a674421d8b91447543ad5ddae4e5", - "sha256": "f6fdf613e51cee90807544e96acf2b0ee71160fd11e4fb6cce43506254ed4229", - "size": 1842016 - }, - "615": { - "releaseTime": "2013-03-28T06:16:30", - "sha1": "2f846dac453503c38e94a2ec4b1912c4107ad6ea", - "sha256": "46fe09a4b47cfea1314406db10ec52446187bf9d4ee82d891fe445f06057e95a", - "size": 1841842 - }, - "616": { - "releaseTime": "2013-03-28T06:32:18", - "sha1": "e924ed455c1352274bf758b61290c5cddfccf16f", - "sha256": "905002cc9488c0e553b24f602280e672911de6a7d3e8c5d102b9d64c1ebab3bf", - "size": 1841905 - }, - "617": { - "releaseTime": "2013-03-28T15:50:34", - "sha1": "9293a9a74adb8991c6057b3cdfc985276ead3a71", - "sha256": "21ae46fb70a81ca1140a4e499b8971c66d8dfba5d2b37fd47ff4e209fc67d927", - "size": 1841930 - }, - "618": { - "releaseTime": "2013-03-29T10:54:14", - "sha1": "eacfb8930e7426c7aad65db03f1c4d47f9a629b4", - "sha256": "bb60011ad40b9967458f7f94dd38b169487f273f3063b29e6387ec9a101ec913", - "size": 1841693 - }, - "62": { - "releaseTime": "2012-03-25T23:38:34", - "sha1": "4764871665c79041b233e06b62951b6500693007", - "sha256": "0ab4b860362867ca3eb3f18db522a74876f1cbe8d9e9fb50892f8003a21691ca", - "size": 503894 - }, - "620": { - "releaseTime": "2013-03-29T14:30:48", - "sha1": "fba2fc79ab6adbf37543ba7c832ff69dd9e4bca8", - "sha256": "d64106428e99e04b2a8200f8bb1f7a5dd415c5e16e1c244a976eb8ca53bb5a64", - "size": 1842046 - }, - "621": { - "releaseTime": "2013-03-29T19:53:46", - "sha1": "2fd638d07a63d3d266dd1f355a0037d8a121a75f", - "sha256": "89eab9898290cf4361784c3f81ed6be8445483935fee900e5a19f1266ec71095", - "size": 1842165 - }, - "622": { - "releaseTime": "2013-03-30T10:26:26", - "sha1": "aa86d940795a19314a97225bfcfa58ad5f466384", - "sha256": "1716af38d742c935515879897795b4ae6b91066ab2dcafe9db1de1847b3baa44", - "size": 1842514 - }, - "623": { - "releaseTime": "2013-03-31T07:59:12", - "sha1": "8958c9643b16640342f0b63396c6f2cf2072099b", - "sha256": "5c9e09c1c5524db1a5eddb09ff57ff7078cebce970ac266bbc83f5732a73ce43", - "size": 1841475 - }, - "624": { - "releaseTime": "2013-03-31T08:34:44", - "sha1": "20aedfa6e7d255f99adfadf9f345c3ab9aa5a521", - "sha256": "756c0869814858979a866381e09f53565461e7964a86d97ed26602ff4b2a225b", - "size": 1841511 - }, - "625": { - "releaseTime": "2013-04-03T01:01:26", - "sha1": "985c86a6b349d03952897f0b516b4970782ccd97", - "sha256": "feb6b97edd2501de5825624311c90a5a05b23b67a85331d00b04132f7362f5e1", - "size": 1845610 - }, - "627": { - "releaseTime": "2013-04-03T03:17:22", - "sha1": "887556c1ee0c9cec4447ed38a4abf09858266aaa", - "sha256": "a1cfb5ed61fffd2291407da332876db576c5008eb3319c75e35773c50bedbe4c", - "size": 1845607 - }, - "628": { - "releaseTime": "2013-04-03T03:37:02", - "sha1": "686799aaadad7814253190bdb0a1fc7560451178", - "sha256": "3eaac663cc980ac9a4563e239dcbc134f2047cb700230424a5c558e996d9acf9", - "size": 1845673 - }, - "629": { - "releaseTime": "2013-04-03T05:16:26", - "sha1": "d3aa64bfdacbda1048ccaa9f5238f1f541528ad4", - "sha256": "1e356867221fa36ae1e60e4be61eade98675eecb1f92c82b30fe41fd27de7ecc", - "size": 1845744 - }, - "63": { - "releaseTime": "2012-03-26T02:56:50", - "sha1": "4fe8f595c76a6ac45d2243e610222b05f5d5696e", - "sha256": "fc55e2ba6f78afe8ca60dc6d2388e8510ba8262160c6acf11b1ff7b64bea6042", - "size": 503843 - }, - "630": { - "releaseTime": "2013-04-04T17:17:08", - "sha1": "67a728e15c95d5bf0c79c4bd2eb5a6cfe9ede6c0", - "sha256": "c3acf9e87f951770d71e4d4f082424f2c10523e2987d7201adfddfd047bf19d5", - "size": 1846619 - }, - "631": { - "releaseTime": "2013-04-04T18:39:42", - "sha1": "6444644de15fb9780b66a51008124dcc78bf36bb", - "sha256": "737d1307d2585a5ce50384476fc36b8f74e81db48af542737764a16c5c3f1c4c", - "size": 1847007 - }, - "632": { - "releaseTime": "2013-04-04T19:04:58", - "sha1": "315204071999b6f5b71ddc7e146a00462e68f2af", - "sha256": "8961e9275dfde5b55f4503b0ca12fa50dd79295ad7f6eb7edf6deeccfef7c25b", - "size": 1852106 - }, - "633": { - "releaseTime": "2013-04-04T19:22:44", - "sha1": "d52c199a6699a8a5c5192e2024d5f0b08c987a5c", - "sha256": "329ee4d1b752025c123df1511f120a36c76e58d9604558d7420ff9c58f10c2b4", - "size": 1853907 - }, - "634": { - "releaseTime": "2013-04-04T19:45:34", - "sha1": "19d4a565a3a3fa307d1a7691a18f15b7053ec9c3", - "sha256": "ea4473393f4fd4b05d136f09bede7f163cfb3ed349b90385cd9aee308de75a53", - "size": 1862442 - }, - "635": { - "releaseTime": "2013-04-04T20:03:00", - "sha1": "51b985a55285d32017de00f585b9f36142de6fce", - "sha256": "0013a81965e4a557753088da180a9117ccd15a399ca9f289be4ebeeccfa49300", - "size": 1864201 - }, - "636": { - "releaseTime": "2013-04-04T20:19:58", - "sha1": "ce0ff3cc72c656a36d574fcaa13c5e948d0e96ed", - "sha256": "6d5858ee8a582757b9d9e90466b741c360aadb19e7c9db0d7e03cf471ae8906a", - "size": 1864670 - }, - "637": { - "releaseTime": "2013-04-05T00:44:22", - "sha1": "63e4e9126f9db7d938d5172d9cd892f9e8570b71", - "sha256": "0e88cdfdc1bfc123ec1f3c171721d16b7ddcfef16710762b2ff3e549caf4535f", - "size": 1864839 - }, - "638": { - "releaseTime": "2013-04-05T11:40:16", - "sha1": "6b837529e509ce80bf67a708be7d9160d58a3b77", - "sha256": "6fb257167c1752f8d35ce73f3212b0648ed105c86bd60ce1d2f460b80c7ba55b", - "size": 1864944 - }, - "639": { - "releaseTime": "2013-04-05T16:21:02", - "sha1": "d49ebade7765363fa5d227cbef125969f0848407", - "sha256": "d6d5c05f335e67031e78637be76ada17eabca3f7de020f512104ce0301bd9ef9", - "size": 1864957 - }, - "64": { - "releaseTime": "2012-03-26T04:37:02", - "sha1": "e590a6e7f9cd6d0b683010abca34c69080893c28", - "sha256": "fff2343e68c5815b9aa664770d493543a4f016af5a0160556c9fb5a6b098e429", - "size": 503843 - }, - "640": { - "releaseTime": "2013-04-07T22:55:46", - "sha1": "e7c2fe9a95126c6c1a048df07f6a055aefad290d", - "sha256": "9b92c7b583c86186fe0e60515412389f5885c1f1962b3d8691f177051681f6e7", - "size": 1867592 - }, - "642": { - "releaseTime": "2013-04-09T19:28:00", - "sha1": "d5ba1d70d59d8a8b7840ce4dab9ae70c5a63de31", - "sha256": "496a0cb967490a83f15d439896809dd498da25a210b5ab34de9ada2fdde0adff", - "size": 1871955 - }, - "643": { - "releaseTime": "2013-04-09T22:12:00", - "sha1": "eb9b08f9fb309260302a7b3be845dd9e8168ebff", - "sha256": "e1d1e43d8592d4cd237a0b2528111a7f48f616554454ce8049a0d46e8b1121d2", - "size": 1874769 - }, - "644": { - "releaseTime": "2013-04-10T07:06:26", - "sha1": "efd54911c2ca6f4c300451f94b2840e93f5316b1", - "sha256": "d02b73facccf65d96b33c13e1d98965491e19117bc445b1f29279f844e713b0b", - "size": 1874656 - }, - "645": { - "releaseTime": "2013-04-10T12:14:10", - "sha1": "db855176a6c2d4e869a875cb51dcf0c244726fa9", - "sha256": "fc18fef4c1ee6f7eacde0f4ff6ce582123aeec6092407e9b4a5d23b47470f33e", - "size": 1874885 - }, - "646": { - "releaseTime": "2013-04-10T16:46:34", - "sha1": "0a4310d327dba9c1d1939a8da17a46015cfce441", - "sha256": "c70b0203184883682daafc854c0575fcc9291fe348858aa481d32c062692be8d", - "size": 1889074 - }, - "647": { - "releaseTime": "2013-04-10T17:01:26", - "sha1": "563345cc96844f8005374f64dae2dc78d989e43a", - "sha256": "0e4f5c0fc1c681eed6c84fc715d0e1aaa9ddaa46726837ddc3046a4c8c70810f", - "size": 1889074 - }, - "648": { - "releaseTime": "2013-04-10T17:42:02", - "sha1": "dd37e5b9ad13c7b07983f872818f86f42896c437", - "sha256": "b83d160c0d210f99fd32a510dbd39af972ad65d4813a7efb0f6b6fe32f1c26b6", - "size": 1889326 - }, - "649": { - "releaseTime": "2013-04-10T18:05:30", - "sha1": "fc44d88885a297f2fcaae01262beb460d9044840", - "sha256": "1141912de80faedc8ded1128cb6c73428dbf4223b525f050e26b94def2551ce2", - "size": 1893066 - }, - "65": { - "releaseTime": "2012-03-27T00:44:54", - "sha1": "fdf2e7bdc7ca3cd179b82c4b690e208f9a62bcaa", - "sha256": "d70dabe8ee2f6440b0f612fe61be8e6e990dd97eed60c7dbb98b7820eab16a7a", - "size": 503852 - }, - "650": { - "releaseTime": "2013-04-10T18:33:56", - "sha1": "f862748c96233f922bf2983198251c0d4466cfa1", - "sha256": "78b95b183f8387f6f031f81ebe2556765931302c4b74a0e4d1098e2c1f198e08", - "size": 1893143 - }, - "651": { - "releaseTime": "2013-04-11T12:49:12", - "sha1": "076eeff722342a367058fe5ab60ce355335fe676", - "sha256": "4a30217b29fc967fed7065c5c00bf045e9512eccc68324db44e0b480d12bbf93", - "size": 1900288 - }, - "652": { - "releaseTime": "2013-04-12T15:23:20", - "sha1": "680fc079a7ed7a92cc30db07a50d7318febdfbcf", - "sha256": "7cd5153a145b8d5affda63beeba6dfda738ccda225277c21e0550caac073acd7", - "size": 1898972 - }, - "653": { - "releaseTime": "2013-04-14T22:50:24", - "sha1": "02297c606a18a47ef0159b743f107ce8c4c796b1", - "sha256": "d3cb69d82969dbc8a62858d2fbf54d30d7d088a7d8fea79b194f6e5b0465f584", - "size": 1901921 - }, - "654": { - "releaseTime": "2013-04-15T11:24:44", - "sha1": "79952eda8d6f6350f8d9dbfb775b9f3c9f7a6b45", - "sha256": "1cc0106a37883f7eeefc73e81c4078056f603d99a6c66c6c9f1fdad5d7ca1410", - "size": 1901953 - }, - "655": { - "releaseTime": "2013-04-15T17:11:20", - "sha1": "f070ee134a478cf2c04457e38523ecfce8b6c46f", - "sha256": "b2af5209824736919c5fe6dc2a77a19ebd3c1c80c127db6ea08058219fceacc9", - "size": 1902601 - }, - "656": { - "releaseTime": "2013-04-16T12:03:34", - "sha1": "a893fec9952765389312a7af9a71180774258051", - "sha256": "e3ea6746adca859367fa05aad6257a81e6b10052a34a116fa92bfd99eefab6d3", - "size": 1903303 - }, - "657": { - "releaseTime": "2013-04-17T15:09:52", - "sha1": "70dce35b96dc4d8de33cce93219caa0b3eae98ab", - "sha256": "87fd6f594e94d8ca6a806911f1da5897a9feaede5daf63f899868254adcdd084", - "size": 1903009 - }, - "659": { - "releaseTime": "2013-04-17T20:27:52", - "sha1": "0318a86dafe9b34f17d469f4db59254370e53d16", - "sha256": "8b55ceba1e73e9e10c45da5368554c1996102907de265a58110c258eff8dc853", - "size": 1903124 - }, - "66": { - "releaseTime": "2012-03-27T01:04:54", - "sha1": "ff7197ad0ee80015b31109a7b042d57627ec1248", - "sha256": "0b0fd015dbe8d2ca139ca4b95800cd8e61499ed55bce18b94333811b6109042f", - "size": 503851 - }, - "660": { - "releaseTime": "2013-04-18T15:28:58", - "sha1": "ff188d20471985d2f2e5fd73859271ad0ed6d519", - "sha256": "a17d872ef84e533b369a4b8d4b83d5564d397c29054c16c021af80357e1f0eea", - "size": 1903328 - }, - "661": { - "releaseTime": "2013-04-19T11:59:40", - "sha1": "29d1a1aec78fe793d96e41cec7d3d7caecfa7787", - "sha256": "73a6e3aa3a9346491299761ab0558cbcedf056256ff97ac1b8680ecd3aada47a", - "size": 1903438 - }, - "662": { - "releaseTime": "2013-04-19T23:14:02", - "sha1": "f77e0c8e14c80c07b42161218b59be8fde0bb341", - "sha256": "ceaaae977aac1edb3c518f77efbccecf459ab93b3c77ff2ba002302044f8113b", - "size": 1903425 - }, - "663": { - "releaseTime": "2013-04-20T12:31:26", - "sha1": "61399f70ca08255d09b3ff09b30083d2e9de471c", - "sha256": "3ae90dce0661a86b10a85c80ab487272f97dffc2c65fbf84ae5c1fa0cc91524d", - "size": 1905710 - }, - "664": { - "releaseTime": "2013-04-21T01:20:58", - "sha1": "5c9759fb7183a96d86faf8a5b715afebe2254306", - "sha256": "23ff1c9d97b9fff49223a08207137a9d70081d94b52f8827932029dc06963b5c", - "size": 1905898 - }, - "665": { - "releaseTime": "2013-04-21T11:47:24", - "sha1": "d55b620f5550af53bb7f6a8b9289c87240ce2519", - "sha256": "e4b9bf245caf46efd9643bac2e035c2b422bf445ba599b451d3f4bc24a49deb8", - "size": 1921258 - }, - "666": { - "releaseTime": "2013-04-21T15:01:28", - "sha1": "b09a58b89476fd18e461dec1bedb9a60889ee192", - "sha256": "db41ae60dce1e47363d3b046b68d7ab15b5fe1b42c84c153246b3a23e83d19ec", - "size": 1922439 - }, - "667": { - "releaseTime": "2013-04-22T19:21:50", - "sha1": "7556b581a57f140413b3467dcc6d9139b3f15bdc", - "sha256": "d491dd5c2026bdbcd7b545ebb830db0d1a23caeac03351b2ce299be5f34935a4", - "size": 1922690 - }, - "67": { - "releaseTime": "2012-03-27T07:32:36", - "sha1": "9558cb918a1766d2e11ebba352eff9fcc5a23437", - "sha256": "a979d8479974c422973970d1c27c1b57fe9b3721a1b082f42e327c69c36486d9", - "size": 503826 - }, - "672": { - "releaseTime": "2013-04-23T20:56:40", - "sha1": "1738bc1cf39d465cf78d24b8f31784cb3568ea13", - "sha256": "259a465b177aad0724da4815619f046635881367ca93b525ed305001a4134bd0", - "size": 1923182 - }, - "673": { - "releaseTime": "2013-04-23T21:42:26", - "sha1": "d3f2eb1683bf8ab158aabcff2f2eb3daa0deb31d", - "sha256": "4131973e4eb330e64a135ca7687efe66eb6d49ddc958b3b90ddbb7af511fa61e", - "size": 1923226 - }, - "674": { - "releaseTime": "2013-04-24T11:58:00", - "sha1": "a8aba7c84b23427100b9d60d7337165430abd034", - "sha256": "af174f6c991ea67c3d85bb122f13ae5e7764abfe745783af0ae719356d5ff9aa", - "size": 1973350 - }, - "675": { - "releaseTime": "2013-04-25T19:51:18", - "sha1": "fd98cd49077ce57749235316d7a428545ba4d2b4", - "sha256": "7e112989d08179b444f7aba1f6b1441654121d92c2e9eaf661dcef3f04203edc", - "size": 1973642 - }, - "676": { - "releaseTime": "2013-04-26T14:15:34", - "sha1": "4a80718c75542fed023bb178c11695373539d329", - "sha256": "cada7dad8f5966da437187416413ac8e72cbf2824bbb99314b3bf9e1df5bfe4f", - "size": 1973741 - }, - "678": { - "releaseTime": "2013-04-28T15:27:56", - "sha1": "01bc4839acb7b32a5214906d5f7c1612da1fd5f4", - "sha256": "df6647bd1e408ebc55a9779c1d5b660a24855c2189ca0d04bc0bf4cbd62b37b7", - "size": 1973777 - }, - "679": { - "releaseTime": "2013-04-28T16:41:22", - "sha1": "94fbbdbe7dea9ec402fb821cf1a1472507b67a18", - "sha256": "6b54ce0df3f2f97d02233c0ce13e6dbd40b9c2402888fc1e107488ba9bf88042", - "size": 1973698 - }, - "68": { - "releaseTime": "2012-04-02T02:32:02", - "sha1": "472933267af1bd5693f2aa4e89aaad48cfe2d629", - "sha256": "9c9c26dabe099bca7ec29eed9ce8b90f4d55b91b39693170b171084a7b53ed8d", - "size": 504946 - }, - "682": { - "releaseTime": "2013-04-30T21:26:14", - "sha1": "2832ae601b5aac519f82ef4f784d6029b4e6b806", - "sha256": "201cc3b2af2175ef7ee6bc347bbfdcc9cff6e2cfa27ab30eef53aaf62de8e339", - "size": 1973847 - }, - "684": { - "releaseTime": "2013-05-02T10:24:50", - "sha1": "90c15460f12138f90d0ebe23cc32aaf589b3cf1f", - "sha256": "3383e9062ad778d867405eb04eaf7a3ac9b0bcccd3b7b47ce96cdc535725f415", - "size": 1975130 - }, - "685": { - "releaseTime": "2013-05-03T15:46:32", - "sha1": "50b4d98c368340f96e1d85c6a1c98f8158b39f66", - "sha256": "0ceab9100977dc466efe00ce5e65db2261530a7f2fae9a4376abd674478cd45a", - "size": 1975158 - }, - "686": { - "releaseTime": "2013-05-04T18:49:10", - "sha1": "8a176209473781a6870b9c600c33891807a51d23", - "sha256": "9f28c0dd3737df5911d53442b821768ac373e0db618211e60baf31823ff92df3", - "size": 1981647 - }, - "687": { - "releaseTime": "2013-05-06T20:16:46", - "sha1": "015aef26f6a8eb2ae95485c65e8cfa814715e647", - "sha256": "acc3869918a12f3d97506f9eaab9d9029a2d573cf736ffc67b9e9de2825ba8d2", - "size": 1981935 - }, - "688": { - "releaseTime": "2013-05-06T20:32:26", - "sha1": "3226d1cce1245b1c1e78da9fcbccf9918a8325fd", - "sha256": "8c2ac223476f8e37fa58fb93e0966704aee0a3a9bfafff7207a27fa1fbb0dd0d", - "size": 1982018 - }, - "689": { - "releaseTime": "2013-05-08T17:40:56", - "sha1": "710184c7c19b2be41ae111a930ad878089e1f851", - "sha256": "94bbce5bc8cfbd311cd031391e618dd6aa940bd83735f4a574c890360f706eb8", - "size": 1996416 - }, - "69": { - "releaseTime": "2012-04-07T04:32:06", - "sha1": "75f13154c3196f749bd0db90d9cfeb08273882c0", - "sha256": "5346560a1c8feb740834a06d3e621bbb952aeef734a661a4f937b694770e02be", - "size": 503459 - }, - "690": { - "releaseTime": "2013-05-08T18:19:54", - "sha1": "d4d81fa3ee06a0376f1ea988d4d5ce01bdb87d38", - "sha256": "8aa17bfad0efd2b681c24cb2c361e5b42b645121ea856b650f3d66e9765f4783", - "size": 1996762 - }, - "691": { - "releaseTime": "2013-05-09T02:10:34", - "sha1": "d26816531b8a602b1017fc12c5751b3f0c898f91", - "sha256": "164b63443db99450ffb21e210e2c4cff5b6ac1811274ca22b099048a53b13316", - "size": 1996885 - }, - "692": { - "releaseTime": "2013-05-11T02:12:34", - "sha1": "a6db5508997a1c7da4967be62566a8a9ecbd76a8", - "sha256": "04baab4a61ac567b19a16ccabc2d24621246ec5a8ead0de6964311640bcecbfa", - "size": 1996907 - }, - "693": { - "releaseTime": "2013-05-11T11:05:56", - "sha1": "929858c287ebf13a0dbdbae880cee535031593a8", - "sha256": "bbf24f529798daaf1853bf30b5f716b9d223be7aaa9e75a21d681fb704971593", - "size": 1996968 - }, - "694": { - "releaseTime": "2013-05-11T11:21:40", - "sha1": "d0aaf895840de87de21ac2e39b402b2462108365", - "sha256": "8cc42ebd28541937c1ab671f88d536f2904fc0dba8706761703266076009d897", - "size": 1997048 - }, - "695": { - "releaseTime": "2013-05-11T12:05:32", - "sha1": "df03ea2882aba13d16a806a25c487b0b63d80e12", - "sha256": "2fd71dbf432d2602f884e457f981285725fab90d6461d15b663afdc776b30ef6", - "size": 1998522 - }, - "696": { - "releaseTime": "2013-05-11T13:23:26", - "sha1": "63ca0f99d1cbfa1aef0cb3464d72f1bdb675fe8f", - "sha256": "8675a75da788e107451398ebabba25b8e6b8ed74ab5b75f47c4447019ff4d180", - "size": 1998669 - }, - "697": { - "releaseTime": "2013-05-13T21:40:24", - "sha1": "a67ec8dab25c86822284b73b9be0d895548191bb", - "sha256": "be9e0180ccb4481193d2a99e1327c21c6e3b0248a30c90003f7383a4d6cd20e1", - "size": 2001775 - }, - "698": { - "releaseTime": "2013-05-13T22:11:38", - "sha1": "23476d809fea3460ef2cd61e6198806ec826c2d8", - "sha256": "7232431f16d42899b6a2a56dbe049e23d30489fb66f98406da1893ce0d7b4cc9", - "size": 2001837 - }, - "699": { - "releaseTime": "2013-05-13T22:27:50", - "sha1": "b1c584f190dd2a3802fac3323ac2f939ccf1539e", - "sha256": "ee6e58c5d956d61ebcdaf76ae5693bc2ccb56fa11da67db7c149392aa589058f", - "size": 2001888 - }, - "7": { - "releaseTime": "2012-02-10T07:13:14", - "sha1": "9f74f177ac12b2b99d5418133a48d829c7065163", - "sha256": "5bf54ac1cccba02d30c2f1bf39b06c18f1e7fbdccfb80a60bae2dcbed2e6d111", - "size": 421307 - }, - "70": { - "releaseTime": "2012-04-07T08:10:50", - "sha1": "76b6d4414355a4451f568223f8ed8a0707ab5c0c", - "sha256": "15e2fc339c8bd32383cefa4b3964af35decfc94872f65b039327a0c491753ea0", - "size": 503473 - }, - "700": { - "releaseTime": "2013-05-13T22:44:34", - "sha1": "ce3831b7f357872c476221e28facfa430e9f84f9", - "sha256": "d3c2e269d14b40bfc330f0d532d5c117201b409bae9dfb344ab5373cd2b9001d", - "size": 2002002 - }, - "701": { - "releaseTime": "2013-05-15T18:36:52", - "sha1": "5f7141eefcb4ed3fcb87e638cd7d2eefa0457e2a", - "sha256": "5ac8b8c591cce7ad7623aa62bf569ced84dca30574bc268f8e2de6f80e3ca54e", - "size": 2004225 - }, - "702": { - "releaseTime": "2013-05-15T18:58:42", - "sha1": "8c1422010f057f81d3ea0fbc73bc8e04e04ecb45", - "sha256": "ce2852ad64cf8f6315aff0a294091b586a313da6fa5dcefe956766247c56cd51", - "size": 2004573 - }, - "703": { - "releaseTime": "2013-05-16T08:19:28", - "sha1": "39bb7c0c79e942046675d85e3b60ece4dc7b4a58", - "sha256": "4581ed106a8f9819fde5b7c76a575ab3428b3970bb767c2acd73a906bb90bcfd", - "size": 2004639 - }, - "704": { - "releaseTime": "2013-05-19T14:37:58", - "sha1": "c3948bab0718823ff488bbd7c15e5f3fd79fdfa2", - "sha256": "5be44a78b162876127971f551f6306460a20b9e87fc5b87a7872d590c35f3aa4", - "size": 2004691 - }, - "705": { - "releaseTime": "2013-05-19T14:55:40", - "sha1": "fb0fb76a907588402ac8416d3d37725da8ac7e8d", - "sha256": "249c828331f213d92e4d4484eaf4d0fb6dda8db572551a6b7c3727907124c715", - "size": 2004808 - }, - "706": { - "releaseTime": "2013-05-20T19:58:56", - "sha1": "3c12441da278d3cd993afd3822585797a5d788cc", - "sha256": "74a22bca0f957f7328b158d14e991adc7f26a2bd7cc95c8f23e2dc4a0fb2cf82", - "size": 2008262 - }, - "707": { - "releaseTime": "2013-05-20T20:31:34", - "sha1": "b079436f13cc59cdce6f54e0409d99c0222130f3", - "sha256": "f4b435c84e3a8a44802dc8ba476027c5d7b379852713677b403a38dcc411b115", - "size": 2008384 - }, - "708": { - "releaseTime": "2013-05-21T09:10:24", - "sha1": "ed6c6e9bb5b8b3ab7d6281717ef67359d687c326", - "sha256": "fbdc9297bb1ba5760928d1ef77f610d295a49ba15f1d937e4db87ea76a03e552", - "size": 2008476 - }, - "71": { - "releaseTime": "2012-04-07T21:15:22", - "sha1": "43034ab1176c672ff81b658d8071cd7955a50fcd", - "sha256": "4c7d2eaf146ad1d492434b03a4b7f46c7e91469edda17e3f1cfac270bd4a95e7", - "size": 503475 - }, - "710": { - "releaseTime": "2013-05-21T21:20:08", - "sha1": "0b8d1daccad003be2e930b9391fa87aec2c9d8bf", - "sha256": "d0eef0327f00aadf59c7215d834f9ea7230bbce84e303cea0cbb9ec32eed3440", - "size": 2012979 - }, - "711": { - "releaseTime": "2013-05-23T23:14:24", - "sha1": "c78c3775b880b2b45e8b6b14769da6d2b4748037", - "sha256": "c247dd77fbff8c16a8834fce812f618d34ed4663ead3c7f3f3b1f4a88b446be1", - "size": 2014309 - }, - "712": { - "releaseTime": "2013-05-23T23:31:14", - "sha1": "228c0999c5a224d8290e29823c4dd31b5679866b", - "sha256": "b52b2f0cf5b2dedc06185c500c215ab9e7426f7342d8a4f2fe4f2dd0d7f6fadd", - "size": 2014600 - }, - "713": { - "releaseTime": "2013-05-27T09:17:32", - "sha1": "51f931ead831c564033b17cc835e3c2edab1e24b", - "sha256": "cd79d0b0c55ce044664177c201fc8036a0f18431b67b7e97570ac1b991f0bff6", - "size": 2017084 - }, - "715": { - "releaseTime": "2013-05-27T17:19:28", - "sha1": "00700cefeb2effc71737f65a6cbb204effd5f300", - "sha256": "b3fad160a0d59a27a73b8ebedc40fce8c9885d7ef20fb291e820a4642eb97982", - "size": 2017367 - }, - "716": { - "releaseTime": "2013-05-28T21:44:14", - "sha1": "6118150c8c0e15a6926c62e8525f9014d14dc34e", - "sha256": "71987c72116cd81bd0e7e55ca01755946d4a0a42cc93e264b977daf6abe91f78", - "size": 2021922 - }, - "719": { - "releaseTime": "2013-06-02T17:33:16", - "sha1": "6b90d931a20413bb13c31e08e543f39dd7155d59", - "sha256": "e8dea27918aa6b5573571c8f3f008a576aa11b777d7aa292bf20b7dba0c4d4b6", - "size": 1969868 - }, - "72": { - "releaseTime": "2012-04-08T04:34:02", - "sha1": "8d3179e614985a5d8604b5e28008d36edd8795c9", - "sha256": "81c65151bdae9e7effde9df1bb281b6eda6a409340a45c5f721186f5dccc9d25", - "size": 503474 - }, - "720": { - "releaseTime": "2013-06-02T22:35:34", - "sha1": "56f9d5a36821e3deb3e8d8e5c7c12d26b007f744", - "sha256": "cc4df5646f71a005f0696d4de9ebeb558bd553cd746524e06262f40ab423dbb8", - "size": 1970132 - }, - "721": { - "releaseTime": "2013-06-02T22:56:08", - "sha1": "02323336f7d1e8e68a3feab3123ad1aaf935e756", - "sha256": "d0f1422ceaf76e44b7dfb11fa651689f43a3367863b799610a947191ec540690", - "size": 1970162 - }, - "722": { - "releaseTime": "2013-06-03T13:30:32", - "sha1": "573149c42a161efbe95627850629c801c9107e83", - "sha256": "8b8e6a0dfcf085e4687548b68fa600d8126b84066033f3ddf266c1761fbf71df", - "size": 1970177 - }, - "723": { - "releaseTime": "2013-06-04T18:24:30", - "sha1": "9d0686ede1e00c46b6540cdf9d9354d701fc1fe9", - "sha256": "399da9a77a7a90792b761a007f4fdd8ddfbb15729b0a701edfb46ec02d23fe35", - "size": 1970645 - }, - "725": { - "releaseTime": "2013-06-06T10:24:40", - "sha1": "23126c578162a9675aa80160c5f45ed602b6a546", - "sha256": "cbdd44edc72118d851521d3f65c8c3d93c7eafa88b0c22420cd726962641f803", - "size": 1970914 - }, - "726": { - "releaseTime": "2013-06-08T13:28:12", - "sha1": "68a5d447ad321f5f993a5bedd820fe4349fc4fe4", - "sha256": "9b12289096fb79acefb402d21306f0211e6d8a1ad23d4286c7491b1d11c909b3", - "size": 1970976 - }, - "727": { - "releaseTime": "2013-06-08T15:09:38", - "sha1": "50e7d54fd520da847acf2841915fbfc3aba180bc", - "sha256": "62b5ef66f76390cf5f8267a899de64bc6ab201059af5bf36d7926fb18ee35af3", - "size": 1971222 - }, - "728": { - "releaseTime": "2013-06-08T19:45:40", - "sha1": "dccd0e8722a5dd394fe8c8b3d03f631bd92aea00", - "sha256": "8c95ff2b90b1d20cfc1dbdb36b562c6de95a9bc0b73b17132a4aba39002ba3a1", - "size": 1971257 - }, - "729": { - "releaseTime": "2013-06-08T20:43:38", - "sha1": "94f3f2912a8b02cf96102c6e6d113a7892a745eb", - "sha256": "837f3081f2b570b4fd46f6c9454a3cdb3fe6221e98a1c10528b5849ed9a1ee78", - "size": 1971301 - }, - "73": { - "releaseTime": "2012-04-09T23:01:20", - "sha1": "73c54a203bda1ac2e2b99e5209a122938db118bd", - "sha256": "aaae6d2eb7d882f0bf4496687a7fd4ba9a286006b73ec2b7f896d616f5755848", - "size": 505435 - }, - "730": { - "releaseTime": "2013-06-10T02:45:26", - "sha1": "f75107ac5491862f90d446d955d064350b9ec2e3", - "sha256": "00b98fda45ca4dc97de7ec581cf3abb73b59b5f1230e30aab86f5783a4df9127", - "size": 1971321 - }, - "731": { - "releaseTime": "2013-06-10T03:14:12", - "sha1": "58c8ca5c9f80db437c5d1b6a7617616a869ff86a", - "sha256": "704ebecb955f25eb6bcce50c5fb5e8992b394f27bee610b923cb541914827604", - "size": 1971325 - }, - "732": { - "releaseTime": "2013-06-10T03:35:28", - "sha1": "4794e92c949150dcd742232dc54b340361121e65", - "sha256": "7edbd0b24a16c9fc82c3c213f7deecb18f74560218bf3231638a3d13849f1dd1", - "size": 2027315 - }, - "733": { - "releaseTime": "2013-06-10T15:06:34", - "sha1": "b15e7357fc4cd580df113b31b01d2ab096322eb2", - "sha256": "01a36247c9eca10edc6dbc833e88571063ced5ce8a327e1e3fc3a3ffe0bbc2b1", - "size": 2030486 - }, - "734": { - "releaseTime": "2013-06-11T13:06:00", - "sha1": "6c928588eb71df046994d90f1d080fdf0ddc7aa9", - "sha256": "1cd22d0160ea0e0ba73570b89d506e6bc51234e6fd819b425e527492df4d443c", - "size": 2030872 - }, - "735": { - "releaseTime": "2013-06-14T12:39:28", - "sha1": "82a1dabe45e2261606da04994cf4a68d9ba06f94", - "sha256": "7bebf6b5d546062f47b7427fcced5b3fb55618de6697ba2803fb082433816953", - "size": 2031022 - }, - "736": { - "releaseTime": "2013-06-14T13:17:30", - "sha1": "bc07940c37813839c8137ff07ef616515d75e3c6", - "sha256": "db5a8de955581d386254240cdf71191e59be2b1a17d66ecaad61f404ba792ef7", - "size": 2032700 - }, - "737": { - "releaseTime": "2013-06-15T01:26:46", - "sha1": "7b36d45f87a89071c6252f4cd50e632e7d285ecd", - "sha256": "988072f14ba1f70392e7d2305f6193f7c96399ed004896f5f489c3e04b5c6260", - "size": 2032810 - }, - "738": { - "releaseTime": "2013-06-17T09:35:38", - "sha1": "76223709288287a6a8d22ab16b43a6ab2a284a0d", - "sha256": "5758f6b77d3192cf5fe6d718a522c66fb2a4ddbc375d4b66f4b0019190d07f98", - "size": 2033732 - }, - "74": { - "releaseTime": "2012-04-10T00:47:32", - "sha1": "26e3a344b4aa38f8201109a7d965ac914c3d166c", - "sha256": "5566dea1974860dbf2d74e24ff93eeffef32c9a110e69840e40ef2a4bc339387", - "size": 509139 - }, - "75": { - "releaseTime": "2012-04-10T01:06:54", - "sha1": "8cbf482dcb0722632fd89543f623cf148c53e641", - "sha256": "c3de9491468598a5e69ace5eec1dd99489a88ee188f7cefcd0fa5f053665f466", - "size": 509659 - }, - "77": { - "releaseTime": "2012-04-12T00:51:04", - "sha1": "677b006d34ea06e3cf5aa636717142ebb2e0f8bd", - "sha256": "5a055de2522561542a0ab8aea8cf7d153787222ff81d6cd642a67cc356de8f3f", - "size": 509761 - }, - "78": { - "releaseTime": "2012-04-12T21:50:42", - "sha1": "e78981327efff67efad73471fd22218c9f98d29c", - "sha256": "a5a6efec545b7f068ac989f0ecc73de0b769f319d5b3796b09d6c8666c0a67b8", - "size": 509780 - }, - "79": { - "releaseTime": "2012-04-12T23:40:58", - "sha1": "4261e979e992ad6bfb5d76bbf6aae773774895c5", - "sha256": "603b5cd9226564b5b9217e2f45ae43fbb8636b43a62af249679ddcf42d05f196", - "size": 509886 - }, - "8": { - "releaseTime": "2012-02-13T04:20:56", - "sha1": "82de2ba21c06a352b571ea1374e428e63a91239b", - "sha256": "eacdb5ff32dc902f38e1c5fbde3e29a2a401722378f47f2a76396f13462a572c", - "size": 435800 - }, - "80": { - "releaseTime": "2012-04-13T09:56:58", - "sha1": "24e00e4620341bcceb50cd68f4f24aec2c2f8435", - "sha256": "f0bf7269da20eaff1f7c4a6d967685c65c8a70fe3cd4afc9900f2784355e3efa", - "size": 509886 - }, - "81": { - "releaseTime": "2012-04-13T10:35:16", - "sha1": "185629be371faedee1259e749921fe134c24c82c", - "sha256": "f2b22173dd2d683a05cc212db097388756adba1256eef6410901fe68e01eadd0", - "size": 509833 - }, - "82": { - "releaseTime": "2012-04-14T13:10:58", - "sha1": "f83a1d16d6b0a6f126e6da1084b53d45718e0f7a", - "sha256": "5aa92446463dd6873a71d0477e3933eae094f900e0b26b483d4304d838f351ae", - "size": 509874 - }, - "83": { - "releaseTime": "2012-04-15T07:40:04", - "sha1": "3b16bd8a6cb0c576e0c9d2c32bb063beda71fc1e", - "sha256": "3787eb348373d6cf60cd63dcd8182998e68d3c5fc71f36600546643d60c8e803", - "size": 510336 - }, - "84": { - "releaseTime": "2012-04-15T08:38:52", - "sha1": "c1320821760b73bdb195dd47cddc57f11bde9bc2", - "sha256": "e493a1d690b0b84e8088ab6047391221efec056e98d360d4a03dd9ef2ff11429", - "size": 510337 - }, - "85": { - "releaseTime": "2012-04-16T15:21:44", - "sha1": "24ad84c2b8a29a4cac503bfb40337c2246baec08", - "sha256": "5a006be9b3d6f6ad96697229a2ca413d7675c3bc9da904dc98a26edc46063bce", - "size": 510341 - }, - "86": { - "releaseTime": "2012-04-17T08:50:44", - "sha1": "9226f1ea2b7528b14b46a1550df63a941d02d4a7", - "sha256": "78202fecf9aa24e66c8c24fb5edd3fe85806135db85596ac9e36dee7454c0de4", - "size": 510362 - }, - "87": { - "releaseTime": "2012-04-17T10:30:58", - "sha1": "0822f3f25056be30419e187cdc3e4545bc837c06", - "sha256": "4b5b66c3c26a706a6c2b61b919e5f1bc418a3cca19fb6630d1bc1ed4f90729db", - "size": 510360 - }, - "88": { - "releaseTime": "2012-04-17T11:49:12", - "sha1": "cbf82171afecf4be0f0277ff0bef6646466e8900", - "sha256": "5c501a2f00233812bd746b737e4f3936044555f421f1b82a623a54ee711f3f5e", - "size": 517391 - }, - "89": { - "releaseTime": "2012-04-18T19:46:12", - "sha1": "ba77728f246cc494e84e1754f0f3ce03acb51a9c", - "sha256": "934dc21dfcdd5362554a83239669654a2e964d8621cc8165133099ff6691751e", - "size": 520417 - }, - "9": { - "releaseTime": "2012-02-14T10:43:10", - "sha1": "da9c0bad1054c5c8da8a22bf9394e14f3f70f8f2", - "sha256": "41c3ed9c7caf5d08e9d47dab1a36ce07d3c7ab1219da79fed0f486be61b38ee2", - "size": 446478 - }, - "90": { - "releaseTime": "2012-04-18T21:22:14", - "sha1": "d57947d579fe7441b65c6c1e0df7d3f8c62bed0a", - "sha256": "1ce05a2727edca09e7abca9ffe067feba6ece29de1bdd8473f7a5de4ecb4f9be", - "size": 522552 - }, - "91": { - "releaseTime": "2012-04-19T10:29:24", - "sha1": "513bf2fd928db15bde37aa31783bf243cc1e66b5", - "sha256": "c0843a2ecae1614bb18893633a47539c5ebabdd6c6e421d3de91723f850196bf", - "size": 522849 - }, - "92": { - "releaseTime": "2012-04-19T15:46:52", - "sha1": "3726362c75145a17bfd4d86bbdbc5d2770fc548d", - "sha256": "78065abadccafc87468f50013f7db8f021b00dae0a1640b222f7f3ec68a81b33", - "size": 523485 - }, - "93": { - "releaseTime": "2012-04-19T22:15:26", - "sha1": "246407ad677b342757ed635e0ff27574eed187ae", - "sha256": "2fcfadc16a4c171730e205fee1e7cd169037ac2ddcdc618f37775d1cda75d8ea", - "size": 525255 - }, - "94": { - "releaseTime": "2012-04-20T12:13:26", - "sha1": "17d961b3b62d2a050b3dfcc3598c7ea3fa200680", - "sha256": "4963274a498620988b13a142c02f6092a2b55681a0aa58309bbe0e034657bf44", - "size": 525307 - }, - "95": { - "releaseTime": "2012-04-22T19:56:48", - "sha1": "ce95bd720b3b40360dc0e8c3d1c139b22ff41819", - "sha256": "db66f23cda2d3b2a7490bde96c6105fe5ec184a89d95bab9d7a9451d1c861017", - "size": 534102 - }, - "96": { - "releaseTime": "2012-04-23T10:22:12", - "sha1": "7eb8bbd96e3dffba57cbf54b7945f1a971582496", - "sha256": "7bda8102696ca29c23edfa0889bafe062a66c31a9141e7ac5bc1a60f98545b1f", - "size": 534131 - }, - "97": { - "releaseTime": "2012-04-23T19:21:40", - "sha1": "41b4f307950fdcf862d4cdbda55384cd0af92eed", - "sha256": "fda396ff176e4cf52a9ab308ed0f1cc9883ee1223b8128546e4b49f5a8129e3d", - "size": 534216 - }, - "98": { - "releaseTime": "2012-04-25T01:41:00", - "sha1": "70c6e3b3bf059dffed3d75d1b6b83d2ddd8f4513", - "sha256": "ea6717dd33d9345ed71753278e3bc393adefb69219217f2c456657476a78a6e9", - "size": 535244 - }, - "99": { - "releaseTime": "2012-04-25T01:48:48", - "sha1": "bbeabcea70aa1bd7a24141fd34af67cf259a9270", - "sha256": "62756c8436b22a43ad56096da5e5a406daa416ba106a75ac61f165151cf55b23", - "size": 535241 - } - } -} \ No newline at end of file diff --git a/static/mojang/library-patches.json b/static/mojang/library-patches.json deleted file mode 100644 index 74d4d26c4b..0000000000 --- a/static/mojang/library-patches.json +++ /dev/null @@ -1,2879 +0,0 @@ -[ - { - "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.2/3.3.3", - "match": [ - "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-natives-macos-arm64:3.3.2", - "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-natives-macos-arm64:3.3.3" - ], - "override": { - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - }, - { - "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.2/3.3.3", - "match": [ - "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-natives-windows-arm64:3.3.2", - "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-natives-windows-arm64:3.3.3" - ], - "override": { - "rules": [ - { - "action": "allow", - "os": { - "name": "windows-arm64" - } - } - ] - } - }, - { - "_comment": "Add missing tinyfd to the broken LWJGL 3.2.2 variant", - "match": [ - "org.lwjgl:lwjgl:3.2.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", - "size": 7092, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2" - }, - { - "downloads": { - "artifact": { - "sha1": "fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9", - "size": 7092, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "39e35b161c130635d9c8918ce04e887a30c5b687", - "size": 38804, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar" - }, - "natives-macos": { - "sha1": "46d0798228b8a28e857a2a0f02310fd6ba2a4eab", - "size": 42136, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar" - }, - "natives-windows": { - "sha1": "e9115958773644e863332a6a06488d26f9e1fc9f", - "size": 208314, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2", - "natives": { - "linux": "natives-linux", - "osx": "natives-macos", - "windows": "natives-windows" - } - } - ], - "patchAdditionalLibraries": true - }, - { - "_comment": "Add additional library just for osx-arm64. No override needed", - "match": [ - "ca.weblite:java-objc-bridge:1.0.0" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "369a83621e3c65496348491e533cb97fe5f2f37d", - "size": 91947, - "url": "https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar" - } - }, - "name": "ca.weblite:java-objc-bridge:1.1.0-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add additional classifiers for jinput-platform", - "match": [ - "net.java.jinput:jinput-platform:2.0.5" - ], - "override": { - "downloads": { - "classifiers": { - "natives-osx-arm64": { - "sha1": "5189eb40db3087fb11ca063b68fa4f4c20b199dd", - "size": 10031, - "url": "https://github.com/r58Playz/jinput-m1/raw/main/plugins/OSX/bin/jinput-platform-2.0.5.jar" - }, - "natives-linux-arm64": { - "sha1": "42b388ccb7c63cec4e9f24f4dddef33325f8b212", - "size": 10932, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" - }, - "natives-linux-arm32": { - "sha1": "f3c455b71c5146acb5f8a9513247fc06db182fd5", - "size": 4521, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/jinput-platform-2.0.5-natives-linux.jar" - } - } - }, - "natives": { - "linux-arm64": "natives-linux-arm64", - "linux-arm32": "natives-linux-arm32", - "osx-arm64": "natives-osx-arm64" - } - } - }, - { - "_comment": "Use a newer version on osx-arm64", - "match": [ - "com.mojang:text2speech:1.0.10", - "com.mojang:text2speech:1.5", - "com.mojang:text2speech:1.6", - "com.mojang:text2speech:1.7", - "com.mojang:text2speech:1.10.1", - "com.mojang:text2speech:1.10.3", - "com.mojang:text2speech:1.11.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "f378f889797edd7df8d32272c06ca80a1b6b0f58", - "size": 13164, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar" - } - }, - "name": "com.mojang:text2speech:1.11.3", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl.lwjgl:lwjgl:2.9.3", - "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131120", - "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017", - "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3", - "org.lwjgl.lwjgl:lwjgl:2.9.1" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "697517568c68e78ae0b4544145af031c81082dfe", - "size": 1047168, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar" - } - }, - "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - }, - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl.lwjgl:lwjgl_util:2.9.3", - "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131120", - "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131017", - "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20130708-debug3", - "org.lwjgl.lwjgl:lwjgl_util:2.9.1" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", - "size": 173887, - "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar" - } - }, - "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - }, - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", - "org.lwjgl.lwjgl:lwjgl-platform:2.9.3", - "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131120", - "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131017", - "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20130708-debug3", - "org.lwjgl.lwjgl:lwjgl-platform:2.9.1" - ], - "override": { - "downloads": { - "classifiers": { - "natives-osx-arm64": { - "sha1": "eff546c0b319d6ffc7a835652124c18089c67f36", - "size": 488316, - "url": "https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" - }, - "natives-linux-arm64": { - "sha1": "63ac7da0f4a4785c7eadc0f8edc1e9dcc4dd08cb", - "size": 579979, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" - }, - "natives-linux-arm32": { - "sha1": "fa483e540a9a753a5ffbb23dcf7879a5bf752611", - "size": 475177, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-2.9.4/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" - } - } - }, - "natives": { - "linux-arm64": "natives-linux-arm64", - "linux-arm32": "natives-linux-arm32", - "osx-arm64": "natives-osx-arm64" - } - } - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl:lwjgl-glfw:3.2.2", - "org.lwjgl:lwjgl-glfw:3.2.1", - "org.lwjgl:lwjgl-glfw:3.1.6", - "org.lwjgl:lwjgl-glfw:3.1.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", - "size": 108691, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "155d175037efc76630940c197ca6dea2b17d7e18", - "size": 108691, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw.jar" - }, - "classifiers": { - "natives-linux-arm64": { - "sha1": "074ad243761147df0d060fbefc814614d2ff75cc", - "size": 85072, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman64.1", - "natives": { - "linux-arm64": "natives-linux-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", - "size": 108691, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman32.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "99e9a39fa8ed4167e3ff9e04d47eb32c9e69804d", - "size": 108691, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw.jar" - }, - "classifiers": { - "natives-linux-arm32": { - "sha1": "4265f2fbe3b9d642591165165a17cf406cf7b98e", - "size": 80186, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-glfw-natives-linux-arm32.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.2.2-gman32.1", - "natives": { - "linux-arm32": "natives-linux-arm32" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", - "size": 130128, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.3.1-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "e9a101bca4fa30d26b21b526ff28e7c2d8927f1b", - "size": 130128, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw.jar" - }, - "classifiers": { - "natives-osx-arm64": { - "sha1": "71d793d0a5a42e3dfe78eb882abc2523a2c6b496", - "size": 129076, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-glfw-natives-macos-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-glfw:3.3.1-mmachina.1", - "natives": { - "osx-arm64": "natives-osx-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl:lwjgl-jemalloc:3.2.2", - "org.lwjgl:lwjgl-jemalloc:3.2.1", - "org.lwjgl:lwjgl-jemalloc:3.1.6", - "org.lwjgl:lwjgl-jemalloc:3.1.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", - "size": 33790, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "cc04eec29b2fa8c298791af9800a3766d9617954", - "size": 33790, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" - }, - "classifiers": { - "natives-linux-arm64": { - "sha1": "762d7d80c9cdf3a3f3fc80c8a5f86612255edfe0", - "size": 156343, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-jemalloc-patched-natives-linux-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman64.2", - "natives": { - "linux-arm64": "natives-linux-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", - "size": 33790, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman32.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "8224ae2e8fc6d8e1a0fc7d84dc917aa3c440620c", - "size": 33790, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc.jar" - }, - "classifiers": { - "natives-linux-arm32": { - "sha1": "9163a2a5559ef87bc13ead8fea84417ea3928748", - "size": 134237, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-jemalloc-natives-linux-arm32.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.2.2-gman32.1", - "natives": { - "linux-arm32": "natives-linux-arm32" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "4fb94224378d3588d52d2beb172f2eeafea2d546", - "size": 36976, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.3.1-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "4fb94224378d3588d52d2beb172f2eeafea2d546", - "size": 36976, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc.jar" - }, - "classifiers": { - "natives-osx-arm64": { - "sha1": "b0be721188d2e7195798780b1c5fe7eafe8091c1", - "size": 103478, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-jemalloc-natives-macos-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-jemalloc:3.3.1-mmachina.1", - "natives": { - "osx-arm64": "natives-osx-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl:lwjgl-openal:3.2.2", - "org.lwjgl:lwjgl-openal:3.2.1", - "org.lwjgl:lwjgl-openal:3.1.6", - "org.lwjgl:lwjgl-openal:3.1.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", - "size": 79582, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal:3.2.2-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "6dfce9dc6a9629c75b2ae01a8df7e7be80ba0261", - "size": 79582, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal.jar" - }, - "classifiers": { - "natives-linux-arm64": { - "sha1": "948e415b5b2a2c650c25b377a4a9f443b21ce92e", - "size": 469432, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-openal:3.2.2-gman64.1", - "natives": { - "linux-arm64": "natives-linux-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", - "size": 79582, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal:3.2.2-gman32.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "304f0571fd5971621ee6da86a4c1e90f6f52e2ee", - "size": 79582, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal.jar" - }, - "classifiers": { - "natives-linux-arm32": { - "sha1": "ecbc981fdd996492a1f6334f003ed62e5a8c0cd5", - "size": 398418, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-openal-natives-linux-arm32.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-openal:3.2.2-gman32.1", - "natives": { - "linux-arm32": "natives-linux-arm32" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "d48e753d85916fc8a200ccddc709b36e3865cc4e", - "size": 88880, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal:3.3.1-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "d48e753d85916fc8a200ccddc709b36e3865cc4e", - "size": 88880, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal.jar" - }, - "classifiers": { - "natives-osx-arm64": { - "sha1": "6b80fc0b982a0723b141e88859c42d6f71bd723f", - "size": 346131, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-openal-natives-macos-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-openal:3.3.1-mmachina.1", - "natives": { - "osx-arm64": "natives-osx-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl:lwjgl-opengl:3.2.2", - "org.lwjgl:lwjgl-opengl:3.2.1", - "org.lwjgl:lwjgl-opengl:3.1.6", - "org.lwjgl:lwjgl-opengl:3.1.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", - "size": 937609, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "198bc2f72e0b2eb401eb6f5999aea52909b31ac4", - "size": 937609, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl.jar" - }, - "classifiers": { - "natives-linux-arm64": { - "sha1": "bd40897077bf7d12f562da898b18ac2c68e1f9d7", - "size": 56109, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman64.1", - "natives": { - "linux-arm64": "natives-linux-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", - "size": 937609, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman32.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "9762ae928d02147e716cd82e929b74a97ea9600a", - "size": 937609, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl.jar" - }, - "classifiers": { - "natives-linux-arm32": { - "sha1": "3af5599c74dd76dd8dbb567b3f9b4963a6abeed5", - "size": 56388, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-opengl-natives-linux-arm32.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.2.2-gman32.1", - "natives": { - "linux-arm32": "natives-linux-arm32" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "962c2a8d2a8cdd3b89de3d78d766ab5e2133c2f4", - "size": 929233, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.3.1-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "962c2a8d2a8cdd3b89de3d78d766ab5e2133c2f4", - "size": 929233, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl.jar" - }, - "classifiers": { - "natives-osx-arm64": { - "sha1": "bb575058e0372f515587b5d2d04ff7db185f3ffe", - "size": 41667, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-opengl-natives-macos-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-opengl:3.3.1-mmachina.1", - "natives": { - "osx-arm64": "natives-osx-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl:lwjgl-stb:3.2.2", - "org.lwjgl:lwjgl-stb:3.2.1", - "org.lwjgl:lwjgl-stb:3.1.6", - "org.lwjgl:lwjgl-stb:3.1.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", - "size": 104075, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb:3.2.2-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "46a5735f3eb9d17eb5dcbdd5afa194066d2a6555", - "size": 104075, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb.jar" - }, - "classifiers": { - "natives-linux-arm64": { - "sha1": "077efa7d7ea41b32df5c6078e912e724cccd06db", - "size": 202038, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-stb:3.2.2-gman64.1", - "natives": { - "linux-arm64": "natives-linux-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", - "size": 104075, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb:3.2.2-gman32.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "ea979b0af45b8e689f5f47c989aa8550c148d8a2", - "size": 104075, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb.jar" - }, - "classifiers": { - "natives-linux-arm32": { - "sha1": "ec9d70aaebd0ff76dfeecf8f00b56118bf3706b1", - "size": 149387, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-stb-natives-linux-arm32.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-stb:3.2.2-gman32.1", - "natives": { - "linux-arm32": "natives-linux-arm32" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "703e4b533e2542560e9f94d6d8bd148be1c1d572", - "size": 113273, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb:3.3.1-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "703e4b533e2542560e9f94d6d8bd148be1c1d572", - "size": 113273, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb.jar" - }, - "classifiers": { - "natives-osx-arm64": { - "sha1": "98f0ad956c754723ef354d50057cc30417ef376a", - "size": 178409, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-stb-natives-macos-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-stb:3.3.1-mmachina.1", - "natives": { - "osx-arm64": "natives-osx-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl:lwjgl-tinyfd:3.2.2", - "org.lwjgl:lwjgl-tinyfd:3.2.1", - "org.lwjgl:lwjgl-tinyfd:3.1.6", - "org.lwjgl:lwjgl-tinyfd:3.1.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", - "size": 5571, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "3a75b9811607633bf33c978f53964df1534a4bc1", - "size": 5571, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" - }, - "classifiers": { - "natives-linux-arm64": { - "sha1": "37c744ca289b5d7ae155d79e39029488b3254e5b", - "size": 37893, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman64.1", - "natives": { - "linux-arm64": "natives-linux-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", - "size": 5571, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman32.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "a8c09f5b7fa24bd53ec329c231b566497a163d5b", - "size": 5571, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd.jar" - }, - "classifiers": { - "natives-linux-arm32": { - "sha1": "82d16054ada6633297a3108fb6d8bae98800c76f", - "size": 41663, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-tinyfd-natives-linux-arm32.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.2.2-gman32.1", - "natives": { - "linux-arm32": "natives-linux-arm32" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "1203660b3131cbb8681b17ce6437412545be95e0", - "size": 6802, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.3.1-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "1203660b3131cbb8681b17ce6437412545be95e0", - "size": 6802, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd.jar" - }, - "classifiers": { - "natives-osx-arm64": { - "sha1": "015b931a2daba8f0c317d84c9d14e8e98ae56e0c", - "size": 41384, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-tinyfd-natives-macos-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl-tinyfd:3.3.1-mmachina.1", - "natives": { - "osx-arm64": "natives-osx-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Use a newer patched version on osx-arm64, linux-arm64, and linux-arm32", - "match": [ - "org.lwjgl:lwjgl:3.2.2", - "org.lwjgl:lwjgl:3.2.1", - "org.lwjgl:lwjgl:3.1.6", - "org.lwjgl:lwjgl:3.1.2" - ], - "override": { - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux-arm64" - } - }, - { - "action": "disallow", - "os": { - "name": "linux-arm32" - } - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "360899386df83d6a8407844a94478607af937f97", - "size": 318833, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar" - } - }, - "name": "org.lwjgl:lwjgl:3.2.2-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "360899386df83d6a8407844a94478607af937f97", - "size": 318833, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-core.jar" - }, - "classifiers": { - "natives-linux-arm64": { - "sha1": "612efd57d12b2e48e554858eb35e7e2eb46ebb4c", - "size": 87121, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl:3.2.2-gman64.1", - "natives": { - "linux-arm64": "natives-linux-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", - "size": 318413, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar" - } - }, - "name": "org.lwjgl:lwjgl:3.2.2-gman32.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "16ea3934fca417368250d1ddac01a30c1809d317", - "size": 318413, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-core.jar" - }, - "classifiers": { - "natives-linux-arm32": { - "sha1": "6bd0b37fef777a309936a72dc7f63126e8c79ea5", - "size": 90296, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm32/raw/lwjgl-3.2.2/lwjgl-natives-linux-arm32.jar" - } - } - }, - "name": "org.lwjgl:lwjgl:3.2.2-gman32.1", - "natives": { - "linux-arm32": "natives-linux-arm32" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "8e664dd69ad7bbcf2053da23efc7848e39e498db", - "size": 719038, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl.jar" - } - }, - "name": "org.lwjgl:lwjgl:3.3.1-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "8e664dd69ad7bbcf2053da23efc7848e39e498db", - "size": 719038, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl.jar" - }, - "classifiers": { - "natives-osx-arm64": { - "sha1": "984df31fadaab86838877b112e5b4e4f68a00ccf", - "size": 42693, - "url": "https://github.com/MinecraftMachina/lwjgl3/releases/download/3.3.1-mmachina.1/lwjgl-natives-macos-arm64.jar" - } - } - }, - "name": "org.lwjgl:lwjgl:3.3.1-mmachina.1", - "natives": { - "osx-arm64": "natives-osx-arm64" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.1", - "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.1", - "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.1", - "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.1", - "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.1", - "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.1", - "org.lwjgl:lwjgl-natives-macos-arm64:3.3.1" - ], - "override": { - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - }, - { - "_comment": "Only allow osx-arm64 for existing java-objc-bridge:1.1", - "match": [ - "ca.weblite:java-objc-bridge:1.1" - ], - "override": { - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - }, - { - "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.1", - "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.1", - "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.1", - "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.1", - "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.1", - "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.1", - "org.lwjgl:lwjgl-natives-windows-arm64:3.3.1" - ], - "override": { - "rules": [ - { - "action": "allow", - "os": { - "name": "windows-arm64" - } - } - ] - } - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-glfw:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "513eb39b866d0fe131a18d5c517087805433b029", - "size": 112350, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-jemalloc:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "749be48a9b86ee2c3a2da5fd77511208adcfb33b", - "size": 159993, - "url": "https://github.com/theofficialgman/lwjgl3-binaries-arm64/raw/lwjgl-3.3.1/lwjgl-jemalloc-patched-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.1-gman64.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-openal:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "cf4e303257e82981b8b2e31bba3d7f8f7b8f42b2", - "size": 470743, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-opengl:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "1c528fb258a6e63e8fceb4482d8db0f3af10a634", - "size": 57908, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-stb:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "8e8348a1813aad7f30aaf75ea197151ebb7beba9", - "size": 205491, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-tinyfd:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "964f628b7a82fd909def086c0dd9a4b84bb259ae", - "size": 42654, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "b597401014acb7196c76d97e15a6288f54f1f692", - "size": 86308, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl/lwjgl-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-glfw:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "816d935933f2dd743074c4e717cc25b55720f294", - "size": 104027, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-jemalloc:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "a96a6d6cb3876d7813fcee53c3c24f246aeba3b3", - "size": 136157, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-openal:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "ffbe35d7fa5ec9b7eca136a7c71f24d4025a510b", - "size": 400129, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-opengl:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "e3550fa91097fd56e361b4370fa822220fef3595", - "size": 58474, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-stb:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "b08226bab162c06ae69337d8a1b0ee0a3fdf0b90", - "size": 153889, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl-tinyfd:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "d53d331e859217a61298fcbcf8d79137f3df345c", - "size": 48061, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.1", - "match": [ - "org.lwjgl:lwjgl:3.3.1" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "41a3c1dd15d6b964eb8196dde69720a3e3e5e969", - "size": 82374, - "url": "https://build.lwjgl.org/release/3.3.1/bin/lwjgl/lwjgl-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.1-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-freetype:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "896e7d9b8f60d7273f3d491c69270afc67ece3ce", - "size": 1073374, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-glfw:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "bc49e64bae0f7ff103a312ee8074a34c4eb034c7", - "size": 120168, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-jemalloc:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "5249f18a9ae20ea86c5816bc3107a888ce7a17d2", - "size": 206402, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-openal:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "22408980cc579709feaf9acb807992d3ebcf693f", - "size": 590865, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-opengl:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "bb9eb56da6d1d549d6a767218e675e36bc568eb9", - "size": 58627, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-stb:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "11a380c37b0f03cb46db235e064528f84d736ff7", - "size": 207419, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-tinyfd:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "93f8c5bc1984963cd79109891fb5a9d1e580373e", - "size": 43381, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "8bd89332c90a90e6bc4aa997a25c05b7db02c90a", - "size": 90795, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl/lwjgl-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-freetype:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "b7f77ceb951182659fd400437272aa7e96709968", - "size": 924657, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-glfw:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "5907d9a6b7c44fb0612a63bb1cff5992588f65be", - "size": 110067, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-jemalloc:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "9367437ce192e4d6f5725d53d85520644c0b0d6f", - "size": 177571, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-openal:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "7c82bbc33ef49ee4094b216c940db564b2998224", - "size": 503352, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-opengl:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "821f9a2d1d583c44893f42b96f6977682b48a99b", - "size": 59265, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-stb:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "ca9333da184aade20757151f4615f1e27ca521ae", - "size": 154928, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl-tinyfd:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "807e220913aa0740449ff90d3b3d825cf5f359ed", - "size": 48788, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.2", - "match": [ - "org.lwjgl:lwjgl:3.3.2" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "afcbfaaa46f217e98a6da4208550f71de1f2a225", - "size": 89347, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl/lwjgl-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.2-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-freetype:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "498965aac06c4a0d42df1fbef6bacd05bde7f974", - "size": 1093516, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-glfw:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "492a0f11f85b85899a6568f07511160c1b87cd38", - "size": 122159, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-jemalloc:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "eff8b86798191192fe2cba2dc2776109f30c239d", - "size": 209315, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-openal:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "ad8f302118a65bb8d615f8a2a680db58fb8f835e", - "size": 592963, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-opengl:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "2096f6b94b2d68745d858fbfe53aacf5f0c8074c", - "size": 58625, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-stb:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "ddc177afc2be1ee8d93684b11363b80589a13fe1", - "size": 207418, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-tinyfd:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "2823a8c955c758d0954d282888075019ef99cec7", - "size": 43864, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm64 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "f35d8b6ffe1ac1e3a5eb1d4e33de80f044ad5fd8", - "size": 91294, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl/lwjgl-natives-linux-arm64.jar" - } - }, - "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm64" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-freetype:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "7dd3b1f751571adaf2c4dc882bc675a5d1e796e6", - "size": 942636, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-glfw:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "d9af485c32545b37dd5359b163161d42d7534dcf", - "size": 112560, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-jemalloc:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "109b6931880d02d4e65ced38928a16e41d19873e", - "size": 178324, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-openal:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "e1702aa09d20359d6cf5cb2999fa7685a785eca7", - "size": 505618, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-opengl:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "dbba17fc5ac0985d14a57c11f9537617d67b9952", - "size": 59263, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-stb:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "1ae28ff044699ff29b0e980ffabd73fba8a664b3", - "size": 154931, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl-tinyfd:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "c2a0a05c82c4b9f69ded0b6ad5f417addea78ce2", - "size": 49495, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Add linux-arm32 support for LWJGL 3.3.3", - "match": [ - "org.lwjgl:lwjgl:3.3.3" - ], - "additionalLibraries": [ - { - "downloads": { - "artifact": { - "sha1": "2075c51a80f0ef0f22ba616ba54007ac2b0debd4", - "size": 89565, - "url": "https://build.lwjgl.org/release/3.3.3/bin/lwjgl/lwjgl-natives-linux-arm32.jar" - } - }, - "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.3-lwjgl.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "linux-arm32" - } - } - ] - } - ] - }, - { - "_comment": "Replace glfw from 3.3.1 with version from 3.3.2 to prevent stack smashing", - "match": [ - "org.lwjgl:lwjgl-glfw-natives-linux:3.3.1" - ], - "override": { - "downloads": { - "artifact": { - "sha1": "0766bb0e8e829598b1c8052fd8173c62af741c52", - "size": 115553, - "url": "https://build.lwjgl.org/release/3.3.2/bin/lwjgl-glfw/lwjgl-glfw-natives-linux.jar" - } - }, - "name": "org.lwjgl:lwjgl-glfw-natives-linux:3.3.2-lwjgl.1" - } - } -] diff --git a/static/mojang/minecraft-experiments.json b/static/mojang/minecraft-experiments.json deleted file mode 100644 index 94b50c1a60..0000000000 --- a/static/mojang/minecraft-experiments.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "experiments": [ - { - "id": "1_19_deep_dark_experimental_snapshot-1", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/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", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8c", - "url": "https://launcher.mojang.com/experiments/combat/ea08f7eb1f96cdc82464e27c0f95d23965083cfb/1_16_combat-6.zip" - }, - { - "id": "1_16_combat-5", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8b", - "url": "https://launcher.mojang.com/experiments/combat/9b2b984d635d373564b50803807225c75d7fd447/1_16_combat-5.zip" - }, - { - "id": "1_16_combat-4", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8", - "url": "https://cdn.discordapp.com/attachments/369990015096455168/947864881028272198/1_16_combat-4.zip" - }, - { - "id": "1_16_combat-3", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7c", - "url": "https://launcher.mojang.com/experiments/combat/2557b99d95588505e988886220779087d7d6b1e9/1_16_combat-3.zip" - }, - { - "id": "1_16_combat-2", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7b", - "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-2.zip" - }, - { - "id": "1_16_combat-1", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_7", - "url": "https://archive.org/download/Combat_Test_7ab/1_16_combat-1.zip" - }, - { - "id": "1_16_combat-0", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_6", - "url": "https://launcher.mojang.com/experiments/combat/5a8ceec8681ed96ab6ecb9607fb5d19c8a755559/1_16_combat-0.zip" - }, - { - "id": "1_15_combat-6", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_5", - "url": "https://launcher.mojang.com/experiments/combat/52263d42a626b40c947e523128f7a195ec5af76a/1_15_combat-6.zip" - }, - { - "id": "1_15_combat-1", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_4", - "url": "https://launcher.mojang.com/experiments/combat/ac11ea96f3bb2fa2b9b76ab1d20cacb1b1f7ef60/1_15_combat-1.zip" - }, - { - "id": "1_14_combat-3", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_3", - "url": "https://launcher.mojang.com/experiments/combat/0f209c9c84b81c7d4c88b4632155b9ae550beb89/1_14_combat-3.zip" - }, - { - "id": "1_14_combat-0", - "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_2", - "url": "https://launcher.mojang.com/experiments/combat/d164bb6ecc5fca9ac02878c85f11befae61ac1ca/1_14_combat-0.zip" - }, - { - "id": "1_14_combat-212796", - "wiki": "https://minecraft.wiki/w/Java_Edition_1.14.3_-_Combat_Test", - "url": "https://launcher.mojang.com/experiments/combat/610f5c9874ba8926d5ae1bcce647e5f0e6e7c889/1_14_combat-212796.zip" - } - ] -} \ No newline at end of file diff --git a/static/mojang/minecraft-legacy-override.json b/static/mojang/minecraft-legacy-override.json deleted file mode 100644 index d1d951d05f..0000000000 --- a/static/mojang/minecraft-legacy-override.json +++ /dev/null @@ -1,585 +0,0 @@ -{ - "versions": { - "1.5.2": { - "releaseTime": "2013-04-25T17:45:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.5.1": { - "releaseTime": "2013-03-20T12:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w12~": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.5": { - "releaseTime": "2013-03-07T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w10b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w10a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w09c": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w09b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w09a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w11a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w07a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w06a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w05b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w05a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w04a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w03a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w02b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w02a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w01b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "13w01a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.7": { - "releaseTime": "2012-12-28T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.6": { - "releaseTime": "2012-12-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w50b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w50a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w49a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.5": { - "releaseTime": "2012-11-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.4": { - "releaseTime": "2012-11-14T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.3": { - "releaseTime": "2012-11-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.2": { - "releaseTime": "2012-10-25T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4.1": { - "releaseTime": "2012-10-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.4": { - "releaseTime": "2012-10-19T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w42b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w42a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w41b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w41a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w40b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w40a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w39b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w39a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w38b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w38a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w37a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w36a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w34b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w34a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.3.2": { - "releaseTime": "2012-08-16T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w32a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.3.1": { - "releaseTime": "2012-08-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.3": { - "releaseTime": "2012-07-26T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w30e": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w30d": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w30c": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w30b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w30a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w27a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w26a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w25a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w24a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w23b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w23a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w22a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w21b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w21a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w19a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w18a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w17a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w16a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.5": { - "releaseTime": "2012-03-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.4": { - "releaseTime": "2012-03-22T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.3": { - "releaseTime": "2012-03-02T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.2": { - "releaseTime": "2012-03-01T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2.1": { - "releaseTime": "2012-03-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.2": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w08a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w07a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w07b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w06a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w05b": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w05a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w04a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w03a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.1": { - "releaseTime": "2012-01-12T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "12w01a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "11w50a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "11w49a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "11w48a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "11w47a": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "1.0": { - "releaseTime": "2011-11-18T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.9-pre6": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.9-pre5": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.9-pre4": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.9-pre3": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.9-pre2": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.9-pre1": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.8.1": { - "releaseTime": "2011-09-19T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.8": { - "releaseTime": "2011-09-15T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.8-pre2": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.8-pre1-2": { - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.7.3": { - "releaseTime": "2011-07-08T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.7.2": { - "releaseTime": "2011-07-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.7": { - "releaseTime": "2011-06-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.6": { - "releaseTime": "2011-05-31T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.5": { - "releaseTime": "2011-05-28T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.4": { - "releaseTime": "2011-05-26T00:00:04+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.3": { - "releaseTime": "2011-05-26T00:00:03+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.2": { - "releaseTime": "2011-05-26T00:00:02+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6.1": { - "releaseTime": "2011-05-26T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.6": { - "releaseTime": "2011-05-26T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.5_01": { - "releaseTime": "2011-04-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.5": { - "releaseTime": "2011-04-19T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.4_01": { - "releaseTime": "2011-04-05T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.4": { - "releaseTime": "2011-03-31T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.3_01": { - "releaseTime": "2011-02-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.3b": { - "releaseTime": "2011-02-22T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.2_02": { - "releaseTime": "2011-01-21T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.2_01": { - "releaseTime": "2011-01-14T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.2": { - "releaseTime": "2011-01-13T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.1_02": { - "releaseTime": "2010-12-22T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.1_01": { - "releaseTime": "2010-12-22T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.0.2": { - "releaseTime": "2010-12-21T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.0_01": { - "releaseTime": "2010-12-20T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "b1.0": { - "releaseTime": "2010-12-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.6": { - "releaseTime": "2010-12-03T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.5": { - "releaseTime": "2010-12-01T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.4_01": { - "releaseTime": "2010-11-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3_04": { - "releaseTime": "2010-11-26T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3_02": { - "releaseTime": "2010-11-25T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3_01": { - "releaseTime": "2010-11-24T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.3": { - "releaseTime": "2010-11-24T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.2b": { - "releaseTime": "2010-11-10T00:00:01+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.2a": { - "releaseTime": "2010-11-10T00:00:00+02:00", - "+traits": ["legacyLaunch", "texturepacks"] - }, - "a1.2.1_01": { - "releaseTime": "2010-11-05T00:00:01+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.1": { - "releaseTime": "2010-11-05T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.0_02": { - "releaseTime": "2010-11-04T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.0_01": { - "releaseTime": "2010-10-31T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.2.0": { - "releaseTime": "2010-10-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "a1.1.2_01": { - "releaseTime": "2010-09-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.1.2": { - "releaseTime": "2010-09-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.1.0": { - "releaseTime": "2010-09-13T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.17_04": { - "releaseTime": "2010-08-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.17_02": { - "releaseTime": "2010-08-20T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.16": { - "releaseTime": "2010-08-12T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.15": { - "releaseTime": "2010-08-04T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.14": { - "releaseTime": "2010-07-30T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.11": { - "releaseTime": "2010-07-23T00:00:00+02:00", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.5_01": { - "releaseTime": "2010-07-13T00:00:00+02:00", - "mainClass": "y", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "a1.0.4": { - "releaseTime": "2010-07-09T00:00:00+02:00", - "mainClass": "ax", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "inf-20100618": { - "releaseTime": "2010-06-16T00:00:00+02:00", - "mainClass": "net.minecraft.client.d", - "appletClass": "net.minecraft.client.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"], - "+jvmArgs": ["-Djava.util.Arrays.useLegacyMergeSort=true"] - }, - "c0.30_01c": { - "releaseTime": "2009-12-22T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.l", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "c0.0.13a_03": { - "releaseTime": "2009-05-22T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.c", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "c0.0.13a": { - "releaseTime": "2009-05-31T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.Minecraft", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "c0.0.11a": { - "releaseTime": "2009-05-17T00:00:00+02:00", - "mainClass": "com.mojang.minecraft.Minecraft", - "appletClass": "com.mojang.minecraft.MinecraftApplet", - "+traits": ["legacyLaunch", "no-texturepacks"] - }, - "rd-161348": { - "releaseTime": "2009-05-16T13:48:00+02:00", - "mainClass": "com.mojang.minecraft.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-160052": { - "releaseTime": "2009-05-16T00:52:00+02:00", - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-20090515": { - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-132328": { - "releaseTime": "2009-05-13T23:28:00+02:00", - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - }, - "rd-132211": { - "releaseTime": "2009-05-13T22:11:00+02:00", - "mainClass": "com.mojang.rubydung.RubyDung", - "+traits": ["no-texturepacks"] - } - } -} diff --git a/static/mojang/minecraft-legacy-services.json b/static/mojang/minecraft-legacy-services.json deleted file mode 100644 index 420d3f8c74..0000000000 --- a/static/mojang/minecraft-legacy-services.json +++ /dev/null @@ -1,218 +0,0 @@ -[ - "c0.30_01c", - "inf-20100618", - "a1.0.4", - "a1.0.5_01", - "a1.0.11", - "a1.0.14", - "a1.0.15", - "a1.0.16", - "a1.0.17_02", - "a1.0.17_04", - "a1.1.0", - "a1.1.2", - "a1.1.2_01", - "a1.2.0", - "a1.2.0_01", - "a1.2.0_02", - "a1.2.1", - "a1.2.1_01", - "a1.2.2a", - "a1.2.2b", - "a1.2.3", - "a1.2.3_01", - "a1.2.3_02", - "a1.2.3_04", - "a1.2.4_01", - "a1.2.5", - "a1.2.6", - "b1.0", - "b1.0_01", - "b1.0.2", - "b1.1_01", - "b1.1_02", - "b1.2", - "b1.2_01", - "b1.2_02", - "b1.3b", - "b1.3_01", - "b1.4", - "b1.4_01", - "b1.5", - "b1.5_01", - "b1.6", - "b1.6.1", - "b1.6.2", - "b1.6.3", - "b1.6.4", - "b1.6.5", - "b1.6.6", - "b1.7", - "b1.7.2", - "b1.7.3", - "b1.8-pre1-2", - "b1.8-pre2", - "b1.8", - "b1.8.1", - "b1.9-pre1", - "b1.9-pre2", - "b1.9-pre3", - "b1.9-pre4", - "b1.9-pre5", - "b1.9-pre6", - "1.0", - "11w47a", - "11w48a", - "11w49a", - "11w50a", - "12w01a", - "1.1", - "12w03a", - "12w04a", - "12w05a", - "12w05b", - "12w06a", - "12w07b", - "12w07a", - "12w08a", - "1.2", - "1.2.1", - "1.2.2", - "1.2.3", - "1.2.4", - "1.2.5", - "12w16a", - "12w17a", - "12w18a", - "12w19a", - "12w21a", - "12w21b", - "12w22a", - "12w23a", - "12w23b", - "12w24a", - "12w25a", - "12w26a", - "12w27a", - "12w30a", - "12w30b", - "12w30c", - "12w30d", - "12w30e", - "1.3", - "1.3.1", - "12w32a", - "1.3.2", - "12w34a", - "12w34b", - "12w36a", - "12w37a", - "12w38a", - "12w38b", - "12w39a", - "12w39b", - "12w40a", - "12w40b", - "12w41a", - "12w41b", - "12w42a", - "12w42b", - "1.4", - "1.4.1", - "1.4.2", - "1.4.3", - "1.4.4", - "1.4.5", - "12w49a", - "12w50a", - "12w50b", - "1.4.6", - "1.4.7", - "13w01a", - "13w01b", - "13w02a", - "13w02b", - "13w03a", - "13w04a", - "13w05a", - "13w05b", - "13w06a", - "13w07a", - "13w11a", - "13w09a", - "13w09b", - "13w09c", - "13w10a", - "13w10b", - "1.5", - "13w12~", - "1.5.1", - "1.5.2", - "13w17a", - "13w18a", - "13w18b", - "13w18c", - "13w19a", - "13w21a", - "13w21b", - "13w22a", - "13w23a", - "13w23b", - "13w24a", - "13w24b", - "13w25a", - "13w25b", - "13w25c", - "13w26a", - "1.6", - "1.6.1", - "1.6.2", - "13w36a", - "13w36b", - "13w37a", - "1.6.3", - "13w37b", - "1.6.4", - "13w38a", - "13w38b", - "13w38c", - "13w39a", - "13w39b", - "13w41a", - "13w41b", - "13w42a", - "13w42b", - "13w43a", - "1.7", - "1.7.1", - "1.7.2", - "13w47a", - "13w47b", - "13w47c", - "13w47d", - "13w47e", - "13w48a", - "13w48b", - "13w49a", - "1.7.3", - "1.7.4", - "14w02a", - "14w02b", - "14w02c", - "14w03a", - "14w03b", - "14w04a", - "14w04b", - "14w05a", - "14w05b", - "14w06a", - "14w06b", - "14w07a", - "1.7.5", - "14w08a", - "14w10b", - "14w10c", - "1.7.6-pre1", - "1.7.6-pre2", - "14w11a" -] diff --git a/static/mojang/minecraft-old-snapshots.json b/static/mojang/minecraft-old-snapshots.json deleted file mode 100644 index 24ee0ce8b8..0000000000 --- a/static/mojang/minecraft-old-snapshots.json +++ /dev/null @@ -1,604 +0,0 @@ -{ - "old_snapshots": [ - { - "id": "1_2", - "wiki": "https://minecraft.wiki/w/Java_Edition_1.2", - "url": "https://archive.org/download/Minecraft-JSONs/1.2.json", - "sha1": "a2064011425a5e5befd9dee5eeb4f968ddf5ac77", - "size": 3988919, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_2/minecraft.jar" - }, - { - "id": "11w47a", - "wiki": "https://minecraft.wiki/w/Java_Edition_11w47a", - "url": "https://archive.org/download/Minecraft-JSONs/11w47a.json", - "sha1": "4e327918708d22e7443fbadefb9831ca04af4b90", - "size": 2242242, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w47a/minecraft.jar" - }, - { - "id": "11w48a", - "wiki": "https://minecraft.wiki/w/Java_Edition_11w48a", - "url": "https://archive.org/download/Minecraft-JSONs/11w48a.json", - "sha1": "fede770abe88a19e844d99dda611a7d18184155a", - "size": 2242604, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w48a/minecraft.jar" - }, - { - "id": "11w49a", - "wiki": "https://minecraft.wiki/w/Java_Edition_11w49a", - "url": "https://archive.org/download/Minecraft-JSONs/11w49a.json", - "sha1": "6f92a726e6b8b64f66c7e4d236f983c278d5af54", - "size": 3510866, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w49a/minecraft.jar" - }, - { - "id": "11w50a", - "wiki": "https://minecraft.wiki/w/Java_Edition_11w50a", - "url": "https://archive.org/download/Minecraft-JSONs/11w50a.json", - "sha1": "f4981ba0fee00a16d8dc9ec87bf2c4fdb51e4b7c", - "size": 3509701, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/11w50a/minecraft.jar" - }, - { - "id": "12w01a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w01a", - "url": "https://archive.org/download/Minecraft-JSONs/12w01a.json", - "sha1": "653a9cf55884b6bc4dcf3c574331e04bd5ad1032", - "size": 3839447, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w01a/minecraft.jar" - }, - { - "id": "12w03a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w03a", - "url": "https://archive.org/download/Minecraft-JSONs/12w03a.json", - "sha1": "e581c7c9dd57cbf73f72b833be5eff6109187df0", - "size": 3875210, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w03a/minecraft.jar" - }, - { - "id": "12w04a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w04a", - "url": "https://archive.org/download/Minecraft-JSONs/12w04a.json", - "sha1": "4911c473e856ec8102b8419eb36d0f54dad029a0", - "size": 3911974, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w04a/minecraft.jar" - }, - { - "id": "12w05a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w05a", - "url": "https://archive.org/download/Minecraft-JSONs/12w05a.json", - "sha1": "28328e67b82564335aa8280095a0716a2eb790de", - "size": 3931639, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05a/minecraft.jar" - }, - { - "id": "12w05b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w05b", - "url": "https://archive.org/download/Minecraft-JSONs/12w05b.json", - "sha1": "75fbc4a39a244d0f1eb842ff8385e992e2b47dd5", - "size": 3931694, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w05b/minecraft.jar" - }, - { - "id": "12w06a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w06a", - "url": "https://archive.org/download/Minecraft-JSONs/12w06a.json", - "sha1": "a8403c0d4c0cdb65722d864d9cf42663b8aab08b", - "size": 3934973, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w06a/minecraft.jar" - }, - { - "id": "12w07a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w07a", - "url": "https://archive.org/download/Minecraft-JSONs/12w07a.json", - "sha1": "e7ad115b29612b893972f0817030d993bc56fb7e", - "size": 3956252, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07a/minecraft.jar" - }, - { - "id": "12w07b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w07b", - "url": "https://archive.org/download/Minecraft-JSONs/12w07b.json", - "sha1": "0eea35d588fc2cee5d397472aa3565f48c220217", - "size": 3956323, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w07b/minecraft.jar" - }, - { - "id": "12w08a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w08a", - "url": "https://archive.org/download/Minecraft-JSONs/12w08a.json", - "sha1": "db2fcfdd23526b0f381ef2f3f2fd049d36227230", - "size": 3981486, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w08a/minecraft.jar" - }, - { - "id": "12w16a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w16a", - "url": "https://archive.org/download/Minecraft-JSONs/12w16a.json", - "sha1": "6b0a9fe3ac275f79ac6d259f4279752274ec05f8", - "size": 4080437, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w16a/minecraft.jar" - }, - { - "id": "12w17a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w17a", - "url": "https://archive.org/download/Minecraft-JSONs/12w17a.json", - "sha1": "17d41f8a07e054040ba34e523593bdea7f0fb6ba", - "size": 4114768, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w17a/minecraft.jar" - }, - { - "id": "12w18a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w18a", - "url": "https://archive.org/download/Minecraft-JSONs/12w18a.json", - "sha1": "9e9ab992317048bee9158ad9d1e2bc758db2b4af", - "size": 4317820, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w18a/minecraft.zip/bin/minecraft.jar" - }, - { - "id": "12w19a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w19a", - "url": "https://archive.org/download/Minecraft-JSONs/12w19a.json", - "sha1": "474aaac9a8b1dcbf312a5c09c7eae4a6aa401225", - "size": 4343792, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w19a/minecraft.zip/bin/minecraft.jar" - }, - { - "id": "12w21a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w21a", - "url": "https://archive.org/download/Minecraft-JSONs/12w21a.json", - "sha1": "e755423a04b0efde01e035a9d651acadeba0aef9", - "size": 4409586, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21a/minecraft.jar" - }, - { - "id": "12w21b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w21b", - "url": "https://archive.org/download/Minecraft-JSONs/12w21b.json", - "sha1": "84437ded4839b29d34f83e9f3bab07cc48980faf", - "size": 4499708, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w21b/minecraft.jar" - }, - { - "id": "12w22a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w22a", - "url": "https://archive.org/download/Minecraft-JSONs/12w22a.json", - "sha1": "3631a714cb465d39f5cb5c18aa23abf38031b359", - "size": 4542344, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w22a/minecraft.jar" - }, - { - "id": "12w23a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w23a", - "url": "https://archive.org/download/Minecraft-JSONs/12w23a.json", - "sha1": "4a5a8e3349ea2e9d67fa4dde6ec68d385bff46f0", - "size": 4543912, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23a/minecraft.jar" - }, - { - "id": "12w23b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w23b", - "url": "https://archive.org/download/Minecraft-JSONs/12w23b.json", - "sha1": "e107667bcbb4443afc160a7eeb8f347acc9826f8", - "size": 4543928, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w23b/minecraft.jar" - }, - { - "id": "12w24a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w24a", - "url": "https://archive.org/download/Minecraft-JSONs/12w24a.json", - "sha1": "e479c425ffe6ca3512d97ad0e02a8cd85356bf83", - "size": 4540049, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w24a/minecraft.jar" - }, - { - "id": "12w25a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w25a", - "url": "https://archive.org/download/Minecraft-JSONs/12w25a.json", - "sha1": "eddf53994e40ecc44f582d4b47b9a441844909b6", - "size": 4556548, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w25a/minecraft.jar" - }, - { - "id": "12w26a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w26a", - "url": "https://archive.org/download/Minecraft-JSONs/12w26a.json", - "sha1": "2d1e782a4c4435fe921027ae464a272945cca925", - "size": 4573075, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w26a/minecraft.jar" - }, - { - "id": "12w27a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w27a", - "url": "https://archive.org/download/Minecraft-JSONs/12w27a.json", - "sha1": "5e69b80f9c757bdc8275c1f6ce7e71820fe6d79a", - "size": 4584956, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w27a/minecraft.jar" - }, - { - "id": "12w30a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w30a", - "url": "https://archive.org/download/Minecraft-JSONs/12w30a.json", - "sha1": "368215d7fd38ee3e829725e11b3f193d45801128", - "size": 4584574, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30a/minecraft.jar" - }, - { - "id": "12w30b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w30b", - "url": "https://archive.org/download/Minecraft-JSONs/12w30b.json", - "sha1": "9d1e450cdb300ec426b50762e031796a8349aa1c", - "size": 4584593, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30b/minecraft.jar" - }, - { - "id": "12w30c", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w30c", - "url": "https://archive.org/download/Minecraft-JSONs/12w30c.json", - "sha1": "92817a0c3f3c913ad68bdb082ac1f147db986282", - "size": 4584617, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30c/minecraft.jar" - }, - { - "id": "12w30d", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w30d", - "url": "https://archive.org/download/Minecraft-JSONs/12w30d.json", - "sha1": "a5e7508de2d3993cb5222d8e4f8415226745d6ff", - "size": 4585459, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30d/minecraft.jar" - }, - { - "id": "12w30e", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w30e", - "url": "https://archive.org/download/Minecraft-JSONs/12w30e.json", - "sha1": "1a37562cda14028dae15b331bfd36108e617a477", - "size": 4585506, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w30e/minecraft.jar" - }, - { - "id": "12w32a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w32a", - "url": "https://archive.org/download/Minecraft-JSONs/12w32a.json", - "sha1": "13183e023c8918ed08c302c2fe1438f61b53d094", - "size": 4628354, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w32a/minecraft.jar" - }, - { - "id": "12w34a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w34a", - "url": "https://archive.org/download/Minecraft-JSONs/12w34a.json", - "sha1": "41769085c020f4651b5b5dd50a6f83be2b000b29", - "size": 4676139, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34a/minecraft.jar" - }, - { - "id": "12w34b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w34b", - "url": "https://archive.org/download/Minecraft-JSONs/12w34b.json", - "sha1": "5fb51efc8f07ea57ffc2a02a7dac8a2835651b61", - "size": 4682004, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w34b/minecraft.jar" - }, - { - "id": "12w36a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w36a", - "url": "https://archive.org/download/Minecraft-JSONs/12w36a.json", - "sha1": "914bd89686c4621da327d50375a1edbdd9c177da", - "size": 4705667, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w36a/minecraft.jar" - }, - { - "id": "12w37a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w37a", - "url": "https://archive.org/download/Minecraft-JSONs/12w37a.json", - "sha1": "50ea0bac2c91b13c0881bbf99aad66a046533781", - "size": 4727781, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w37a/minecraft.jar" - }, - { - "id": "12w38a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w38a", - "url": "https://archive.org/download/Minecraft-JSONs/12w38a.json", - "sha1": "69e5a531fa615eb870345feb25f26126fe95586b", - "size": 4752649, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38a/minecraft.jar" - }, - { - "id": "12w38b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w38b", - "url": "https://archive.org/download/Minecraft-JSONs/12w38b.json", - "sha1": "867505cb4934016bf46cb8c7833ef0eaef8d39d9", - "size": 4767044, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w38b/minecraft.jar" - }, - { - "id": "12w39a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w39a", - "url": "https://archive.org/download/Minecraft-JSONs/12w39a.json", - "sha1": "65247c02036156b9f34c17f7d8bb053641afd0e7", - "size": 4768937, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39a/minecraft.jar" - }, - { - "id": "12w39b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w39b", - "url": "https://archive.org/download/Minecraft-JSONs/12w39b.json", - "sha1": "620d02bfd74204462a810874f83929d0b8b0b936", - "size": 4766448, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w39b/minecraft.jar" - }, - { - "id": "12w40a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w40a", - "url": "https://archive.org/download/Minecraft-JSONs/12w40a.json", - "sha1": "434652551e93fdfb4de30cbe64310037777f7eff", - "size": 4884173, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40a/minecraft.jar" - }, - { - "id": "12w40b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w40b", - "url": "https://archive.org/download/Minecraft-JSONs/12w40b.json", - "sha1": "1612e0fa6062f764844c5a71ff89660c311f38ae", - "size": 4884732, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w40b/minecraft.jar" - }, - { - "id": "12w41a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w41a", - "url": "https://archive.org/download/Minecraft-JSONs/12w41a.json", - "sha1": "7327bcd4da0d194565d6ee732b1fa48e8b14b347", - "size": 4900512, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41a/minecraft.jar" - }, - { - "id": "12w41b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w41b", - "url": "https://archive.org/download/Minecraft-JSONs/12w41b.json", - "sha1": "d73a5b6919d10689811c11d1c3debcd817050039", - "size": 4900976, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w41b/minecraft.jar" - }, - { - "id": "12w42a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w42a", - "url": "https://archive.org/download/Minecraft-JSONs/12w42a.json", - "sha1": "0b10f7afbd54392b387a23c34547cb0f30d48998", - "size": 4919860, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42a/minecraft.jar" - }, - { - "id": "12w42b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w42b", - "url": "https://archive.org/download/Minecraft-JSONs/12w42b.json", - "sha1": "74024eab7588bd33dd53baa756fd4deb92557b0a", - "size": 4921744, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w42b/minecraft.jar" - }, - { - "id": "12w49a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w49a", - "url": "https://archive.org/download/Minecraft-JSONs/12w49a.json", - "sha1": "a5a4cf65cf89207eb6ad7371c9237973865eba81", - "size": 4990865, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w49a/minecraft.jar" - }, - { - "id": "12w50a", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w50a", - "url": "https://archive.org/download/Minecraft-JSONs/12w50a.json", - "sha1": "96a6427720aef608a594ed1e0291e77cba398155", - "size": 5004175, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50a/minecraft.jar" - }, - { - "id": "12w50b", - "wiki": "https://minecraft.wiki/w/Java_Edition_12w50b", - "url": "https://archive.org/download/Minecraft-JSONs/12w50b.json", - "sha1": "73dc6efe46fef478cc5ed123e711872450e193fd", - "size": 5005360, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/12w50b/minecraft.jar" - }, - { - "id": "13w01a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w01a", - "url": "https://archive.org/download/Minecraft-JSONs/13w01a.json", - "sha1": "e3256fe44cd7c6a1bf45570337e634b030589878", - "size": 5033591, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01a/minecraft.jar" - }, - { - "id": "13w01b", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w01b", - "url": "https://archive.org/download/Minecraft-JSONs/13w01b.json", - "sha1": "87f9f88eb3dcc80dcf818e44af774ab7ff63eb66", - "size": 5035543, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w01b/minecraft.jar" - }, - { - "id": "13w02a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w02a", - "url": "https://archive.org/download/Minecraft-JSONs/13w02a.json", - "sha1": "e9a57e8d5dcddcc9d919054c19b10eb71fcc304e", - "size": 5499864, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02a/minecraft.jar" - }, - { - "id": "13w02b", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w02b", - "url": "https://archive.org/download/Minecraft-JSONs/13w02b.json", - "sha1": "9289953c82ce69ec3d2e59a6044a9c900a99478f", - "size": 5363159, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w02b/minecraft.jar" - }, - { - "id": "13w03a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w03a", - "url": "https://archive.org/download/Minecraft-JSONs/13w03a.json", - "sha1": "6a2d3ffa88b7f5e0949f041193c6525d1c4cc22e", - "size": 6401672, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w03a/minecraft.jar" - }, - { - "id": "13w04a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w04a", - "url": "https://archive.org/download/Minecraft-JSONs/13w04a.json", - "sha1": "dff06285694aab7771682f949d51bca98ce52359", - "size": 6426112, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w04a/minecraft.jar" - }, - { - "id": "13w05a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w05a", - "url": "https://archive.org/download/Minecraft-JSONs/13w05a.json", - "sha1": "7808f090cb92afc8084545dd2ea305773bbd5e6e", - "size": 6442319, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05a/minecraft.jar" - }, - { - "id": "13w05b", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w05b", - "url": "https://archive.org/download/Minecraft-JSONs/13w05b.json", - "sha1": "72074d7cb843229292f71ae917dcefbc0f01461d", - "size": 6442459, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w05b/minecraft.jar" - }, - { - "id": "13w06a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w06a", - "url": "https://archive.org/download/Minecraft-JSONs/13w06a.json", - "sha1": "da409ce9f9c910c08cc729aadc6f592b8ff813cb", - "size": 6445893, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w06a/minecraft.jar" - }, - { - "id": "13w07a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w07a", - "url": "https://archive.org/download/Minecraft-JSONs/13w07a.json", - "sha1": "61f7dad52c34838be7a1e7d37a2370ac847ab87a", - "size": 6510193, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w07a/minecraft.jar" - }, - { - "id": "13w09a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w09a", - "url": "https://archive.org/download/Minecraft-JSONs/13w09a.json", - "sha1": "9ac49c55ca76eedfc985fa245dd0682e08b34982", - "size": 5574252, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09a/minecraft.jar" - }, - { - "id": "13w09b", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w09b", - "url": "https://archive.org/download/Minecraft-JSONs/13w09b.json", - "sha1": "635161d84725b1988f814c890fe5841ad99121e1", - "size": 5578604, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09b/minecraft.jar" - }, - { - "id": "13w09c", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w09c", - "url": "https://archive.org/download/Minecraft-JSONs/13w09c.json", - "sha1": "1367ef1410c2ce7ac0f1c58727aa4883c8677469", - "size": 5533426, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w09c/minecraft.jar" - }, - { - "id": "13w10a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w10a", - "url": "https://archive.org/download/Minecraft-JSONs/13w10a.json", - "sha1": "9162bca3ba8a77da2cd26cda1e46ca89a44bac4a", - "size": 5534991, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10a/minecraft.jar" - }, - { - "id": "13w10b", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w10b", - "url": "https://archive.org/download/Minecraft-JSONs/13w10b.json", - "sha1": "21e35ffe1772d1cf89aea653c7a883acb54b13a3", - "size": 5555235, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w10b/minecraft.jar" - }, - { - "id": "13w11a", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w11a", - "url": "https://archive.org/download/Minecraft-JSONs/13w11a.json", - "sha1": "bec6c96bc4413ea3092428aba93d7425fe6a4ea9", - "size": 5556608, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w11a/minecraft.jar" - }, - { - "id": "13w12~", - "wiki": "https://minecraft.wiki/w/Java_Edition_13w12~", - "url": "https://archive.org/download/Minecraft-JSONs/13w12~.json", - "sha1": "66d6c6b5205ae1e8f0ad3eb78ccf66500f39c0c7", - "size": 5561634, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/13w12_/minecraft.jar" - }, - { - "id": "b1_8-pre1", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.8-pre1-2", - "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre1-2.json", - "sha1": "6789c69ede3aedf83b800c76bea56855d38a0afc", - "size": 1893151, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre/minecraft.jar" - }, - { - "id": "b1_8-pre2", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.8-pre2", - "url": "https://archive.org/download/Minecraft-JSONs/b1.8-pre2.json", - "sha1": "44191f2895bf1e064269c9279778f2e3e9c3c9c7", - "size": 1897780, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_8-pre2/minecraft.jar" - }, - { - "id": "b1_9-pre1", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre1", - "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre1.json", - "sha1": "fdeef0129af130aa00702e53c37c5c4029b7d50e", - "size": 1966908, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre/minecraft.jar" - }, - { - "id": "b1_9-pre2", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre2", - "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre2.json", - "sha1": "b0d40cf43b625631af65e2a645c34b533251da0e", - "size": 1988123, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre2/minecraft.jar" - }, - { - "id": "b1_9-pre3", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre3", - "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre3.json", - "sha1": "5b7fe76a602b7511c97740e36dc25040ccb6e76b", - "size": 2087104, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre3/minecraft.jar" - }, - { - "id": "b1_9-pre4", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre4", - "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre4.json", - "sha1": "5c4831d9705f2e00e3cd993e89b822636492932a", - "size": 2147107, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre4/minecraft.jar" - }, - { - "id": "b1_9-pre5", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre5", - "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre5.json", - "sha1": "e109b297d2c4ee7a0bd6aed72f38f7e3185654cf", - "size": 2211261, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre5/minecraft.jar" - }, - { - "id": "b1_9-pre6", - "wiki": "https://minecraft.wiki/w/Java_Edition_b1.9-pre6", - "url": "https://archive.org/download/Minecraft-JSONs/b1.9-pre6.json", - "sha1": "f0983e65cd1c0768b0d1fec471ce4f69173b8126", - "size": 2239270, - "jar": "https://archive.org/download/assets.minecraft.net-2013-11-13/assets.minecraft.net/1_9-pre6/minecraft.jar" - } - ] -} diff --git a/status.sh b/status.sh deleted file mode 100755 index 4f04e6a99e..0000000000 --- a/status.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -BASEDIR=$(dirname "$0") -cd "${BASEDIR}" || exit 1 -BASEDIR=$(pwd) - -source config.sh - -echo "Upstream:" -pushd "${UPSTREAM_DIR}" || exit 1 -git status -popd || exit 1 -echo - - -echo "PrismLauncher:" -pushd "${LAUNCHER_DIR}" || exit 1 -git status -popd || exit 1 -echo - -echo "Scripts:" -git status -echo \ No newline at end of file diff --git a/update.sh b/update.sh index 48cce7a526..40d885b2b3 100755 --- a/update.sh +++ b/update.sh @@ -1,20 +1,14 @@ -#!/bin/bash - -BASEDIR=$(dirname "$0") -cd "${BASEDIR}" || exit 1 -BASEDIR=$(pwd) +#!/usr/bin/env bash set -x -source config.sh -if [ -f config/config_local.sh ]; then - source config/config_local.sh +if [ -f config.sh ]; then + source config.sh fi -MODE=${MODE:-develop} - -BRANCH_var="BRANCH_$MODE" -BRANCH="${!BRANCH_var}" +export META_CACHE_DIR=${CACHE_DIRECTORY:-./caches} +export META_UPSTREAM_DIR=${META_UPSTREAM_DIR:-${STATE_DIRECTORY:-.}/upstream} +export META_LAUNCHER_DIR=${META_LAUNCHER_DIR:-${STATE_DIRECTORY:-.}/launcher} function fail_in { upstream_git reset --hard HEAD @@ -27,11 +21,11 @@ function fail_out { } function upstream_git { - git -C "${BASEDIR}/${UPSTREAM_DIR}" "$@" + git -C "${META_UPSTREAM_DIR}" "$@" } function launcher_git { - git -C "${BASEDIR}/${LAUNCHER_DIR}" "$@" + git -C "${META_LAUNCHER_DIR}" "$@" } # make sure we *could* push to our repo @@ -39,14 +33,13 @@ function launcher_git { currentDate=$(date -I) upstream_git reset --hard HEAD || exit 1 -upstream_git checkout "${BRANCH}" || exit 1 -python updateMojang.py || fail_in -python updateForge.py || fail_in -python updateNeoForge.py || fail_in -python updateFabric.py || fail_in -python updateQuilt.py || fail_in -python updateLiteloader.py || fail_in +python -m meta.run.update_mojang || fail_in +python -m meta.run.update_forge || fail_in +python -m meta.run.update_neoforge || fail_in +python -m meta.run.update_fabric || fail_in +python -m meta.run.update_quilt || fail_in +python -m meta.run.update_liteloader || fail_in if [ "${DEPLOY_TO_GIT}" = true ] ; then upstream_git add mojang/version_manifest_v2.json mojang/versions/* || fail_in @@ -62,15 +55,14 @@ if [ "${DEPLOY_TO_GIT}" = true ] ; then fi launcher_git reset --hard HEAD || exit 1 -launcher_git checkout "${BRANCH}" || exit 1 -python generateMojang.py || fail_out -python generateForge.py || fail_out -python generateNeoForge.py || fail_out -python generateFabric.py || fail_out -python generateQuilt.py || fail_out -python generateLiteloader.py || fail_out -python index.py || fail_out +python -m meta.run.generate_mojang || fail_out +python -m meta.run.generate_forge || fail_out +python -m meta.run.generate_neoforge || fail_out +python -m meta.run.generate_fabric || fail_out +python -m meta.run.generate_quilt || fail_out +python -m meta.run.generate_liteloader || fail_out +python -m meta.run.index || fail_out if [ "${DEPLOY_TO_GIT}" = true ] ; then launcher_git add index.json org.lwjgl/* org.lwjgl3/* net.minecraft/* || fail_out @@ -87,10 +79,8 @@ if [ "${DEPLOY_TO_GIT}" = true ] ; then fi if [ "${DEPLOY_TO_FOLDER}" = true ] ; then - DEPLOY_FOLDER_var="DEPLOY_FOLDER_$MODE" - DEPLOY_FOLDER="${!DEPLOY_FOLDER_var}" echo "Deploying to ${DEPLOY_FOLDER}" - rsync -rvog --chown="${DEPLOY_FOLDER_USER}:${DEPLOY_FOLDER_GROUP}" --exclude=.git "${BASEDIR}/${LAUNCHER_DIR}/" "${DEPLOY_FOLDER}" + rsync -rvog --chown="${DEPLOY_FOLDER_USER}:${DEPLOY_FOLDER_GROUP}" --exclude=.git "${LAUNCHER_DIR}/" "${DEPLOY_FOLDER}" fi exit 0 diff --git a/updateFabric.py b/updateFabric.py deleted file mode 100755 index 132495b92c..0000000000 --- a/updateFabric.py +++ /dev/null @@ -1,130 +0,0 @@ -import json -import os -import zipfile -from datetime import datetime - -import requests - -from meta.common import ( - upstream_path, - ensure_upstream_dir, - transform_maven_key, - default_session, -) -from meta.common.fabric import ( - JARS_DIR, - INSTALLER_INFO_DIR, - META_DIR, - DATETIME_FORMAT_HTTP, -) -from meta.model.fabric import FabricJarInfo - -UPSTREAM_DIR = upstream_path() - -ensure_upstream_dir(JARS_DIR) -ensure_upstream_dir(INSTALLER_INFO_DIR) -ensure_upstream_dir(META_DIR) - -sess = default_session() - - -def filehash(filename, hashtype, blocksize=65536): - h = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - h.update(block) - return h.hexdigest() - - -def get_maven_url(maven_key, server, ext): - parts = maven_key.split(":", 3) - maven_ver_url = ( - server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" - ) - maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext - return maven_url - - -def get_json_file(path, url): - with open(path, "w", encoding="utf-8") as f: - r = sess.get(url) - r.raise_for_status() - version_json = r.json() - json.dump(version_json, f, sort_keys=True, indent=4) - return version_json - - -def head_file(url): - r = sess.head(url) - r.raise_for_status() - return r.headers - - -def get_binary_file(path, url): - with open(path, "wb") as f: - r = sess.get(url) - r.raise_for_status() - for chunk in r.iter_content(chunk_size=128): - f.write(chunk) - - -def compute_jar_file(path, url): - # These two approaches should result in the same metadata, except for the timestamp which might be a few minutes - # off for the fallback method - try: - # Let's not download a Jar file if we don't need to. - headers = head_file(url) - tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) - except requests.HTTPError: - # Just in case something changes in the future - print(f"Falling back to downloading jar for {url}") - - jar_path = path + ".jar" - get_binary_file(jar_path, url) - tstamp = datetime.fromtimestamp(0) - with zipfile.ZipFile(jar_path) as jar: - allinfo = jar.infolist() - for info in allinfo: - tstamp_new = datetime(*info.date_time) - if tstamp_new > tstamp: - tstamp = tstamp_new - - data = FabricJarInfo(release_time=tstamp) - data.write(path + ".json") - - -def main(): - # get the version list for each component we are interested in - for component in ["intermediary", "loader"]: - index = get_json_file( - os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), - "https://meta.fabricmc.net/v2/versions/" + component, - ) - for it in index: - print(f"Processing {component} {it['version']} ") - jar_maven_url = get_maven_url( - it["maven"], "https://maven.fabricmc.net/", ".jar" - ) - compute_jar_file( - os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), - jar_maven_url, - ) - - # for each loader, download installer JSON file from maven - with open( - os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" - ) as loaderVersionIndexFile: - loader_version_index = json.load(loaderVersionIndexFile) - for it in loader_version_index: - print(f"Downloading JAR info for loader {it['version']} ") - maven_url = get_maven_url( - it["maven"], "https://maven.fabricmc.net/", ".json" - ) - get_json_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), - maven_url, - ) - - -if __name__ == "__main__": - main() diff --git a/updateForge.py b/updateForge.py deleted file mode 100755 index 8bae3768be..0000000000 --- a/updateForge.py +++ /dev/null @@ -1,397 +0,0 @@ -""" - Get the source files necessary for generating Forge versions -""" -import copy -import hashlib -import json -import os -import re -import sys -import zipfile -from contextlib import suppress -from datetime import datetime -from pathlib import Path -from pprint import pprint - -from pydantic import ValidationError - -from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session -from meta.common.forge import ( - JARS_DIR, - INSTALLER_INFO_DIR, - INSTALLER_MANIFEST_DIR, - VERSION_MANIFEST_DIR, - FILE_MANIFEST_DIR, - BAD_VERSIONS, - STATIC_LEGACYINFO_FILE, -) -from meta.model.forge import ( - ForgeFile, - ForgeEntry, - ForgeMCVersionInfo, - ForgeLegacyInfoList, - DerivedForgeIndex, - ForgeVersion, - ForgeInstallerProfile, - ForgeInstallerProfileV2, - InstallerInfo, - ForgeLegacyInfo, -) -from meta.model.mojang import MojangVersion - -UPSTREAM_DIR = upstream_path() -STATIC_DIR = static_path() - -ensure_upstream_dir(JARS_DIR) -ensure_upstream_dir(INSTALLER_INFO_DIR) -ensure_upstream_dir(INSTALLER_MANIFEST_DIR) -ensure_upstream_dir(VERSION_MANIFEST_DIR) -ensure_upstream_dir(FILE_MANIFEST_DIR) - -LEGACYINFO_PATH = os.path.join(STATIC_DIR, STATIC_LEGACYINFO_FILE) - -sess = default_session() - - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - -def filehash(filename, hashtype, blocksize=65536): - hashtype = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - hashtype.update(block) - return hashtype.hexdigest() - - -def get_single_forge_files_manifest(longversion): - print(f"Getting Forge manifest for {longversion}") - path_thing = UPSTREAM_DIR + "/forge/files_manifests/%s.json" % longversion - files_manifest_file = Path(path_thing) - from_file = False - if files_manifest_file.is_file(): - with open(path_thing, "r") as f: - files_json = json.load(f) - from_file = True - else: - file_url = ( - "https://files.minecraftforge.net/net/minecraftforge/forge/%s/meta.json" - % longversion - ) - r = sess.get(file_url) - r.raise_for_status() - files_json = r.json() - - ret_dict = dict() - - for classifier, extensionObj in files_json.get("classifiers").items(): - assert type(classifier) == str - assert type(extensionObj) == dict - - # assert len(extensionObj.items()) == 1 - index = 0 - count = 0 - while index < len(extensionObj.items()): - mutable_copy = copy.deepcopy(extensionObj) - extension, hashtype = mutable_copy.popitem() - if not type(classifier) == str: - pprint(classifier) - pprint(extensionObj) - if not type(hashtype) == str: - pprint(classifier) - pprint(extensionObj) - print( - "%s: Skipping missing hash for extension %s:" - % (longversion, extension) - ) - index += 1 - continue - assert type(classifier) == str - processed_hash = re.sub(r"\W", "", hashtype) - if not len(processed_hash) == 32: - print( - "%s: Skipping invalid hash for extension %s:" - % (longversion, extension) - ) - pprint(extensionObj) - index += 1 - continue - - file_obj = ForgeFile( - classifier=classifier, hash=processed_hash, extension=extension - ) - if count == 0: - ret_dict[classifier] = file_obj - index += 1 - count += 1 - else: - print( - "%s: Multiple objects detected for classifier %s:" - % (longversion, classifier) - ) - pprint(extensionObj) - assert False - - if not from_file: - with open(path_thing, "w", encoding="utf-8") as f: - json.dump(files_json, f, sort_keys=True, indent=4) - - return ret_dict - - -def main(): - # get the remote version list fragments - r = sess.get( - "https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json" - ) - r.raise_for_status() - main_json = r.json() - assert type(main_json) == dict - - r = sess.get( - "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json" - ) - r.raise_for_status() - promotions_json = r.json() - assert type(promotions_json) == dict - - promoted_key_expression = re.compile( - "(?P[^-]+)-(?P(latest)|(recommended))(-(?P[a-zA-Z0-9\\.]+))?" - ) - - recommended_set = set() - - new_index = DerivedForgeIndex() - - # FIXME: does not fully validate that the file has not changed format - # NOTE: For some insane reason, the format of the versions here is special. It having a branch at the end means it - # affects that particular branch. - # We don't care about Forge having branches. - # Therefore we only use the short version part for later identification and filter out the branch-specific - # promotions (among other errors). - print("Processing promotions:") - for promoKey, shortversion in promotions_json.get("promos").items(): - match = promoted_key_expression.match(promoKey) - if not match: - print("Skipping promotion %s, the key did not parse:" % promoKey) - pprint(promoKey) - assert match - if not match.group("mc"): - print( - "Skipping promotion %s, because it has no Minecraft version." % promoKey - ) - continue - if match.group("branch"): - print("Skipping promotion %s, because it on a branch only." % promoKey) - continue - elif match.group("promotion") == "recommended": - recommended_set.add(shortversion) - print("%s added to recommended set" % shortversion) - elif match.group("promotion") == "latest": - pass - else: - assert False - - version_expression = re.compile( - "^(?P[0-9a-zA-Z_\\.]+)-(?P[0-9\\.]+\\.(?P[0-9]+))(-(?P[a-zA-Z0-9\\.]+))?$" - ) - - print("") - print("Processing versions:") - for mc_version, value in main_json.items(): - assert type(mc_version) == str - assert type(value) == list - for long_version in value: - assert type(long_version) == str - match = version_expression.match(long_version) - if not match: - pprint(long_version) - assert match - assert match.group("mc") == mc_version - - files = get_single_forge_files_manifest(long_version) - - build = int(match.group("build")) - version = match.group("ver") - branch = match.group("branch") - - is_recommended = version in recommended_set - - entry = ForgeEntry( - long_version=long_version, - mc_version=mc_version, - version=version, - build=build, - branch=branch, - # NOTE: we add this later after the fact. The forge promotions file lies about these. - latest=False, - recommended=is_recommended, - files=files, - ) - new_index.versions[long_version] = entry - if not new_index.by_mc_version: - new_index.by_mc_version = dict() - if mc_version not in new_index.by_mc_version: - new_index.by_mc_version.setdefault(mc_version, ForgeMCVersionInfo()) - new_index.by_mc_version[mc_version].versions.append(long_version) - # NOTE: we add this later after the fact. The forge promotions file lies about these. - # if entry.latest: - # new_index.by_mc_version[mc_version].latest = long_version - if entry.recommended: - new_index.by_mc_version[mc_version].recommended = long_version - - print("") - print("Post processing promotions and adding missing 'latest':") - for mc_version, info in new_index.by_mc_version.items(): - latest_version = info.versions[-1] - info.latest = latest_version - new_index.versions[latest_version].latest = True - print("Added %s as latest for %s" % (latest_version, mc_version)) - - print("") - print("Dumping index files...") - - with open(UPSTREAM_DIR + "/forge/maven-metadata.json", "w", encoding="utf-8") as f: - json.dump(main_json, f, sort_keys=True, indent=4) - - with open(UPSTREAM_DIR + "/forge/promotions_slim.json", "w", encoding="utf-8") as f: - json.dump(promotions_json, f, sort_keys=True, indent=4) - - new_index.write(UPSTREAM_DIR + "/forge/derived_index.json") - - legacy_info_list = ForgeLegacyInfoList() - - print("Grabbing installers and dumping installer profiles...") - # get the installer jars - if needed - and get the installer profiles out of them - for key, entry in new_index.versions.items(): - eprint("Updating Forge %s" % key) - if entry.mc_version is None: - eprint("Skipping %d with invalid MC version" % entry.build) - continue - - version = ForgeVersion(entry) - if version.url() is None: - eprint("Skipping %d with no valid files" % version.build) - continue - if version.long_version in BAD_VERSIONS: - eprint(f"Skipping bad version {version.long_version}") - continue - - jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) - - if version.uses_installer(): - installer_info_path = ( - UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version - ) - profile_path = ( - UPSTREAM_DIR - + "/forge/installer_manifests/%s.json" % version.long_version - ) - version_file_path = ( - UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version - ) - - installer_refresh_required = not os.path.isfile( - profile_path - ) or not os.path.isfile(installer_info_path) - - if installer_refresh_required: - # grab the installer if it's not there - if not os.path.isfile(jar_path): - eprint("Downloading %s" % version.url()) - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - with open(jar_path, "wb") as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) - - eprint("Processing %s" % version.url()) - # harvestables from the installer - if not os.path.isfile(profile_path): - print(jar_path) - with zipfile.ZipFile(jar_path) as jar: - with suppress(KeyError): - with jar.open("version.json") as profile_zip_entry: - version_data = profile_zip_entry.read() - - # Process: does it parse? - MojangVersion.parse_raw(version_data) - - with open(version_file_path, "wb") as versionJsonFile: - versionJsonFile.write(version_data) - versionJsonFile.close() - - with jar.open("install_profile.json") as profile_zip_entry: - install_profile_data = profile_zip_entry.read() - - # Process: does it parse? - is_parsable = False - exception = None - try: - ForgeInstallerProfile.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - try: - ForgeInstallerProfileV2.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - - if not is_parsable: - if version.is_supported(): - raise exception - else: - eprint( - "Version %s is not supported and won't be generated later." - % version.long_version - ) - - with open(profile_path, "wb") as profileFile: - profileFile.write(install_profile_data) - profileFile.close() - - # installer info v1 - if not os.path.isfile(installer_info_path): - installer_info = InstallerInfo() - installer_info.sha1hash = filehash(jar_path, hashlib.sha1) - installer_info.sha256hash = filehash(jar_path, hashlib.sha256) - installer_info.size = os.path.getsize(jar_path) - installer_info.write(installer_info_path) - else: - # ignore the two versions without install manifests and jar mod class files - # TODO: fix those versions? - if version.mc_version_sane == "1.6.1": - continue - - # only gather legacy info if it's missing - if not os.path.isfile(LEGACYINFO_PATH): - # grab the jar/zip if it's not there - if not os.path.isfile(jar_path): - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - with open(jar_path, "wb") as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) - # find the latest timestamp in the zip file - tstamp = datetime.fromtimestamp(0) - with zipfile.ZipFile(jar_path) as jar: - for info in jar.infolist(): - tstamp_new = datetime(*info.date_time) - if tstamp_new > tstamp: - tstamp = tstamp_new - legacy_info = ForgeLegacyInfo() - legacy_info.release_time = tstamp - legacy_info.sha1 = filehash(jar_path, hashlib.sha1) - legacy_info.sha256 = filehash(jar_path, hashlib.sha256) - legacy_info.size = os.path.getsize(jar_path) - legacy_info_list.number[key] = legacy_info - - # only write legacy info if it's missing - if not os.path.isfile(LEGACYINFO_PATH): - legacy_info_list.write(LEGACYINFO_PATH) - - -if __name__ == "__main__": - main() diff --git a/updateLiteloader.py b/updateLiteloader.py deleted file mode 100755 index 383644754d..0000000000 --- a/updateLiteloader.py +++ /dev/null @@ -1,37 +0,0 @@ -import json -import os - -from meta.common import upstream_path, ensure_upstream_dir, default_session -from meta.common.liteloader import VERSIONS_FILE, BASE_DIR -from meta.model.liteloader import LiteloaderIndex - -UPSTREAM_DIR = upstream_path() - -ensure_upstream_dir(BASE_DIR) - -sess = default_session() - - -def main(): - # get the remote version list - r = sess.get("http://dl.liteloader.com/versions/versions.json") - r.raise_for_status() - - # make sure it's JSON - main_json = r.json() - - # make sure we understand the schema - remote_versions = LiteloaderIndex.parse_obj(main_json) - parsed = remote_versions.json() - original = json.dumps(main_json, sort_keys=True, indent=4) - assert parsed == original - - print("Successfully parsed index") - print(f"Last updated {remote_versions.meta.updated}") - - # save the json it to file - remote_versions.write(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) - - -if __name__ == "__main__": - main() diff --git a/updateMojang.py b/updateMojang.py deleted file mode 100755 index 8d3a2296e0..0000000000 --- a/updateMojang.py +++ /dev/null @@ -1,165 +0,0 @@ -import json -import os -import zipfile - -from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session -from meta.common.http import download_binary_file -from meta.common.mojang import ( - BASE_DIR, - VERSION_MANIFEST_FILE, - VERSIONS_DIR, - ASSETS_DIR, - STATIC_EXPERIMENTS_FILE, - STATIC_OLD_SNAPSHOTS_FILE, -) -from meta.model.mojang import ( - MojangIndexWrap, - MojangIndex, - ExperimentIndex, - ExperimentIndexWrap, - OldSnapshotIndexWrap, - OldSnapshotIndex, -) - -UPSTREAM_DIR = upstream_path() -STATIC_DIR = static_path() - -ensure_upstream_dir(BASE_DIR) -ensure_upstream_dir(VERSIONS_DIR) -ensure_upstream_dir(ASSETS_DIR) - -sess = default_session() - - -def fetch_zipped_version(path, url): - zip_path = f"{path}.zip" - download_binary_file(sess, zip_path, url) - with zipfile.ZipFile(zip_path) as z: - for info in z.infolist(): - if info.filename.endswith(".json"): - print(f"Found {info.filename} as version json") - version_json = json.load(z.open(info)) - break - - assert version_json - - with open(path, "w", encoding="utf-8") as f: - json.dump(version_json, f, sort_keys=True, indent=4) - - return version_json - - -def fetch_modified_version(path, version): - r = sess.get(version.url) - r.raise_for_status() - version_json = r.json() - - version_json["releaseTime"] = version_json["releaseTime"] + "T00:00:00+02:00" - version_json["time"] = version_json["releaseTime"] - - downloads = { - "client": {"url": version.jar, "sha1": version.sha1, "size": version.size} - } - - version_json["downloads"] = downloads - version_json["type"] = "old_snapshot" - - with open(path, "w", encoding="utf-8") as f: - json.dump(version_json, f, sort_keys=True, indent=4) - - return version_json - - -def fetch_version(path, url): - r = sess.get(url) - r.raise_for_status() - version_json = r.json() - - with open(path, "w", encoding="utf-8") as f: - json.dump(version_json, f, sort_keys=True, indent=4) - - return version_json - - -def main(): - # get the remote version list - r = sess.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json") - r.raise_for_status() - - remote_versions = MojangIndexWrap(MojangIndex(**r.json())) - remote_ids = set(remote_versions.versions.keys()) - - version_manifest_path = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE) - - if os.path.exists(version_manifest_path): - # get the local version list - current_versions = MojangIndexWrap( - MojangIndex.parse_file(version_manifest_path) - ) - local_ids = set(current_versions.versions.keys()) - - # versions not present locally but present remotely are new - pending_ids = remote_ids.difference(local_ids) - - for x in local_ids: - remote_version = remote_versions.versions[x] - local_version = current_versions.versions[x] - if remote_version.time > local_version.time: - pending_ids.add(x) - else: - pending_ids = remote_ids - - for x in pending_ids: - version = remote_versions.versions[x] - 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) - if os.path.exists(static_experiments_path): - experiments = ExperimentIndexWrap( - ExperimentIndex.parse_file(static_experiments_path) - ) - experiment_ids = set(experiments.versions.keys()) - - for x in experiment_ids: - version = experiments.versions[x] - experiment_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") - - print("Updating experiment " + version.id) - if not os.path.isfile(experiment_path): - fetch_zipped_version(experiment_path, version.url) - else: - print("Already have experiment " + version.id) - - static_old_snapshots_path = os.path.join(STATIC_DIR, STATIC_OLD_SNAPSHOTS_FILE) - - # deal with old snapshots - if os.path.exists(static_old_snapshots_path): - old_snapshots = OldSnapshotIndexWrap( - OldSnapshotIndex.parse_file(static_old_snapshots_path) - ) - old_snapshots_ids = set(old_snapshots.versions.keys()) - - for x in old_snapshots_ids: - version = old_snapshots.versions[x] - old_snapshots_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") - - print("Updating old snapshot " + version.id) - if not os.path.isfile(old_snapshots_path): - fetch_modified_version(old_snapshots_path, version) - else: - print("Already have old snapshot " + version.id) - - remote_versions.index.write(version_manifest_path) - - -if __name__ == "__main__": - main() diff --git a/updateNeoForge.py b/updateNeoForge.py deleted file mode 100644 index 1db5b43a05..0000000000 --- a/updateNeoForge.py +++ /dev/null @@ -1,319 +0,0 @@ -""" - Get the source files necessary for generating Forge versions -""" -import copy -import hashlib -import json -import os -import re -import sys -import zipfile -from contextlib import suppress -from datetime import datetime -from pathlib import Path -from pprint import pprint -import urllib.parse - -from pydantic import ValidationError - -from meta.common import upstream_path, ensure_upstream_dir, static_path, default_session -from meta.common.neoforge import ( - JARS_DIR, - INSTALLER_INFO_DIR, - INSTALLER_MANIFEST_DIR, - VERSION_MANIFEST_DIR, - FILE_MANIFEST_DIR, -) -from meta.model.neoforge import ( - NeoForgeFile, - NeoForgeEntry, - NeoForgeMCVersionInfo, - DerivedNeoForgeIndex, - NeoForgeVersion, - NeoForgeInstallerProfileV2, - InstallerInfo, -) -from meta.model.mojang import MojangVersion - -UPSTREAM_DIR = upstream_path() -STATIC_DIR = static_path() - -ensure_upstream_dir(JARS_DIR) -ensure_upstream_dir(INSTALLER_INFO_DIR) -ensure_upstream_dir(INSTALLER_MANIFEST_DIR) -ensure_upstream_dir(VERSION_MANIFEST_DIR) -ensure_upstream_dir(FILE_MANIFEST_DIR) - -sess = default_session() - - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - -def filehash(filename, hashtype, blocksize=65536): - hashtype = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - hashtype.update(block) - return hashtype.hexdigest() - - -def find_nth(haystack, needle, n): - start = haystack.find(needle) - while start >= 0 and n > 1: - start = haystack.find(needle, start + len(needle)) - n -= 1 - return start - - -def get_single_forge_files_manifest(longversion, artifact: str): - print(f"Getting NeoForge manifest for {longversion}") - path_thing = UPSTREAM_DIR + "/neoforge/files_manifests/%s.json" % longversion - files_manifest_file = Path(path_thing) - from_file = False - if files_manifest_file.is_file(): - with open(path_thing, "r") as f: - files_json = json.load(f) - from_file = True - else: - file_url = ( - f"https://maven.neoforged.net/api/maven/details/releases/net%2Fneoforged%2F{artifact}%2F" - + urllib.parse.quote(longversion) - ) - r = sess.get(file_url) - r.raise_for_status() - files_json = r.json() - - ret_dict = dict() - - for file in files_json.get("files"): - assert type(file) == dict - name = file["name"] - prefix = f"{artifact}-{longversion}" - assert name.startswith( - prefix - ), f"{longversion} classifier {name} doesn't start with {prefix}" - file_name = name[len(prefix) :] - if file_name.startswith("-"): - file_name = file_name[1:] - if file_name.startswith("."): - continue - - classifier, ext = os.path.splitext(file_name) - - if ext in [".md5", ".sha1", ".sha256", ".sha512"]: - continue - - # assert len(extensionObj.items()) == 1 - file_obj = NeoForgeFile( - artifact=artifact, classifier=classifier, extension=ext[1:] - ) - ret_dict[classifier] = file_obj - - if not from_file: - Path(path_thing).parent.mkdir(parents=True, exist_ok=True) - with open(path_thing, "w", encoding="utf-8") as f: - json.dump(files_json, f, sort_keys=True, indent=4) - - return ret_dict - - -def main(): - # get the remote version list fragments - r = sess.get( - "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fforge" - ) - r.raise_for_status() - main_json = r.json()["versions"] - assert type(main_json) == list - - # get the new remote version list fragments - r = sess.get( - "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fneoforge" - ) - r.raise_for_status() - new_main_json = r.json()["versions"] - assert type(new_main_json) == list - - main_json += new_main_json - - new_index = DerivedNeoForgeIndex() - - version_expression = re.compile( - r"^(?P[0-9a-zA-Z_\.]+)-(?P[0-9\.]+\.(?P[0-9]+))(-(?P[a-zA-Z0-9\.]+))?$" - ) - neoforge_version_re = re.compile( - r"^(?P\d+).(?P\d+).(?P\d+)(?:-(?P\w+))?$" - ) - - print("") - print("Processing versions:") - for long_version in main_json: - assert type(long_version) == str - - match = version_expression.match(long_version) - if match: - mc_version = match.group("mc") - build = int(match.group("build")) - version = match.group("ver") - branch = match.group("branch") - artifact = "forge" - - match_nf = neoforge_version_re.match(long_version) - if match_nf: - mc_version = f"1.{match_nf.group('mcminor')}.{match_nf.group('mcpatch')}" - build = int(match_nf.group("number")) - version = match_nf.group("number") - branch = match_nf.group("tag") - match = match_nf - artifact = "neoforge" - - assert match, f"{long_version} doesn't match version regex" - try: - files = get_single_forge_files_manifest(long_version, artifact) - except: - continue - - # TODO: what *is* recommended? - is_recommended = False - - entry = NeoForgeEntry( - artifact=artifact, - long_version=long_version, - mc_version=mc_version, - version=version, - build=build, - branch=branch, - # NOTE: we add this later after the fact. The forge promotions file lies about these. - latest=False, - recommended=is_recommended, - files=files, - ) - new_index.versions[long_version] = entry - if not new_index.by_mc_version: - new_index.by_mc_version = dict() - if mc_version not in new_index.by_mc_version: - new_index.by_mc_version.setdefault(mc_version, NeoForgeMCVersionInfo()) - new_index.by_mc_version[mc_version].versions.append(long_version) - # NOTE: we add this later after the fact. The forge promotions file lies about these. - # if entry.latest: - # new_index.by_mc_version[mc_version].latest = long_version - if entry.recommended: - new_index.by_mc_version[mc_version].recommended = long_version - - print("") - print("Dumping index files...") - - with open( - UPSTREAM_DIR + "/neoforge/maven-metadata.json", "w", encoding="utf-8" - ) as f: - json.dump(main_json, f, sort_keys=True, indent=4) - - new_index.write(UPSTREAM_DIR + "/neoforge/derived_index.json") - - print("Grabbing installers and dumping installer profiles...") - # get the installer jars - if needed - and get the installer profiles out of them - for key, entry in new_index.versions.items(): - eprint("Updating NeoForge %s" % key) - if entry.mc_version is None: - eprint("Skipping %d with invalid MC version" % entry.build) - continue - - version = NeoForgeVersion(entry) - if version.url() is None: - eprint("Skipping %d with no valid files" % version.build) - continue - if not version.uses_installer(): - eprint(f"version {version.long_version} does not use installer") - continue - - jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) - - installer_info_path = ( - UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version - ) - profile_path = ( - UPSTREAM_DIR - + "/neoforge/installer_manifests/%s.json" % version.long_version - ) - version_file_path = ( - UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version - ) - - installer_refresh_required = not os.path.isfile( - profile_path - ) or not os.path.isfile(installer_info_path) - - if installer_refresh_required: - # grab the installer if it's not there - if not os.path.isfile(jar_path): - eprint("Downloading %s" % version.url()) - try: - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - Path(jar_path).parent.mkdir(parents=True, exist_ok=True) - with open(jar_path, "wb") as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) - except Exception as e: - eprint("Failed to download %s" % version.url()) - eprint("Error is %s" % e) - continue - - eprint("Processing %s" % version.url()) - # harvestables from the installer - if not os.path.isfile(profile_path): - print(jar_path) - with zipfile.ZipFile(jar_path) as jar: - with suppress(KeyError): - with jar.open("version.json") as profile_zip_entry: - version_data = profile_zip_entry.read() - - # Process: does it parse? - MojangVersion.parse_raw(version_data) - - Path(version_file_path).parent.mkdir( - parents=True, exist_ok=True - ) - with open(version_file_path, "wb") as versionJsonFile: - versionJsonFile.write(version_data) - versionJsonFile.close() - - with jar.open("install_profile.json") as profile_zip_entry: - install_profile_data = profile_zip_entry.read() - - # Process: does it parse? - is_parsable = False - exception = None - try: - NeoForgeInstallerProfileV2.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - - if not is_parsable: - if version.is_supported(): - raise exception - else: - eprint( - "Version %s is not supported and won't be generated later." - % version.long_version - ) - - Path(profile_path).parent.mkdir(parents=True, exist_ok=True) - with open(profile_path, "wb") as profileFile: - profileFile.write(install_profile_data) - profileFile.close() - - # installer info v1 - if not os.path.isfile(installer_info_path): - installer_info = InstallerInfo() - installer_info.sha1hash = filehash(jar_path, hashlib.sha1) - installer_info.sha256hash = filehash(jar_path, hashlib.sha256) - installer_info.size = os.path.getsize(jar_path) - installer_info.write(installer_info_path) - - -if __name__ == "__main__": - main() diff --git a/updateQuilt.py b/updateQuilt.py deleted file mode 100755 index 5eaa8ed0d0..0000000000 --- a/updateQuilt.py +++ /dev/null @@ -1,122 +0,0 @@ -import json -import os -import zipfile -from datetime import datetime - -import requests - -from meta.common import ( - upstream_path, - ensure_upstream_dir, - transform_maven_key, - default_session, -) -from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, USE_QUILT_MAPPINGS -from meta.common.fabric import DATETIME_FORMAT_HTTP -from meta.model.fabric import FabricJarInfo - -UPSTREAM_DIR = upstream_path() - -ensure_upstream_dir(JARS_DIR) -ensure_upstream_dir(INSTALLER_INFO_DIR) -ensure_upstream_dir(META_DIR) - -sess = default_session() - - -def filehash(filename, hashtype, blocksize=65536): - h = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - h.update(block) - return h.hexdigest() - - -def get_maven_url(maven_key, server, ext): - parts = maven_key.split(":", 3) - maven_ver_url = ( - server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" - ) - maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext - return maven_url - - -def get_json_file(path, url): - with open(path, "w", encoding="utf-8") as f: - r = sess.get(url) - r.raise_for_status() - print(f"QUILT DEBUG {r.headers}") - version_json = r.json() - json.dump(version_json, f, sort_keys=True, indent=4) - return version_json - - -def head_file(url): - r = sess.head(url) - r.raise_for_status() - return r.headers - - -def get_binary_file(path, url): - with open(path, "wb") as f: - r = sess.get(url) - r.raise_for_status() - for chunk in r.iter_content(chunk_size=128): - f.write(chunk) - - -def compute_jar_file(path, url): - # NOTE: Quilt Meta does not make any guarantees about Last-Modified. - # Always download the JAR file instead - jar_path = path + ".jar" - get_binary_file(jar_path, url) - tstamp = datetime.fromtimestamp(0) - with zipfile.ZipFile(jar_path) as jar: - allinfo = jar.infolist() - for info in allinfo: - tstamp_new = datetime(*info.date_time) - if tstamp_new > tstamp: - tstamp = tstamp_new - - data = FabricJarInfo(release_time=tstamp) - data.write(path + ".json") - - -def main(): - # get the version list for each component we are interested in - components = ["loader"] - if USE_QUILT_MAPPINGS: - components.append("hashed") - for component in components: - index = get_json_file( - os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), - "https://meta.quiltmc.org/v3/versions/" + component, - ) - for it in index: - print(f"Processing {component} {it['version']} ") - jar_maven_url = get_maven_url( - it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar" - ) - compute_jar_file( - os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), - jar_maven_url, - ) - - # for each loader, download installer JSON file from maven - with open( - os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" - ) as loaderVersionIndexFile: - loader_version_index = json.load(loaderVersionIndexFile) - for it in loader_version_index: - print(f"Downloading JAR info for loader {it['version']} ") - maven_url = get_maven_url( - it["maven"], "https://maven.quiltmc.org/repository/release/", ".json" - ) - get_json_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), - maven_url, - ) - - -if __name__ == "__main__": - main() -- cgit 0.0.5-2-1-g0f52 From 2a598736f094cdfcfaecb4a29678412f6e47c983 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 27 Apr 2024 22:12:01 +0300 Subject: Renamed old_sanpshots Signed-off-by: Trial97 --- meta/run/update_mojang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/run/update_mojang.py b/meta/run/update_mojang.py index 52921f3e8a..130fecf1d5 100755 --- a/meta/run/update_mojang.py +++ b/meta/run/update_mojang.py @@ -61,7 +61,7 @@ def fetch_modified_version(path, version): } version_json["downloads"] = downloads - version_json["type"] = "old_snapshot" + version_json["type"] = "snapshot" with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) -- cgit 0.0.5-2-1-g0f52 From a19055bebbf2f39e94b5a0a7df0403b6775bee53 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 29 Apr 2024 19:07:47 +0300 Subject: completely remove old_ prefix Signed-off-by: Trial97 --- meta/run/update_mojang.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/run/update_mojang.py b/meta/run/update_mojang.py index 130fecf1d5..97f497564f 100755 --- a/meta/run/update_mojang.py +++ b/meta/run/update_mojang.py @@ -41,6 +41,7 @@ def fetch_zipped_version(path, url): break assert version_json + version_json["type"] = version_json["type"].removeprefix("old_") with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) @@ -61,7 +62,7 @@ def fetch_modified_version(path, version): } version_json["downloads"] = downloads - version_json["type"] = "snapshot" + version_json["type"] = version_json["type"].removeprefix("old_") with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) @@ -74,6 +75,7 @@ def fetch_version(path, url): r.raise_for_status() version_json = r.json() + version_json["type"] = version_json["type"].removeprefix("old_") with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) -- cgit 0.0.5-2-1-g0f52 From ae40a7e5ce95e42d86df3f25114a3c29b6fa368f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 29 Apr 2024 22:28:01 +0200 Subject: chore: fix 1_16_combat-4 Signed-off-by: Sefa Eyeoglu --- meta/common/mojang-minecraft-experiments.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/common/mojang-minecraft-experiments.json b/meta/common/mojang-minecraft-experiments.json index 94b50c1a60..02572c78c7 100644 --- a/meta/common/mojang-minecraft-experiments.json +++ b/meta/common/mojang-minecraft-experiments.json @@ -53,7 +53,7 @@ { "id": "1_16_combat-4", "wiki": "https://minecraft.wiki/w/Java_Edition_Combat_Test_8", - "url": "https://cdn.discordapp.com/attachments/369990015096455168/947864881028272198/1_16_combat-4.zip" + "url": "https://archive.org/download/1-16-combat-4_202404/1_16_combat-4.zip" }, { "id": "1_16_combat-3", @@ -101,4 +101,4 @@ "url": "https://launcher.mojang.com/experiments/combat/610f5c9874ba8926d5ae1bcce647e5f0e6e7c889/1_14_combat-212796.zip" } ] -} \ No newline at end of file +} -- cgit 0.0.5-2-1-g0f52 From 804c9a5ea57d9d4b5aab0e349a795ddb0d67fb96 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 30 Apr 2024 15:02:15 +0300 Subject: Revert back #43 temporary Signed-off-by: Trial97 --- meta/run/update_mojang.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/run/update_mojang.py b/meta/run/update_mojang.py index 97f497564f..52921f3e8a 100755 --- a/meta/run/update_mojang.py +++ b/meta/run/update_mojang.py @@ -41,7 +41,6 @@ def fetch_zipped_version(path, url): break assert version_json - version_json["type"] = version_json["type"].removeprefix("old_") with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) @@ -62,7 +61,7 @@ def fetch_modified_version(path, version): } version_json["downloads"] = downloads - version_json["type"] = version_json["type"].removeprefix("old_") + version_json["type"] = "old_snapshot" with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) @@ -75,7 +74,6 @@ def fetch_version(path, url): r.raise_for_status() version_json = r.json() - version_json["type"] = version_json["type"].removeprefix("old_") with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) -- cgit 0.0.5-2-1-g0f52 From 60a3f5f194974399cb1fb20b5414c7ddcaa69419 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 9 May 2024 10:03:00 +0300 Subject: Map alpha and beta to gamma in case of arm os Signed-off-by: Trial97 --- meta/run/generate_java.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'meta') diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index 95803f21f1..110d871d86 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -327,6 +327,15 @@ def main(): if comp == MojangJavaComponent.Exe: continue # doesn't appear to be used and not marked with a full verison so I don't trust it mojang_runtimes = mojang_java_manifest[mojang_os_name][comp] + if ( + len(mojang_runtimes) == 0 + and mojang_os_name + in [MojangJavaOsName.WindowsArm64, MojangJavaOsName.MacOSArm64] + and comp in [MojangJavaComponent.Alpha, MojangJavaComponent.Beta] + ): + mojang_runtimes = mojang_java_manifest[mojang_os_name][ + MojangJavaComponent.Gamma + ] for mojang_runtime in mojang_runtimes: if comp == MojangJavaComponent.JreLegacy: major = 8 -- cgit 0.0.5-2-1-g0f52 From adef8d673c93b5a1fdfcffa05aeb01af94f466d8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 10 May 2024 23:58:50 +0300 Subject: Mapped linux-arm variants to mojang provider Signed-off-by: Trial97 --- meta/run/generate_java.py | 181 +++++++++++++++++++++++++++++++--------------- 1 file changed, 123 insertions(+), 58 deletions(-) (limited to 'meta') diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index 110d871d86..fd32308217 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -123,6 +123,26 @@ def mojang_os_to_java_os(mojang_os: MojangJavaOsName) -> JavaRuntimeOS: return JavaRuntimeOS.Unknown +def mojang_component_to_major(mojang_component: MojangJavaComponent) -> int: + match mojang_component: + case MojangJavaComponent.JreLegacy: + return 8 + case MojangJavaComponent.Alpha: + return 17 + case MojangJavaComponent.Beta: + return 17 + case MojangJavaComponent.Gamma: + return 17 + case MojangJavaComponent.GammaSnapshot: + return 17 + case MojangJavaComponent.Exe: + return 0 + case MojangJavaComponent.Delta: + return 21 + case _: + return 0 + + def mojang_runtime_to_java_runtime( mojang_runtime: MojangJavaRuntime, mojang_component: MojangJavaComponent, @@ -240,34 +260,6 @@ def azul_package_to_java_runtime( ) -PREFERED_VENDOR_ORDER = ["mojang", "eclipse", "azul"] - -__PREFERED_VENDOR_ORDER = list(reversed(PREFERED_VENDOR_ORDER)) - - -def vendor_priority(vendor: str) -> int: - """Get a numeric priority for a given vendor - - Args: - vendor (str): the vendor to check - - Returns: - int: how preferable the vendor is, the higher the better - """ - if vendor not in PREFERED_VENDOR_ORDER: - return -1 - return __PREFERED_VENDOR_ORDER.index(vendor) - - -def pkg_type_priority(pkg_type: JavaPackageType) -> int: - match pkg_type: - case JavaPackageType.Jre: - return 2 - case JavaPackageType.Jdk: - return 1 - return -1 - - def writeJavas(javas: dict[int, list[JavaRuntimeMeta]], uid: str): def oldest_timestamp(a: datetime.datetime | None, b: datetime.datetime): if a is None or a > b: @@ -308,6 +300,7 @@ def writeJavas(javas: dict[int, list[JavaRuntimeMeta]], uid: str): def main(): javas: dict[int, list[JavaRuntimeMeta]] = {} + extra_mojang_javas: dict[int, list[JavaRuntimeMeta]] = {} def add_java_runtime(runtime: JavaRuntimeMeta, major: int): if major not in javas: @@ -315,37 +308,27 @@ def main(): print(f"Regestering runtime: {runtime.name} for Java {major}") javas[major].append(runtime) - print("Processing Mojang Javas") - mojang_java_manifest = JavaIndex.parse_file( - os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) - ) - for mojang_os_name in mojang_java_manifest: - if mojang_os_name == MojangJavaOsName.Gamecore: - continue # empty - java_os = mojang_os_to_java_os(mojang_os_name) - for comp in mojang_java_manifest[mojang_os_name]: - if comp == MojangJavaComponent.Exe: - continue # doesn't appear to be used and not marked with a full verison so I don't trust it - mojang_runtimes = mojang_java_manifest[mojang_os_name][comp] - if ( - len(mojang_runtimes) == 0 - and mojang_os_name - in [MojangJavaOsName.WindowsArm64, MojangJavaOsName.MacOSArm64] - and comp in [MojangJavaComponent.Alpha, MojangJavaComponent.Beta] - ): - mojang_runtimes = mojang_java_manifest[mojang_os_name][ - MojangJavaComponent.Gamma + # only add specific versions to the list + if ( + ( + runtime.runtime_os + in [JavaRuntimeOS.MacOsArm64, JavaRuntimeOS.WindowsArm64] + and major == 8 + ) + or ( + runtime.runtime_os + in [ + JavaRuntimeOS.WindowsArm32, + JavaRuntimeOS.LinuxArm32, + JavaRuntimeOS.LinuxArm64, ] - for mojang_runtime in mojang_runtimes: - if comp == MojangJavaComponent.JreLegacy: - major = 8 - else: - major = int(mojang_runtime.version.name.partition(".")[0]) - runtime = mojang_runtime_to_java_runtime(mojang_runtime, comp, java_os) - add_java_runtime(runtime, major) - - writeJavas(javas=javas, uid=JAVA_MINECRAFT_COMPONENT) - javas = {} + and major in [8, 17, 21] + ) + or (runtime.runtime_os == JavaRuntimeOS.LinuxX86 and major in [17, 21]) + ): + if major not in extra_mojang_javas: + extra_mojang_javas[major] = list[JavaRuntimeMeta]() + extra_mojang_javas[major].append(runtime) print("Processing Adoptium Releases") adoptium_path = os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") @@ -411,6 +394,88 @@ def main(): writeJavas(javas=javas, uid=JAVA_AZUL_COMPONENT) javas = {} + # constructs the missing mojang javas based on adoptium or azul + def get_mojang_extra_java( + mojang_component: MojangJavaComponent, java_os: JavaRuntimeOS + ) -> JavaRuntimeMeta | None: + java_major = mojang_component_to_major(mojang_component) + if not java_major in extra_mojang_javas: + return None + posible_javas = list( + filter(lambda x: x.runtime_os == java_os, extra_mojang_javas[java_major]) + ) + if len(posible_javas) == 0: + return None + prefered_vendor = list(filter(lambda x: x.vendor != "azul", posible_javas)) + if len(prefered_vendor) == 0: + prefered_vendor = posible_javas + prefered_vendor.sort(key=lambda x: x.version, reverse=True) + runtime = prefered_vendor[0] + runtime.name = mojang_component + return runtime + + print("Processing Mojang Javas") + mojang_java_manifest = JavaIndex.parse_file( + os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) + ) + for mojang_os_name in mojang_java_manifest: + if mojang_os_name == MojangJavaOsName.Gamecore: + continue # empty + java_os = mojang_os_to_java_os(mojang_os_name) + for comp in mojang_java_manifest[mojang_os_name]: + if comp == MojangJavaComponent.Exe: + continue # doesn't appear to be used and not marked with a full verison so I don't trust it + mojang_runtimes = mojang_java_manifest[mojang_os_name][comp] + if len(mojang_runtimes) == 0: + if mojang_os_name in [ + MojangJavaOsName.WindowsArm64, + MojangJavaOsName.MacOSArm64, + ]: + if comp in [MojangJavaComponent.Alpha, MojangJavaComponent.Beta]: + mojang_runtimes = mojang_java_manifest[mojang_os_name][ + MojangJavaComponent.Gamma + ] + elif ( + comp == MojangJavaComponent.JreLegacy + ): # arm version of win and mac is missing the legacy java + runtime = get_mojang_extra_java(comp, java_os) + if runtime != None: + add_java_runtime(runtime, mojang_component_to_major(comp)) + if ( + mojang_os_name == MojangJavaOsName.Linuxi386 + and comp != MojangJavaComponent.JreLegacy + ): # the linux x86 is missing all but legacy + runtime = get_mojang_extra_java(comp, java_os) + if runtime != None: + add_java_runtime(runtime, mojang_component_to_major(comp)) + for mojang_runtime in mojang_runtimes: + if comp == MojangJavaComponent.JreLegacy: + major = 8 + else: + major = int(mojang_runtime.version.name.partition(".")[0]) + runtime = mojang_runtime_to_java_runtime(mojang_runtime, comp, java_os) + add_java_runtime(runtime, major) + # mojang doesn't provide any versions for the following systems so borrow info from adoptium/azul + for java_os in [ + JavaRuntimeOS.WindowsArm32, + JavaRuntimeOS.LinuxArm32, + JavaRuntimeOS.LinuxArm64, + ]: + for comp in [ + MojangJavaComponent.JreLegacy, + MojangJavaComponent.Alpha, + MojangJavaComponent.Beta, + MojangJavaComponent.Gamma, + MojangJavaComponent.GammaSnapshot, + MojangJavaComponent.Delta, + ]: + runtime = get_mojang_extra_java(comp, java_os) + if runtime != None: + add_java_runtime(runtime, mojang_component_to_major(comp)) + + writeJavas(javas=javas, uid=JAVA_MINECRAFT_COMPONENT) + javas = {} + if __name__ == "__main__": main() -- cgit 0.0.5-2-1-g0f52 From 06d0390e79161e5da815159cf20237b018278850 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 29 May 2024 17:33:11 +0200 Subject: fix: add new LWJGL variant Signed-off-by: Sefa Eyeoglu --- meta/common/mojang-library-patches.json | 15 +++++++++++++++ meta/run/generate_mojang.py | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index 74d4d26c4b..7ea3be266c 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -2875,5 +2875,20 @@ }, "name": "org.lwjgl:lwjgl-glfw-natives-linux:3.3.2-lwjgl.1" } + }, + { + "match": [ + "org.lwjgl:lwjgl-freetype-natives-macos-patch:3.3.3" + ], + "override": { + "rules": [ + { + "action": "allow", + "os": { + "name": "osx" + } + } + ] + } } ] diff --git a/meta/run/generate_mojang.py b/meta/run/generate_mojang.py index e0068c24ec..9631a6c240 100755 --- a/meta/run/generate_mojang.py +++ b/meta/run/generate_mojang.py @@ -90,8 +90,7 @@ LOG4J_HASHES = { # We want versions that contain natives for all platforms. If there are multiple, pick the latest one # LWJGL versions we want PASS_VARIANTS = [ - # TODO: needs arm64 for Linux? - "8a9b08f11271eb4de3b50e5d069949500b2c7bc1", # 3.3.3 (2024-04-03 11:49:39+00:00) + "6f32ef730d05562ede7db0b845b72ea16dd239d5", # 3.3.3 (2024-05-29 12:04:43+00:00) "765b4ab443051d286bdbb1c19cd7dc86b0792dce", # 3.3.2 (2024-01-17 13:19:20+00:00) "54c4fb1d6a96ac3007c947bf310c8bcf94a862be", # 3.3.1 (2023-04-20 11:55:19+00:00) split natives, with WoA natives "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) will be patched, missing tinyfd @@ -107,6 +106,7 @@ PASS_VARIANTS = [ # LWJGL versions we def. don't want! BAD_VARIANTS = [ + "8a9b08f11271eb4de3b50e5d069949500b2c7bc1", # 3.3.3 (2024-04-03 11:49:39+00:00) seems to have a broken libfreetype for macOS x86_64 "79bde9e46e9ad9accebda11e8293ed08d80dbdc3", # 3.3.2 (2023-08-30 11:24:35+00:00) does not have lwjgl-freetype "8836c419f90f69a278b97d945a34af165c24ff60", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, with workaround, replaced by 23w26a "3c624b94c06dbc4abae08fe6156d74abe4a2cca5", # 3.3.1 (2022-05-04 14:41:35+00:00) we already have a nice 3.3.1 -- cgit 0.0.5-2-1-g0f52 From b9a98bc2439296f96fb2e766e7a66be989d24585 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 5 Jun 2024 14:01:51 +0200 Subject: fix: add new LWJGL variant with fixed os rules Signed-off-by: Sefa Eyeoglu --- meta/common/mojang-library-patches.json | 15 --------------- meta/run/generate_mojang.py | 3 ++- 2 files changed, 2 insertions(+), 16 deletions(-) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index 7ea3be266c..74d4d26c4b 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -2875,20 +2875,5 @@ }, "name": "org.lwjgl:lwjgl-glfw-natives-linux:3.3.2-lwjgl.1" } - }, - { - "match": [ - "org.lwjgl:lwjgl-freetype-natives-macos-patch:3.3.3" - ], - "override": { - "rules": [ - { - "action": "allow", - "os": { - "name": "osx" - } - } - ] - } } ] diff --git a/meta/run/generate_mojang.py b/meta/run/generate_mojang.py index 9631a6c240..6a0d0d9b9e 100755 --- a/meta/run/generate_mojang.py +++ b/meta/run/generate_mojang.py @@ -90,7 +90,7 @@ LOG4J_HASHES = { # We want versions that contain natives for all platforms. If there are multiple, pick the latest one # LWJGL versions we want PASS_VARIANTS = [ - "6f32ef730d05562ede7db0b845b72ea16dd239d5", # 3.3.3 (2024-05-29 12:04:43+00:00) + "73974b3af2afeb5b272ffbadcd7963014387c84f", # 3.3.3 (2024-05-22 16:25:41+00:00) "765b4ab443051d286bdbb1c19cd7dc86b0792dce", # 3.3.2 (2024-01-17 13:19:20+00:00) "54c4fb1d6a96ac3007c947bf310c8bcf94a862be", # 3.3.1 (2023-04-20 11:55:19+00:00) split natives, with WoA natives "ea4973ebc9eadf059f30f0958c89f330898bff51", # 3.2.2 (2019-07-04 14:41:05+00:00) will be patched, missing tinyfd @@ -106,6 +106,7 @@ PASS_VARIANTS = [ # LWJGL versions we def. don't want! BAD_VARIANTS = [ + "6f32ef730d05562ede7db0b845b72ea16dd239d5", # 3.3.3 (2024-05-29 12:04:43+00:00) missing os rule for freetype natives-macos-patch "8a9b08f11271eb4de3b50e5d069949500b2c7bc1", # 3.3.3 (2024-04-03 11:49:39+00:00) seems to have a broken libfreetype for macOS x86_64 "79bde9e46e9ad9accebda11e8293ed08d80dbdc3", # 3.3.2 (2023-08-30 11:24:35+00:00) does not have lwjgl-freetype "8836c419f90f69a278b97d945a34af165c24ff60", # 3.3.1 (2022-05-18 13:51:54+00:00) split natives, with workaround, replaced by 23w26a -- cgit 0.0.5-2-1-g0f52 From e233614c5414272409f523b9c3506f828a957fd9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 13 Jun 2024 19:00:41 +0300 Subject: remove jdk Signed-off-by: Trial97 --- meta/run/update_java.py | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'meta') diff --git a/meta/run/update_java.py b/meta/run/update_java.py index dc9e159be3..b77bb1df37 100644 --- a/meta/run/update_java.py +++ b/meta/run/update_java.py @@ -23,6 +23,7 @@ from meta.model.java import ( AzulArchiveType, AzulReleaseStatus, AzulAvailabilityType, + AzulJavaPackageType, azulApiPackageDetailUrl, ZuluPackageDetail, ZuluPackagesDetail, @@ -78,26 +79,6 @@ def main(): break page += 1 - page = 0 - while True: - query = AdoptiumAPIFeatureReleasesQuery( - image_type=AdoptiumImageType.Jdk, page_size=page_size, page=page - ) - api_call = adoptiumAPIFeatureReleasesUrl(feature, query=query) - print("Fetching JDK Page:", page, api_call) - r_rls = sess.get(api_call) - if r_rls.status_code == 404: - break - else: - r_rls.raise_for_status() - - releases = list(AdoptiumRelease(**rls) for rls in r_rls.json()) - releases_for_feature.extend(releases) - - if len(r_rls.json()) < page_size: - break - page += 1 - print("Total Adoptium releases for feature:", len(releases_for_feature)) releases = AdoptiumReleases(__root__=releases_for_feature) feature_file = os.path.join( @@ -115,6 +96,7 @@ def main(): archive_type=AzulArchiveType.Zip, release_status=AzulReleaseStatus.Ga, availability_types=[AzulAvailabilityType.CA], + java_package_type=AzulJavaPackageType.Jre, javafx_bundled=False, page=page, page_size=page_size, -- cgit 0.0.5-2-1-g0f52 From bd3030419a2028285de1f31d984bc7ed4ee3c46c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 13 Jun 2024 18:08:13 +0200 Subject: Concurrency (#57) Co-authored-by: bloodnighttw --- meta/run/update_fabric.py | 45 ++++++++++++++++++++++++----------------- meta/run/update_mojang.py | 49 ++++++++++++++++++++++++++------------------- meta/run/update_quilt.py | 51 ++++++++++++++++++++++++++++------------------- 3 files changed, 86 insertions(+), 59 deletions(-) (limited to 'meta') diff --git a/meta/run/update_fabric.py b/meta/run/update_fabric.py index 132495b92c..850ec8eac1 100755 --- a/meta/run/update_fabric.py +++ b/meta/run/update_fabric.py @@ -1,3 +1,4 @@ +import concurrent.futures import json import os import zipfile @@ -93,6 +94,26 @@ def compute_jar_file(path, url): data.write(path + ".json") +def compute_jar_file_concurrent(component, it): + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) + print(f"Processing {component} {it['version']} Done") + + +def get_json_file_concurrent(it): + print(f"Downloading JAR info for loader {it['version']} ") + maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) + print(f"Downloading JAR info for loader {it['version']} Done") + + def main(): # get the version list for each component we are interested in for component in ["intermediary", "loader"]: @@ -100,30 +121,18 @@ def main(): os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), "https://meta.fabricmc.net/v2/versions/" + component, ) - for it in index: - print(f"Processing {component} {it['version']} ") - jar_maven_url = get_maven_url( - it["maven"], "https://maven.fabricmc.net/", ".jar" - ) - compute_jar_file( - os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), - jar_maven_url, - ) + with concurrent.futures.ThreadPoolExecutor() as executor: + for it in index: + executor.submit(compute_jar_file_concurrent, component, it) # for each loader, download installer JSON file from maven with open( os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" ) as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) - for it in loader_version_index: - print(f"Downloading JAR info for loader {it['version']} ") - maven_url = get_maven_url( - it["maven"], "https://maven.fabricmc.net/", ".json" - ) - get_json_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), - maven_url, - ) + with concurrent.futures.ThreadPoolExecutor() as executor: + for it in loader_version_index: + executor.submit(get_json_file_concurrent, it) if __name__ == "__main__": diff --git a/meta/run/update_mojang.py b/meta/run/update_mojang.py index 52921f3e8a..defc371c1c 100755 --- a/meta/run/update_mojang.py +++ b/meta/run/update_mojang.py @@ -1,3 +1,4 @@ +import concurrent.futures import json import os import zipfile @@ -80,6 +81,28 @@ def fetch_version(path, url): return version_json +def fetch_version_concurrent(remote_versions, x): + version = remote_versions.versions[x] + 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) + + +def fetch_modified_version_concurrent(old_snapshots, x): + version = old_snapshots.versions[x] + old_snapshots_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") + + print("Updating old snapshot " + version.id) + if not os.path.isfile(old_snapshots_path): + fetch_modified_version(old_snapshots_path, version) + else: + print("Already have old snapshot " + version.id) + + def main(): # get the remote version list r = sess.get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json") @@ -108,17 +131,9 @@ def main(): else: pending_ids = remote_ids - for x in pending_ids: - version = remote_versions.versions[x] - 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 - ) + with concurrent.futures.ThreadPoolExecutor() as executor: + for x in pending_ids: + executor.submit(fetch_version_concurrent, remote_versions, x) # deal with experimental snapshots separately if os.path.exists(STATIC_EXPERIMENTS_FILE): @@ -144,15 +159,9 @@ def main(): ) old_snapshots_ids = set(old_snapshots.versions.keys()) - for x in old_snapshots_ids: - version = old_snapshots.versions[x] - old_snapshots_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json") - - print("Updating old snapshot " + version.id) - if not os.path.isfile(old_snapshots_path): - fetch_modified_version(old_snapshots_path, version) - else: - print("Already have old snapshot " + version.id) + with concurrent.futures.ThreadPoolExecutor() as executor: + for x in old_snapshots_ids: + executor.submit(fetch_modified_version_concurrent, old_snapshots, x) remote_versions.index.write(version_manifest_path) diff --git a/meta/run/update_quilt.py b/meta/run/update_quilt.py index 5eaa8ed0d0..5f3c40caa8 100755 --- a/meta/run/update_quilt.py +++ b/meta/run/update_quilt.py @@ -1,10 +1,9 @@ +import concurrent.futures import json import os import zipfile from datetime import datetime -import requests - from meta.common import ( upstream_path, ensure_upstream_dir, @@ -12,7 +11,6 @@ from meta.common import ( default_session, ) from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, USE_QUILT_MAPPINGS -from meta.common.fabric import DATETIME_FORMAT_HTTP from meta.model.fabric import FabricJarInfo UPSTREAM_DIR = upstream_path() @@ -82,6 +80,29 @@ def compute_jar_file(path, url): data.write(path + ".json") +def compute_jar_file_concurrent(component, it): + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar" + ) + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) + print(f"Processing {component} {it['version']} Done") + + +def get_json_file_concurrent(it): + print(f"Downloading JAR info for loader {it['version']} ") + maven_url = get_maven_url( + it["maven"], "https://maven.quiltmc.org/repository/release/", ".json" + ) + get_json_file( + os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), + maven_url, + ) + + def main(): # get the version list for each component we are interested in components = ["loader"] @@ -92,30 +113,18 @@ def main(): os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), "https://meta.quiltmc.org/v3/versions/" + component, ) - for it in index: - print(f"Processing {component} {it['version']} ") - jar_maven_url = get_maven_url( - it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar" - ) - compute_jar_file( - os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), - jar_maven_url, - ) + with concurrent.futures.ThreadPoolExecutor() as executor: + for it in index: + executor.submit(compute_jar_file_concurrent, component, it) # for each loader, download installer JSON file from maven with open( os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" ) as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) - for it in loader_version_index: - print(f"Downloading JAR info for loader {it['version']} ") - maven_url = get_maven_url( - it["maven"], "https://maven.quiltmc.org/repository/release/", ".json" - ) - get_json_file( - os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), - maven_url, - ) + with concurrent.futures.ThreadPoolExecutor() as executor: + for it in loader_version_index: + executor.submit(get_json_file_concurrent, it) if __name__ == "__main__": -- cgit 0.0.5-2-1-g0f52 From 6706cb5258e023bdada0cb4de0291bc96e113132 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 13 Jun 2024 19:58:16 +0300 Subject: use only latest for azul Signed-off-by: Trial97 --- meta/run/update_java.py | 1 + 1 file changed, 1 insertion(+) (limited to 'meta') diff --git a/meta/run/update_java.py b/meta/run/update_java.py index b77bb1df37..326fb5f924 100644 --- a/meta/run/update_java.py +++ b/meta/run/update_java.py @@ -98,6 +98,7 @@ def main(): availability_types=[AzulAvailabilityType.CA], java_package_type=AzulJavaPackageType.Jre, javafx_bundled=False, + latest=True, page=page, page_size=page_size, ) -- cgit 0.0.5-2-1-g0f52 From a4f59d327a02338b8342d83931758e6a17a85e00 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 13 Jun 2024 19:33:18 +0200 Subject: fix(updateNeoForge): don't include mcpatch if 0 Signed-off-by: Sefa Eyeoglu --- meta/run/update_neoforge.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 826981aed1..60b94ec6b1 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -162,7 +162,9 @@ def main(): match_nf = neoforge_version_re.match(long_version) if match_nf: - mc_version = f"1.{match_nf.group('mcminor')}.{match_nf.group('mcpatch')}" + mc_version = f"1.{match_nf.group('mcminor')}" + if match_nf.group("mcpatch") != "0": + mc_version += f".{match_nf.group('mcpatch')}" build = int(match_nf.group("number")) version = match_nf.group("number") branch = match_nf.group("tag") -- cgit 0.0.5-2-1-g0f52 From b25375f23a9c49d135c6ee7999c5875dcc916261 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 8 Aug 2024 16:55:38 +0300 Subject: add is_quick_play_singleplayer trait Signed-off-by: Trial97 --- meta/model/mojang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index 6fb71e7e73..af639f469c 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -22,7 +22,7 @@ DEFAULT_JAVA_NAME = ( "jre-legacy" # By default, we should recommend Java 8 if we don't know better ) COMPATIBLE_JAVA_MAPPINGS = {16: [17]} -SUPPORTED_FEATURES = ["is_quick_play_multiplayer"] +SUPPORTED_FEATURES = ["is_quick_play_multiplayer", "is_quick_play_singleplayer"] """ Mojang index files look like this: -- cgit 0.0.5-2-1-g0f52 From b1760b180426c9163d507434fc45c7db33b3ff5e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 12 Aug 2024 09:42:16 +0200 Subject: fix: remove download_count from adoptium models We don't use this number and it causes unnecessary updates on the meta repo. Signed-off-by: Sefa Eyeoglu --- meta/model/java.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/model/java.py b/meta/model/java.py index e24932ef85..4ba551a61f 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -247,8 +247,8 @@ class AdoptiumPackage(AdoptiumFile): checksum: Optional[str] checksum_link: Optional[str] signature_link: Optional[str] - download_count: Optional[int] metadata_link: Optional[str] + # we intentionally omit download_count class AdoptiumBinary(MetaBase): @@ -260,10 +260,10 @@ class AdoptiumBinary(MetaBase): package: Optional[AdoptiumPackage] installer: Optional[AdoptiumPackage] heap_size: AdoptiumHeapSize - download_count: Optional[int] updated_at: datetime scm_ref: Optional[str] project: AdoptiumProject + # we intentionally omit download_count class AdoptiumVersion(MetaBase): @@ -286,12 +286,12 @@ class AdoptiumRelease(MetaBase): timestamp: datetime updated_at: datetime binaries: list[AdoptiumBinary] - download_count: Optional[int] release_type: str vendor: AdoptiumVendor version_data: AdoptiumVersion source: Optional[AdoptiumFile] release_notes: Optional[AdoptiumFile] + # we intentionally omit download_count class AdoptiumReleases(MetaBase): -- cgit 0.0.5-2-1-g0f52 From c1da9492097cdfe60eaa601e57463c597ba178b8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 25 Jan 2025 12:21:58 +0200 Subject: Fix quilt broken versions Signed-off-by: Trial97 --- meta/run/generate_quilt.py | 47 ++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'meta') diff --git a/meta/run/generate_quilt.py b/meta/run/generate_quilt.py index ccf2797380..01964d5864 100755 --- a/meta/run/generate_quilt.py +++ b/meta/run/generate_quilt.py @@ -1,5 +1,6 @@ import json import os +import sys from meta.common import ( ensure_component_dir, @@ -27,6 +28,10 @@ ensure_component_dir(LOADER_COMPONENT) ensure_component_dir(INTERMEDIARY_COMPONENT) +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + def load_jar_info(artifact_key) -> FabricJarInfo: return FabricJarInfo.parse_file( os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json") @@ -106,15 +111,21 @@ def main(): for entry in loader_version_index: version = entry["version"] print(f"Processing loader {version}") + try: + v, should_recommend = process_loader_version(entry) - v, should_recommend = process_loader_version(entry) + if ( + not recommended_loader_versions and should_recommend + ): # newest stable loader is recommended + recommended_loader_versions.append(version) - if ( - not recommended_loader_versions and should_recommend - ): # newest stable loader is recommended - recommended_loader_versions.append(version) - - v.write(os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json")) + v.write( + os.path.join(LAUNCHER_DIR, LOADER_COMPONENT, f"{v.version}.json") + ) + except Exception as e: + eprint("Failed to download %s" % version) + eprint("Error is %s" % e) + continue if USE_QUILT_MAPPINGS: with open( @@ -125,18 +136,22 @@ def main(): version = entry["version"] print(f"Processing intermediary {version}") - v = process_intermediary_version(entry) + try: + v = process_intermediary_version(entry) - recommended_intermediary_versions.append( - version - ) # all intermediaries are recommended + recommended_intermediary_versions.append( + version + ) # all intermediaries are recommended - v.write( - os.path.join( - LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json" + v.write( + os.path.join( + LAUNCHER_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json" + ) ) - ) - + except Exception as e: + eprint("Failed to download %s" % version) + eprint("Error is %s" % e) + continue package = MetaPackage(uid=LOADER_COMPONENT, name="Quilt Loader") package.recommended = recommended_loader_versions package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft." -- cgit 0.0.5-2-1-g0f52 From 44fb68430174f1db81332fef1c8abb507201654e Mon Sep 17 00:00:00 2001 From: Kenneth Chew <79120643+kthchew@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:02:30 -0500 Subject: Update JNA 5.* to at least 5.13.0 to fix faulty assertion crash on macOS Signed-off-by: Kenneth Chew <79120643+kthchew@users.noreply.github.com> --- meta/common/mojang-library-patches.json | 110 ++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index 74d4d26c4b..3370a6f894 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -2875,5 +2875,115 @@ }, "name": "org.lwjgl:lwjgl-glfw-natives-linux:3.3.2-lwjgl.1" } + }, + { + "_comment": "Use newer JNA on macOS to prevent crashes due to faulty assertion", + "match": [ + "net.java.dev.jna:jna:5.6.0", + "net.java.dev.jna:jna:5.8.0", + "net.java.dev.jna:jna:5.9.0", + "net.java.dev.jna:jna:5.10.0", + "net.java.dev.jna:jna:5.12.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1200e7ebeedbe0d10062093f32925a912020e747", + "size": 1879325, + "url": "https://libraries.minecraft.net/net/java/dev/jna/jna/5.13.0/jna-5.13.0.jar" + } + }, + "name": "net.java.dev.jna:jna:5.13.0", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx" + } + }, + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Use newer JNA on macOS to prevent crashes due to faulty assertion", + "match": [ + "net.java.dev.jna:jna-platform:5.6.0", + "net.java.dev.jna:jna-platform:5.8.0", + "net.java.dev.jna:jna-platform:5.9.0", + "net.java.dev.jna:jna-platform:5.10.0", + "net.java.dev.jna:jna-platform:5.12.1" + ], + "override": { + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "osx" + } + }, + { + "action": "disallow", + "os": { + "name": "osx-arm64" + } + } + ] + }, + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "88e9a306715e9379f3122415ef4ae759a352640d", + "size": 1363209, + "url": "https://libraries.minecraft.net/net/java/dev/jna/jna-platform/5.13.0/jna-platform-5.13.0.jar" + } + }, + "name": "net.java.dev.jna:jna-platform:5.13.0", + "rules": [ + { + "action": "allow", + "os": { + "name": "osx" + } + }, + { + "action": "allow", + "os": { + "name": "osx-arm64" + } + } + ] + } + ] } ] -- cgit 0.0.5-2-1-g0f52 From 535614dcc863108fa5af1568e35d6284b8889bc2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 5 Jul 2024 09:32:52 +0300 Subject: check sha1 for forge/neoforge maven Signed-off-by: Trial97 --- meta/common/__init__.py | 9 +++++++++ meta/run/update_forge.py | 20 +++++++++++++++++++- meta/run/update_neoforge.py | 20 +++++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index d7ee49ac4a..16a4f507bf 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -86,3 +86,12 @@ def default_session(): sess.headers.update({"User-Agent": "PrismLauncherMeta/1.0"}) return sess + + +def remove_files(file_paths): + for file_path in file_paths: + try: + if os.path.isfile(file_path): + os.remove(file_path) + except Exception as e: + print(e) diff --git a/meta/run/update_forge.py b/meta/run/update_forge.py index 8fc8920bad..5a86727199 100755 --- a/meta/run/update_forge.py +++ b/meta/run/update_forge.py @@ -16,7 +16,12 @@ from pprint import pprint from pydantic import ValidationError -from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common import ( + upstream_path, + ensure_upstream_dir, + default_session, + remove_files, +) from meta.common.forge import ( JARS_DIR, INSTALLER_INFO_DIR, @@ -292,6 +297,19 @@ def main(): UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version ) + if not os.path.isfile(jar_path): + remove_files([profile_path, installer_info_path]) + else: + fileSha1 = filehash(jar_path, hashlib.sha1) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + if fileSha1 != rfile.text.strip(): + remove_files([jar_path, profile_path, installer_info_path]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) + installer_refresh_required = not os.path.isfile( profile_path ) or not os.path.isfile(installer_info_path) diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 60b94ec6b1..c6eb0f3cd4 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -17,7 +17,12 @@ import urllib.parse from pydantic import ValidationError -from meta.common import upstream_path, ensure_upstream_dir, default_session +from meta.common import ( + upstream_path, + ensure_upstream_dir, + default_session, + remove_files, +) from meta.common.neoforge import ( JARS_DIR, INSTALLER_INFO_DIR, @@ -243,6 +248,19 @@ def main(): UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version ) + if not os.path.isfile(jar_path): + remove_files([profile_path, installer_info_path]) + else: + fileSha1 = filehash(jar_path, hashlib.sha1) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + if fileSha1 != rfile.text.strip(): + remove_files([jar_path, profile_path, installer_info_path]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) + installer_refresh_required = not os.path.isfile( profile_path ) or not os.path.isfile(installer_info_path) -- cgit 0.0.5-2-1-g0f52 From 02f837ca1c02e602ed97e4ab49a97e84416a5fe3 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 13 Apr 2025 13:47:05 +0200 Subject: fix: allow NeoForge snapshots to be generated Signed-off-by: Sefa Eyeoglu --- meta/run/update_neoforge.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'meta') diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 60b94ec6b1..25c316321f 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -144,7 +144,7 @@ def main(): r"^(?P[0-9a-zA-Z_\.]+)-(?P[0-9\.]+\.(?P[0-9]+))(-(?P[a-zA-Z0-9\.]+))?$" ) neoforge_version_re = re.compile( - r"^(?P\d+).(?P\d+).(?P\d+)(?:-(?P\w+))?$" + r"^(?P\d+).(?:(?P\d+)|(?P[0-9a-z]+)).(?P\d+)(?:-(?P\w+))?$" ) print("") @@ -162,9 +162,11 @@ def main(): match_nf = neoforge_version_re.match(long_version) if match_nf: - mc_version = f"1.{match_nf.group('mcminor')}" - if match_nf.group("mcpatch") != "0": - mc_version += f".{match_nf.group('mcpatch')}" + mc_version = match_nf.group("snapshot") + if not mc_version: + mc_version = f"1.{match_nf.group('mcminor')}" + if match_nf.group("mcpatch") != "0": + mc_version += f".{match_nf.group('mcpatch')}" build = int(match_nf.group("number")) version = match_nf.group("number") branch = match_nf.group("tag") -- cgit 0.0.5-2-1-g0f52 From aeec5043b3583839d539855c72829d701675f72d Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 16 Apr 2025 11:46:39 +0100 Subject: Add logging to meta --- meta/model/__init__.py | 16 ++++++++++++++++ meta/model/mojang.py | 17 ++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 3d06f998ab..483a41e0c0 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -284,6 +284,21 @@ class MojangRules(MetaBase): return self.__root__[item] +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 Library(MetaBase): extract: Optional[MojangLibraryExtractRules] name: Optional[GradleSpecifier] @@ -323,6 +338,7 @@ class MetaVersion(Versioned): additional_traits: Optional[List[str]] = Field(alias="+traits") additional_tweakers: Optional[List[str]] = Field(alias="+tweakers") additional_jvm_args: Optional[List[str]] = Field(alias="+jvmArgs") + logging: Optional[MojangLogging] class MetaPackage(Versioned): diff --git a/meta/model/mojang.py b/meta/model/mojang.py index af639f469c..b1e2167550 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -10,6 +10,7 @@ from . import ( MojangAssets, MojangArtifact, MojangLibraryDownloads, + MojangLogging, Library, MetaVersion, GradleSpecifier, @@ -182,21 +183,6 @@ class MojangArguments(MetaBase): 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 MojangJavaComponent(StrEnum): JreLegacy = "jre-legacy" Alpha = "java-runtime-alpha" @@ -353,4 +339,5 @@ class MojangVersion(MetaBase): compatible_java_name=javaName, additional_traits=addn_traits, main_jar=main_jar, + logging=(self.logging or {}).get("client") ) -- cgit 0.0.5-2-1-g0f52 From cb6ad878937520103b3bbb380166f6e791e13873 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Jul 2025 10:03:58 +0100 Subject: Update forge.py Signed-off-by: TheKodeToad --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 25be5a9949..80d53452a7 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -15,8 +15,8 @@ LEGACYINFO_FILE = join(BASE_DIR, "legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2024-02-29"), - "86c6791e32ac6478dabf9663f0ad19f8b6465dfe", - 35483, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-07-01"), + "9325d3c4f97deffca76633845c3bfc48dcabd18e", + 28917, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 8c3d82ed0498150ec67b4521103b6b648f4dfe17 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 4 Oct 2025 16:32:56 +0300 Subject: Update forge.py Signed-off-by: Trial97 --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 80d53452a7..dc02c1c737 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -15,8 +15,8 @@ LEGACYINFO_FILE = join(BASE_DIR, "legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-07-01"), - "9325d3c4f97deffca76633845c3bfc48dcabd18e", - 28917, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-10-04"), + "7dd8189b0a0d5cf951b4b26e22fb95776bd1dede", + 29187, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 7e8e52dadc0369129589870464eaf2f9e5d21568 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sat, 4 Oct 2025 19:28:23 +0100 Subject: Revert "Update forge.py" --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index dc02c1c737..80d53452a7 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -15,8 +15,8 @@ LEGACYINFO_FILE = join(BASE_DIR, "legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-10-04"), - "7dd8189b0a0d5cf951b4b26e22fb95776bd1dede", - 29187, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-07-01"), + "9325d3c4f97deffca76633845c3bfc48dcabd18e", + 28917, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 18d7ce6d7358a75c67335d018b6a2e2ef9005d7c Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 7 Oct 2025 13:39:09 +0300 Subject: Update forge.py Signed-off-by: Trial97 --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 80d53452a7..573a5efb6f 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -15,8 +15,8 @@ LEGACYINFO_FILE = join(BASE_DIR, "legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-07-01"), - "9325d3c4f97deffca76633845c3bfc48dcabd18e", - 28917, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-10-07"), + "f8f3cc537cc86ef9890474c2d436647ae3c4ff12", + 29351, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From a656869f2071a966a73fd045b730850eca1bc03e Mon Sep 17 00:00:00 2001 From: lordofpipes Date: Tue, 7 Oct 2025 13:43:01 -0600 Subject: fix: separate out the build string into its own thing Signed-off-by: lordofpipes --- meta/model/java.py | 5 ++++- meta/run/generate_java.py | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/java.py b/meta/model/java.py index 4ba551a61f..e5760f8bac 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -41,19 +41,22 @@ class JavaVersionMeta(MetaBase): minor: int security: int build: Optional[int] = None + buildstr: Optional[str] = None name: Optional[str] = None def __str__(self): ver = f"{self.major}.{self.minor}.{self.security}" if self.build is not None: ver = f"{ver}+{self.build}" + if self.buildstr is not None: + ver = f"{ver}-{self.buildstr}" return ver def to_tuple(self): build = 0 if self.build is not None: build = self.build - return (self.major, self.minor, self.security, build) + return (self.major, self.minor, self.security, build, self.buildstr) def __eq__(self, other: Any): return self.to_tuple() == other.to_tuple() diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index fd32308217..1dd1234213 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -148,7 +148,12 @@ def mojang_runtime_to_java_runtime( mojang_component: MojangJavaComponent, runtime_os: JavaRuntimeOS, ) -> JavaRuntimeMeta: - major, _, security = mojang_runtime.version.name.partition("u") + major, _, trail = mojang_runtime.version.name.partition("u") + security, _, buildstr = trail.partition("-") + + if buildstr == "": + buildstr = None + if major and security: version_parts = [int(major), 0, int(security)] else: @@ -166,6 +171,7 @@ def mojang_runtime_to_java_runtime( minor=version_parts[1], security=version_parts[2], build=build, + buildstr=buildstr, name=mojang_runtime.version.name, ) return JavaRuntimeMeta( -- cgit 0.0.5-2-1-g0f52 From 16485b927a8ebbb5a4c9d0778ad195f33992788d Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 21 Oct 2025 17:22:10 +0200 Subject: chore: add new LWJGL variant Signed-off-by: Sefa Eyeoglu --- meta/run/generate_mojang.py | 1 + 1 file changed, 1 insertion(+) (limited to 'meta') diff --git a/meta/run/generate_mojang.py b/meta/run/generate_mojang.py index 6a0d0d9b9e..7a5856fa43 100755 --- a/meta/run/generate_mojang.py +++ b/meta/run/generate_mojang.py @@ -90,6 +90,7 @@ LOG4J_HASHES = { # We want versions that contain natives for all platforms. If there are multiple, pick the latest one # LWJGL versions we want PASS_VARIANTS = [ + "2b00f31688148fc95dbc8c8ef37308942cf0dce0", # 3.3.6 (2025-10-21 11:38:51+00:00) "73974b3af2afeb5b272ffbadcd7963014387c84f", # 3.3.3 (2024-05-22 16:25:41+00:00) "765b4ab443051d286bdbb1c19cd7dc86b0792dce", # 3.3.2 (2024-01-17 13:19:20+00:00) "54c4fb1d6a96ac3007c947bf310c8bcf94a862be", # 3.3.1 (2023-04-20 11:55:19+00:00) split natives, with WoA natives -- cgit 0.0.5-2-1-g0f52 From b0094aa265eb3225690bdb171c35534952921a9b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 22 Oct 2025 18:38:55 +0200 Subject: fix: fix Windows/macOS arm64 natives for 3.3.6 Signed-off-by: Sefa Eyeoglu --- meta/common/mojang-library-patches.json | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index 3370a6f894..656f3fc08d 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -1,6 +1,6 @@ [ { - "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.2/3.3.3", + "_comment": "Only allow osx-arm64 for existing LWJGL 3.3.2/3.3.3/3.3.6", "match": [ "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.2", "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.2", @@ -17,7 +17,15 @@ "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.3", "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.3", "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.3", - "org.lwjgl:lwjgl-natives-macos-arm64:3.3.3" + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.3", + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.6" ], "override": { "rules": [ @@ -31,7 +39,7 @@ } }, { - "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.2/3.3.3", + "_comment": "Only allow windows-arm64 for existing LWJGL 3.3.2/3.3.3/3.3.6", "match": [ "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.2", "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.2", @@ -48,7 +56,15 @@ "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.3", "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.3", "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.3", - "org.lwjgl:lwjgl-natives-windows-arm64:3.3.3" + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.3", + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.6" ], "override": { "rules": [ -- cgit 0.0.5-2-1-g0f52 From 5f10dee2e1fa9e2f6dfa13a9e72539561cee7e68 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 22 Oct 2025 18:48:43 +0200 Subject: feat: add Linux arm32/arm64 natives for 3.3.6 Signed-off-by: Sefa Eyeoglu --- meta/common/mojang-library-patches.json | 390 ++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index 656f3fc08d..cfd8907a75 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -2876,6 +2876,396 @@ } ] }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b54023af492b4c2c72451f3a7aa0f385e9969474", + "size": 141056, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1bc2e16e70df7f418d668c2984ac8066f1f6f5b1", + "size": 222196, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fd2c17603c63e8d543cb57d1db77ebd4574f3b7a", + "size": 656568, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "44de180f79e0b45c9e5bee10ca7540dcb5ddd373", + "size": 79414, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "397f588f867e9c4faf1a34231344c9209dabc052", + "size": 256144, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7806e57c3d9ea6b6a552c72f5e2597343c4d4138", + "size": 44504, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "9eeb8887b5e3aa672efd2e1b0973ffa5891a3151", + "size": 117172, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3f6a1030be5efdcde35cb363c69810245eb59c5a", + "size": 1035183, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "671adf04a6bc4f792af13892e37f804be30b7070", + "size": 118670, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "c484cae39a718010dbc7931fe5e12664600a13c2", + "size": 176503, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7830af894fa110e65bf5075deb9183efbdbc50f5", + "size": 604338, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ee815fbf454b916f13c10fff62e513eb09042ef0", + "size": 58633, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f47bac442afcb7fd014af7d90892024fe3c0d920", + "size": 191834, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "800ad2c9492a7ccadb23886c9e231f60c12a9037", + "size": 50599, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "2c9d698e76c3d0fe307d94cc6f428038492f25df", + "size": 88490, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, { "_comment": "Replace glfw from 3.3.1 with version from 3.3.2 to prevent stack smashing", "match": [ -- cgit 0.0.5-2-1-g0f52 From eabd633072ecd65bf622eb8c00737ab135c1535c Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 5 Nov 2025 15:56:31 +0000 Subject: Add 25w45a_unobfuscated --- meta/common/mojang-minecraft-experiments.json | 5 +++++ meta/run/update_mojang.py | 2 ++ 2 files changed, 7 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-minecraft-experiments.json b/meta/common/mojang-minecraft-experiments.json index 02572c78c7..702ed46e53 100644 --- a/meta/common/mojang-minecraft-experiments.json +++ b/meta/common/mojang-minecraft-experiments.json @@ -1,5 +1,10 @@ { "experiments": [ + { + "id": "25w45a_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_25w45a", + "url": "https://piston-data.mojang.com/v1/objects/de334d80d9ddc5abb94c611b8ad10f9125c4c421/25w45a_unobfuscated.zip" + }, { "id": "1_19_deep_dark_experimental_snapshot-1", "wiki": "https://minecraft.wiki/w/Java_Edition_Deep_Dark_Experimental_Snapshot_1", diff --git a/meta/run/update_mojang.py b/meta/run/update_mojang.py index ddadc16e89..acdbec95a4 100755 --- a/meta/run/update_mojang.py +++ b/meta/run/update_mojang.py @@ -45,6 +45,8 @@ def fetch_zipped_version(path, url): assert version_json + version_json["type"] = "experiment" + with open(path, "w", encoding="utf-8") as f: json.dump(version_json, f, sort_keys=True, indent=4) -- cgit 0.0.5-2-1-g0f52 From dde145abdad3bbbaf2f81c85535f1d7389ba84f3 Mon Sep 17 00:00:00 2001 From: timoreo Date: Tue, 11 Nov 2025 16:29:04 +0100 Subject: Add 25w46a_unobfuscated --- meta/common/mojang-minecraft-experiments.json | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-minecraft-experiments.json b/meta/common/mojang-minecraft-experiments.json index 702ed46e53..7e00ff5734 100644 --- a/meta/common/mojang-minecraft-experiments.json +++ b/meta/common/mojang-minecraft-experiments.json @@ -1,5 +1,10 @@ { "experiments": [ + { + "id": "25w46a_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_25w46a", + "url": "https://piston-data.mojang.com/v1/objects/f9c5e4f9c1469296299635b498438e94d312f0c6/25w46a_unobfuscated.zip" + }, { "id": "25w45a_unobfuscated", "wiki": "https://minecraft.wiki/w/Java_Edition_25w45a", -- cgit 0.0.5-2-1-g0f52 From 82a0a6bb6f8fa675e70c1a4f668ea77633cdd13a Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 19 Nov 2025 20:14:54 +0100 Subject: refactor: use multiprocessing to download Fabric meta Signed-off-by: Sefa Eyeoglu --- meta/run/update_fabric.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'meta') diff --git a/meta/run/update_fabric.py b/meta/run/update_fabric.py index 850ec8eac1..e0c1d819c9 100755 --- a/meta/run/update_fabric.py +++ b/meta/run/update_fabric.py @@ -1,4 +1,5 @@ -import concurrent.futures +from collections import deque +from multiprocessing import Pool import json import os import zipfile @@ -62,9 +63,9 @@ def head_file(url): def get_binary_file(path, url): + r = sess.get(url) + r.raise_for_status() with open(path, "wb") as f: - r = sess.get(url) - r.raise_for_status() for chunk in r.iter_content(chunk_size=128): f.write(chunk) @@ -94,14 +95,14 @@ def compute_jar_file(path, url): data.write(path + ".json") -def compute_jar_file_concurrent(component, it): - print(f"Processing {component} {it['version']} ") +def compute_jar_file_concurrent(it): + print(f"Processing {it['version']} ") jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") compute_jar_file( os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), jar_maven_url, ) - print(f"Processing {component} {it['version']} Done") + print(f"Processing {it['version']} Done") def get_json_file_concurrent(it): @@ -121,18 +122,19 @@ def main(): os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), "https://meta.fabricmc.net/v2/versions/" + component, ) - with concurrent.futures.ThreadPoolExecutor() as executor: - for it in index: - executor.submit(compute_jar_file_concurrent, component, it) + with Pool(None) as pool: + deque(pool.imap_unordered(compute_jar_file_concurrent, index, 32), 0) # for each loader, download installer JSON file from maven with open( os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), "r", encoding="utf-8" ) as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) - with concurrent.futures.ThreadPoolExecutor() as executor: - for it in loader_version_index: - executor.submit(get_json_file_concurrent, it) + with Pool(None) as pool: + deque( + pool.imap_unordered(get_json_file_concurrent, loader_version_index, 32), + 0, + ) if __name__ == "__main__": -- cgit 0.0.5-2-1-g0f52 From 9d751238a566464df8a184755718bf1ac2f485e4 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 19 Nov 2025 20:33:23 +0100 Subject: feat: add workarounds for unobfuscated versions Signed-off-by: Sefa Eyeoglu --- meta/common/fabric.py | 7 +++++++ meta/model/fabric.py | 4 ++++ meta/run/generate_fabric.py | 9 ++++++++- meta/run/update_fabric.py | 28 ++++++++++++++++++---------- 4 files changed, 37 insertions(+), 11 deletions(-) (limited to 'meta') diff --git a/meta/common/fabric.py b/meta/common/fabric.py index 2a35695cf1..667c38482f 100644 --- a/meta/common/fabric.py +++ b/meta/common/fabric.py @@ -10,3 +10,10 @@ LOADER_COMPONENT = "net.fabricmc.fabric-loader" INTERMEDIARY_COMPONENT = "net.fabricmc.intermediary" DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" + +# version -> releaseTime +BROKEN_INTERMEDIARIES = { + "1.21.11-pre1_unobfuscated": "2025-11-19T11:03:07+00:00" # releaseTime of 1.21.11 intermediary +} +EARLY_UNOBFUSCATED_SUFFIX = "_unobfuscated" +NOOP_INTERMEDIARY_VERSION = "net.fabricmc:intermediary:0.0.0" diff --git a/meta/model/fabric.py b/meta/model/fabric.py index 5cb0e9caab..7acd7c8756 100644 --- a/meta/model/fabric.py +++ b/meta/model/fabric.py @@ -6,6 +6,10 @@ from pydantic import Field from . import Library, MetaBase +EARLY_UNOBFUSCATED_SUFFIX = "_unobfuscated" +NOOP_INTERMEDIARY_VERSION = "net.fabricmc:intermediary:0.0.0" + + class FabricInstallerArguments(MetaBase): client: Optional[List[str]] common: Optional[List[str]] diff --git a/meta/run/generate_fabric.py b/meta/run/generate_fabric.py index 7ca50dd6aa..9d1f96263b 100755 --- a/meta/run/generate_fabric.py +++ b/meta/run/generate_fabric.py @@ -8,11 +8,13 @@ from meta.common import ( transform_maven_key, ) from meta.common.fabric import ( + EARLY_UNOBFUSCATED_SUFFIX, JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT, + NOOP_INTERMEDIARY_VERSION, ) from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses @@ -76,8 +78,13 @@ def process_intermediary_version(entry) -> MetaVersion: v.type = "release" v.libraries = [] v.volatile = True + + maven = entry["maven"] + if EARLY_UNOBFUSCATED_SUFFIX in entry["version"]: + maven = NOOP_INTERMEDIARY_VERSION + intermediary_lib = Library( - name=GradleSpecifier.from_string(entry["maven"]), + name=GradleSpecifier.from_string(maven), url="https://maven.fabricmc.net", ) v.libraries.append(intermediary_lib) diff --git a/meta/run/update_fabric.py b/meta/run/update_fabric.py index e0c1d819c9..43a27e146c 100755 --- a/meta/run/update_fabric.py +++ b/meta/run/update_fabric.py @@ -14,6 +14,7 @@ from meta.common import ( default_session, ) from meta.common.fabric import ( + BROKEN_INTERMEDIARIES, JARS_DIR, INSTALLER_INFO_DIR, META_DIR, @@ -70,7 +71,7 @@ def get_binary_file(path, url): f.write(chunk) -def compute_jar_file(path, url): +def fetch_release_time(path, url): # These two approaches should result in the same metadata, except for the timestamp which might be a few minutes # off for the fallback method try: @@ -91,18 +92,25 @@ def compute_jar_file(path, url): if tstamp_new > tstamp: tstamp = tstamp_new - data = FabricJarInfo(release_time=tstamp) - data.write(path + ".json") + return tstamp def compute_jar_file_concurrent(it): - print(f"Processing {it['version']} ") - jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") - compute_jar_file( - os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), - jar_maven_url, - ) - print(f"Processing {it['version']} Done") + print(f"Processing {it['maven']} ") + path = os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])) + tstamp = BROKEN_INTERMEDIARIES.get(it["version"]) + if not tstamp: + jar_maven_url = get_maven_url( + it["maven"], "https://maven.fabricmc.net/", ".jar" + ) + tstamp = fetch_release_time( + path, + jar_maven_url, + ) + + data = FabricJarInfo(release_time=tstamp) + data.write(f"{path}.json") + print(f"Processing {it['maven']} Done") def get_json_file_concurrent(it): -- cgit 0.0.5-2-1-g0f52 From e573624795a546be2b509ef143d06f9c2ee13bde Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 19 Nov 2025 20:38:30 +0100 Subject: chore: add 1_21_11-pre1_unobfuscated Signed-off-by: Sefa Eyeoglu --- meta/common/mojang-minecraft-experiments.json | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-minecraft-experiments.json b/meta/common/mojang-minecraft-experiments.json index 7e00ff5734..e34e82e5e0 100644 --- a/meta/common/mojang-minecraft-experiments.json +++ b/meta/common/mojang-minecraft-experiments.json @@ -1,5 +1,10 @@ { "experiments": [ + { + "id": "1_21_11-pre1_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_1", + "url": "https://piston-data.mojang.com/v1/objects/f98a0c053a8246cce12f8f29f2ba4ce00872fd53/1_21_11-pre1_unobfuscated.zip" + }, { "id": "25w46a_unobfuscated", "wiki": "https://minecraft.wiki/w/Java_Edition_25w46a", -- cgit 0.0.5-2-1-g0f52 From ba4496df4f279304fcffc6de0a9ce5be57de948a Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 8 Dec 2025 00:22:01 +0000 Subject: Update ForgeWrapper to 2025-12-07 Signed-off-by: TheKodeToad --- meta/common/forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 573a5efb6f..2622c957f2 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -15,8 +15,8 @@ LEGACYINFO_FILE = join(BASE_DIR, "legacyinfo.json") FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( - GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-10-07"), - "f8f3cc537cc86ef9890474c2d436647ae3c4ff12", - 29351, + GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-12-07"), + "4c4653d80409e7e968d3e3209196ffae778b7b4e", + 10278, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 3dd12fbbd5c8440a9787691fd28741b949931d24 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Mon, 8 Dec 2025 10:52:04 +0000 Subject: Fix size Signed-off-by: TheKodeToad --- meta/common/forge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/common/forge.py b/meta/common/forge.py index 2622c957f2..3cf5c3d10f 100644 --- a/meta/common/forge.py +++ b/meta/common/forge.py @@ -17,6 +17,6 @@ FORGE_COMPONENT = "net.minecraftforge" FORGEWRAPPER_LIBRARY = make_launcher_library( GradleSpecifier("io.github.zekerzhayard", "ForgeWrapper", "prism-2025-12-07"), "4c4653d80409e7e968d3e3209196ffae778b7b4e", - 10278, + 29731, ) BAD_VERSIONS = ["1.12.2-14.23.5.2851"] -- cgit 0.0.5-2-1-g0f52 From 94a2ce0d61498dec6e284bf1b242093c9858450f Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 9 Dec 2025 21:08:21 +0100 Subject: feat: Add more unobfuscated versions since 26.1.x will be unobfuscated by default, this means these will be all of them Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/common/mojang-minecraft-experiments.json | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-minecraft-experiments.json b/meta/common/mojang-minecraft-experiments.json index e34e82e5e0..2a6792a7b0 100644 --- a/meta/common/mojang-minecraft-experiments.json +++ b/meta/common/mojang-minecraft-experiments.json @@ -1,5 +1,45 @@ { "experiments": [ + { + "id": "1_21_11_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11", + "url": "https://piston-data.mojang.com/v1/objects/82332dfb17146de34cb7a36d2b910e3b2009191a/1_21_11_unobfuscated.zip" + }, + { + "id": "1_21_11-rc3_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Release_Candidate_3", + "url": "https://piston-data.mojang.com/v1/objects/7abe399a1b3c07754c5dc3ec4e5c6f50ee03c10e/1_21_11-rc3_unobfuscated.zip" + }, + { + "id": "1_21_11-rc2_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Release_Candidate_2", + "url": "https://piston-data.mojang.com/v1/objects/fb70de3ae3e19825622b7687d2fd783d78c4b05f/1_21_11-rc2_unobfuscated.zip" + }, + { + "id": "1_21_11-rc1_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Release_Candidate_1", + "url": "https://piston-data.mojang.com/v1/objects/38712002b9d02061e662b69c44753a47d24da516/1_21_11-rc1_unobfuscated.zip" + }, + { + "id": "1_21_11-pre5_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_5", + "url": "https://piston-data.mojang.com/v1/objects/931df659128f913ce356d6036c318c5d9a039e85/1_21_11-pre5_unobfuscated.zip" + }, + { + "id": "1_21_11-pre4_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_4", + "url": "https://piston-data.mojang.com/v1/objects/834666571f1e1374923b73f4baec4203d44e9c0d/1_21_11-pre4_unobfuscated.zip" + }, + { + "id": "1_21_11-pre3_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_3", + "url": "https://piston-data.mojang.com/v1/objects/7717a481468cc33d2414d82ee9c0450f56264db0/1_21_11-pre3_unobfuscated.zip" + }, + { + "id": "1_21_11-pre2_unobfuscated", + "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_2", + "url": "https://piston-data.mojang.com/v1/objects/528731e05b7be26c90fedf8f2ef6470abb0d1994/1_21_11-pre2_unobfuscated.zip" + }, { "id": "1_21_11-pre1_unobfuscated", "wiki": "https://minecraft.wiki/w/Java_Edition_1.21.11_Pre-Release_1", -- cgit 0.0.5-2-1-g0f52 From 064c55aedd6ccf99e510614fc083c021e4e03c1a Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 9 Dec 2025 21:09:33 +0100 Subject: Revert "feat: add workarounds for unobfuscated versions" completely unnecessary as fabric fixed their unobfuscated versions This reverts commit 9d751238a566464df8a184755718bf1ac2f485e4. --- meta/common/fabric.py | 7 ------- meta/model/fabric.py | 4 ---- meta/run/generate_fabric.py | 9 +-------- meta/run/update_fabric.py | 28 ++++++++++------------------ 4 files changed, 11 insertions(+), 37 deletions(-) (limited to 'meta') diff --git a/meta/common/fabric.py b/meta/common/fabric.py index 667c38482f..2a35695cf1 100644 --- a/meta/common/fabric.py +++ b/meta/common/fabric.py @@ -10,10 +10,3 @@ LOADER_COMPONENT = "net.fabricmc.fabric-loader" INTERMEDIARY_COMPONENT = "net.fabricmc.intermediary" DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" - -# version -> releaseTime -BROKEN_INTERMEDIARIES = { - "1.21.11-pre1_unobfuscated": "2025-11-19T11:03:07+00:00" # releaseTime of 1.21.11 intermediary -} -EARLY_UNOBFUSCATED_SUFFIX = "_unobfuscated" -NOOP_INTERMEDIARY_VERSION = "net.fabricmc:intermediary:0.0.0" diff --git a/meta/model/fabric.py b/meta/model/fabric.py index 7acd7c8756..5cb0e9caab 100644 --- a/meta/model/fabric.py +++ b/meta/model/fabric.py @@ -6,10 +6,6 @@ from pydantic import Field from . import Library, MetaBase -EARLY_UNOBFUSCATED_SUFFIX = "_unobfuscated" -NOOP_INTERMEDIARY_VERSION = "net.fabricmc:intermediary:0.0.0" - - class FabricInstallerArguments(MetaBase): client: Optional[List[str]] common: Optional[List[str]] diff --git a/meta/run/generate_fabric.py b/meta/run/generate_fabric.py index 9d1f96263b..7ca50dd6aa 100755 --- a/meta/run/generate_fabric.py +++ b/meta/run/generate_fabric.py @@ -8,13 +8,11 @@ from meta.common import ( transform_maven_key, ) from meta.common.fabric import ( - EARLY_UNOBFUSCATED_SUFFIX, JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT, - NOOP_INTERMEDIARY_VERSION, ) from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses @@ -78,13 +76,8 @@ def process_intermediary_version(entry) -> MetaVersion: v.type = "release" v.libraries = [] v.volatile = True - - maven = entry["maven"] - if EARLY_UNOBFUSCATED_SUFFIX in entry["version"]: - maven = NOOP_INTERMEDIARY_VERSION - intermediary_lib = Library( - name=GradleSpecifier.from_string(maven), + name=GradleSpecifier.from_string(entry["maven"]), url="https://maven.fabricmc.net", ) v.libraries.append(intermediary_lib) diff --git a/meta/run/update_fabric.py b/meta/run/update_fabric.py index 43a27e146c..e0c1d819c9 100755 --- a/meta/run/update_fabric.py +++ b/meta/run/update_fabric.py @@ -14,7 +14,6 @@ from meta.common import ( default_session, ) from meta.common.fabric import ( - BROKEN_INTERMEDIARIES, JARS_DIR, INSTALLER_INFO_DIR, META_DIR, @@ -71,7 +70,7 @@ def get_binary_file(path, url): f.write(chunk) -def fetch_release_time(path, url): +def compute_jar_file(path, url): # These two approaches should result in the same metadata, except for the timestamp which might be a few minutes # off for the fallback method try: @@ -92,25 +91,18 @@ def fetch_release_time(path, url): if tstamp_new > tstamp: tstamp = tstamp_new - return tstamp + data = FabricJarInfo(release_time=tstamp) + data.write(path + ".json") def compute_jar_file_concurrent(it): - print(f"Processing {it['maven']} ") - path = os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])) - tstamp = BROKEN_INTERMEDIARIES.get(it["version"]) - if not tstamp: - jar_maven_url = get_maven_url( - it["maven"], "https://maven.fabricmc.net/", ".jar" - ) - tstamp = fetch_release_time( - path, - jar_maven_url, - ) - - data = FabricJarInfo(release_time=tstamp) - data.write(f"{path}.json") - print(f"Processing {it['maven']} Done") + print(f"Processing {it['version']} ") + jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") + compute_jar_file( + os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), + jar_maven_url, + ) + print(f"Processing {it['version']} Done") def get_json_file_concurrent(it): -- cgit 0.0.5-2-1-g0f52 From bdc461cb10de0562b5a5d7a9be7b2e139a2c51d4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 16 Dec 2025 17:11:56 +0200 Subject: add java-runtime-epsilon Signed-off-by: Trial97 --- meta/model/mojang.py | 3 ++- meta/run/generate_java.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/mojang.py b/meta/model/mojang.py index b1e2167550..b3edfe21f9 100644 --- a/meta/model/mojang.py +++ b/meta/model/mojang.py @@ -191,6 +191,7 @@ class MojangJavaComponent(StrEnum): GammaSnapshot = "java-runtime-gamma-snapshot" Exe = "minecraft-java-exe" Delta = "java-runtime-delta" + Epsilon = "java-runtime-epsilon" class JavaVersion(MetaBase): @@ -339,5 +340,5 @@ class MojangVersion(MetaBase): compatible_java_name=javaName, additional_traits=addn_traits, main_jar=main_jar, - logging=(self.logging or {}).get("client") + logging=(self.logging or {}).get("client"), ) diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index 1dd1234213..7769c7b89c 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -139,6 +139,8 @@ def mojang_component_to_major(mojang_component: MojangJavaComponent) -> int: return 0 case MojangJavaComponent.Delta: return 21 + case MojangJavaComponent.Epsilon: + return 25 case _: return 0 @@ -474,6 +476,7 @@ def main(): MojangJavaComponent.Gamma, MojangJavaComponent.GammaSnapshot, MojangJavaComponent.Delta, + MojangJavaComponent.Epsilon, ]: runtime = get_mojang_extra_java(comp, java_os) if runtime != None: -- cgit 0.0.5-2-1-g0f52 From 7750733ee4a5ebea32b6b554bf39dc6022e5c58e Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 16 Dec 2025 17:27:35 +0100 Subject: fix: Fix linux-arm64 adoptium not being in epsilon Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/run/generate_java.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index 7769c7b89c..b53fdcdd00 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -330,9 +330,9 @@ def main(): JavaRuntimeOS.LinuxArm32, JavaRuntimeOS.LinuxArm64, ] - and major in [8, 17, 21] + and major in [8, 17, 21, 25] ) - or (runtime.runtime_os == JavaRuntimeOS.LinuxX86 and major in [17, 21]) + or (runtime.runtime_os == JavaRuntimeOS.LinuxX86 and major in [17, 21, 25]) ): if major not in extra_mojang_javas: extra_mojang_javas[major] = list[JavaRuntimeMeta]() -- cgit 0.0.5-2-1-g0f52 From a98bb3058477c4a7c2f434f5ae9005050f5b5812 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Mon, 22 Dec 2025 12:04:25 +0100 Subject: fix: skip version if it doesn't match our regex Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/run/generate_neoforge.py | 2 +- meta/run/update_neoforge.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'meta') diff --git a/meta/run/generate_neoforge.py b/meta/run/generate_neoforge.py index ee1e26908d..6937ab01ba 100644 --- a/meta/run/generate_neoforge.py +++ b/meta/run/generate_neoforge.py @@ -117,7 +117,7 @@ def main(): if version.url() is None: eprint("Skipping %s with no valid files" % key) continue - eprint("Processing Forge %s" % version.rawVersion) + eprint("Processing NeoForge %s" % version.rawVersion) version_elements = version.rawVersion.split(".") if len(version_elements) < 1: eprint("Skipping version %s with not enough version elements" % key) diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 25c316321f..1cf3a29b60 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -120,7 +120,7 @@ def get_single_forge_files_manifest(longversion, artifact: str): def main(): - # get the remote version list fragments + # get the 1.20.1 remote version list fragments r = sess.get( "https://maven.neoforged.net/api/maven/versions/releases/net%2Fneoforged%2Fforge" ) @@ -173,7 +173,10 @@ def main(): match = match_nf artifact = "neoforge" - assert match, f"{long_version} doesn't match version regex" + if not match and not match_nf: + print(f"Skipping {long_version} as it does not match regex") + continue + try: files = get_single_forge_files_manifest(long_version, artifact) except: -- cgit 0.0.5-2-1-g0f52 From b640188e1f14bb5b04201875bb08df35c5443e01 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:40:10 +0100 Subject: feat+fix: get minecraft version from profile json instead of regex makes the code less sus and makes meta generate for new neoforge versions Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/model/neoforge.py | 9 -------- meta/run/generate_neoforge.py | 32 +++++++++++++---------------- meta/run/update_neoforge.py | 48 ++++++++----------------------------------- 3 files changed, 22 insertions(+), 67 deletions(-) (limited to 'meta') diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index 5f5237fa5f..53bf67ba43 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -31,10 +31,7 @@ class NeoForgeFile(MetaBase): class NeoForgeEntry(MetaBase): artifact: str long_version: str = Field(alias="longversion") - mc_version: str = Field(alias="mcversion") version: str - build: int - branch: Optional[str] latest: Optional[bool] recommended: Optional[bool] files: Optional[Dict[str, NeoForgeFile]] @@ -48,8 +45,6 @@ class NeoForgeMCVersionInfo(MetaBase): class DerivedNeoForgeIndex(MetaBase): versions: Dict[str, NeoForgeEntry] = Field({}) - by_mc_version: Dict[str, NeoForgeMCVersionInfo] = Field({}, alias="by_mcversion") - class FMLLib( MetaBase @@ -181,14 +176,10 @@ class InstallerInfo(MetaBase): class NeoForgeVersion: def __init__(self, entry: NeoForgeEntry): self.artifact = entry.artifact - self.build = entry.build self.rawVersion = entry.version if self.artifact == "neoforge": self.rawVersion = entry.long_version - self.mc_version = entry.mc_version - self.mc_version_sane = self.mc_version.replace("_pre", "-pre", 1) - self.branch = entry.branch self.installer_filename = None self.installer_url = None self.universal_filename = None diff --git a/meta/run/generate_neoforge.py b/meta/run/generate_neoforge.py index 6937ab01ba..41ac950b7d 100644 --- a/meta/run/generate_neoforge.py +++ b/meta/run/generate_neoforge.py @@ -48,7 +48,6 @@ def version_from_build_system_installer( version: NeoForgeVersion, ) -> MetaVersion: v = MetaVersion(name="NeoForge", version=version.rawVersion, uid=NEOFORGE_COMPONENT) - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=version.mc_version_sane)] v.main_class = "io.github.zekerzhayard.forgewrapper.installer.Main" # FIXME: Add the size and hash here @@ -108,10 +107,6 @@ def main(): recommended_versions = [] for key, entry in remote_versions.versions.items(): - if entry.mc_version is None: - eprint("Skipping %s with invalid MC version" % key) - continue - version = NeoForgeVersion(entry) if version.url() is None: @@ -134,18 +129,6 @@ def main(): if entry.recommended: recommended_versions.append(version.rawVersion) - # If we do not have the corresponding Minecraft version, we ignore it - if not os.path.isfile( - os.path.join( - LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{version.mc_version_sane}.json" - ) - ): - eprint( - "Skipping %s with no corresponding Minecraft version %s" - % (key, version.mc_version_sane) - ) - continue - # Path for new-style build system based installers installer_version_filepath = os.path.join( UPSTREAM_DIR, VERSION_MANIFEST_DIR, f"{version.long_version}.json" @@ -161,7 +144,20 @@ def main(): installer = MojangVersion.parse_file(installer_version_filepath) profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) v = version_from_build_system_installer(installer, profile, version) - + + #we can get the minecraft version from the profile json info, so let's just do that instead of hacky regex + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=profile.minecraft)] + # If we do not have the corresponding Minecraft version, we ignore it + if not os.path.isfile( + os.path.join( + LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{profile.minecraft}.json" + ) + ): + eprint( + "Skipping %s with no corresponding Minecraft version %s" + % (key, profile.minecraft) + ) + continue v.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, f"{v.version}.json")) recommended_versions.sort() diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 1cf3a29b60..24a0da017e 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -140,43 +140,24 @@ def main(): new_index = DerivedNeoForgeIndex() + #let's keep the regex here to remove the 1.20.1- version_expression = re.compile( r"^(?P[0-9a-zA-Z_\.]+)-(?P[0-9\.]+\.(?P[0-9]+))(-(?P[a-zA-Z0-9\.]+))?$" ) - neoforge_version_re = re.compile( - r"^(?P\d+).(?:(?P\d+)|(?P[0-9a-z]+)).(?P\d+)(?:-(?P\w+))?$" - ) print("") print("Processing versions:") for long_version in main_json: assert type(long_version) == str - match = version_expression.match(long_version) - if match: - mc_version = match.group("mc") - build = int(match.group("build")) - version = match.group("ver") - branch = match.group("branch") + legacyMatch = version_expression.match(long_version) + if legacyMatch: + version = legacyMatch.group("ver") artifact = "forge" - - match_nf = neoforge_version_re.match(long_version) - if match_nf: - mc_version = match_nf.group("snapshot") - if not mc_version: - mc_version = f"1.{match_nf.group('mcminor')}" - if match_nf.group("mcpatch") != "0": - mc_version += f".{match_nf.group('mcpatch')}" - build = int(match_nf.group("number")) - version = match_nf.group("number") - branch = match_nf.group("tag") - match = match_nf + else: + version = long_version artifact = "neoforge" - if not match and not match_nf: - print(f"Skipping {long_version} as it does not match regex") - continue - try: files = get_single_forge_files_manifest(long_version, artifact) except: @@ -188,26 +169,16 @@ def main(): entry = NeoForgeEntry( artifact=artifact, long_version=long_version, - mc_version=mc_version, version=version, - build=build, - branch=branch, # NOTE: we add this later after the fact. The forge promotions file lies about these. latest=False, recommended=is_recommended, files=files, ) new_index.versions[long_version] = entry - if not new_index.by_mc_version: - new_index.by_mc_version = dict() - if mc_version not in new_index.by_mc_version: - new_index.by_mc_version.setdefault(mc_version, NeoForgeMCVersionInfo()) - new_index.by_mc_version[mc_version].versions.append(long_version) - # NOTE: we add this later after the fact. The forge promotions file lies about these. - # if entry.latest: - # new_index.by_mc_version[mc_version].latest = long_version + if entry.recommended: - new_index.by_mc_version[mc_version].recommended = long_version + new_index.recommended = long_version print("") print("Dumping index files...") @@ -223,9 +194,6 @@ def main(): # get the installer jars - if needed - and get the installer profiles out of them for key, entry in new_index.versions.items(): eprint("Updating NeoForge %s" % key) - if entry.mc_version is None: - eprint("Skipping %d with invalid MC version" % entry.build) - continue version = NeoForgeVersion(entry) if version.url() is None: -- cgit 0.0.5-2-1-g0f52 From 5c167532587f138e8087babcd5ef0183255c84c8 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Sun, 28 Dec 2025 15:54:15 +0500 Subject: feat: support Java agents --- meta/model/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index 483a41e0c0..a27ec68e04 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -309,6 +309,10 @@ class Library(MetaBase): mmcHint: Optional[str] = Field(None, alias="MMC-hint") +class JavaAgent(Library): + argument: Optional[str] + + class Dependency(MetaBase): uid: str equals: Optional[str] @@ -335,6 +339,7 @@ class MetaVersion(Versioned): release_time: Optional[datetime] = Field(alias="releaseTime") compatible_java_majors: Optional[List[int]] = Field(alias="compatibleJavaMajors") compatible_java_name: Optional[str] = Field(alias="compatibleJavaName") + java_agents: Optional[List[JavaAgent]] = Field(alias="+agents") additional_traits: Optional[List[str]] = Field(alias="+traits") additional_tweakers: Optional[List[str]] = Field(alias="+tweakers") additional_jvm_args: Optional[List[str]] = Field(alias="+jvmArgs") -- cgit 0.0.5-2-1-g0f52 From 2be39ab32d50acd6168cfce9014682e53de8bc54 Mon Sep 17 00:00:00 2001 From: Vixea Date: Wed, 14 Jan 2026 10:05:05 -0600 Subject: Meta: RISC-V 64 support for 3.3.6 --- meta/common/mojang-library-patches.json | 208 ++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index cfd8907a75..e5a7d9bedb 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -3266,6 +3266,214 @@ } ] }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "5eea88e3527bb5fd2d81cc03f2bece1c83eada1c", + "size": 1199082, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-glfw:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "dde300b71892fddae65e4c524760e650bc924bb2", + "size": 119447, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "9c76514b7725d5b8c5731f41218e97dcad3237b9", + "size": 197210, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-openal:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "35fc93e98cf43a51f8fdd2b7e46854cb3820532a", + "size": 640228, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-openal/lwjgl-openal-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-opengl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "c55c0458e903df7bb688401273ad0e7c92c11068", + "size": 57863, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-stb:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "009dbfa917b9fc07459a726e72d9ea9e7178f9d3", + "size": 216086, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-stb/lwjgl-stb-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "0dfe4d23c5c5d92bf70a8bc50a964b0a6452add2", + "size": 46550, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "830923e74105b08d137413735525e2be80a421b8", + "size": 81930, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl/lwjgl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-riscv64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, { "_comment": "Replace glfw from 3.3.1 with version from 3.3.2 to prevent stack smashing", "match": [ -- cgit 0.0.5-2-1-g0f52 From af8a9ac5d7050a8de00a59fa71dbab94d9b907be Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 31 Jan 2026 11:17:39 +0100 Subject: fix: add linux-riscv64 as valid os Signed-off-by: Sefa Eyeoglu --- meta/model/__init__.py | 1 + 1 file changed, 1 insertion(+) (limited to 'meta') diff --git a/meta/model/__init__.py b/meta/model/__init__.py index a27ec68e04..203b367ed5 100644 --- a/meta/model/__init__.py +++ b/meta/model/__init__.py @@ -257,6 +257,7 @@ class OSRule(MetaBase): "osx-arm64", "linux-arm64", "linux-arm32", + "linux-riscv64", ] return v -- cgit 0.0.5-2-1-g0f52 From a7ddff7964214a1cdd7ea266cde72198c63dd0fb Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 17 Feb 2026 18:24:21 +0100 Subject: fix: initial support for lwjgl 3.4.1 Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/run/generate_mojang.py | 1 + 1 file changed, 1 insertion(+) (limited to 'meta') diff --git a/meta/run/generate_mojang.py b/meta/run/generate_mojang.py index 7a5856fa43..693afb66da 100755 --- a/meta/run/generate_mojang.py +++ b/meta/run/generate_mojang.py @@ -90,6 +90,7 @@ LOG4J_HASHES = { # We want versions that contain natives for all platforms. If there are multiple, pick the latest one # LWJGL versions we want PASS_VARIANTS = [ + "1fd0e4d1f0f7c97e8765a69d38225e1f27ee14ef", # 3.4.1 (2026-02-17 12:42:24+00:00) "2b00f31688148fc95dbc8c8ef37308942cf0dce0", # 3.3.6 (2025-10-21 11:38:51+00:00) "73974b3af2afeb5b272ffbadcd7963014387c84f", # 3.3.3 (2024-05-22 16:25:41+00:00) "765b4ab443051d286bdbb1c19cd7dc86b0792dce", # 3.3.2 (2024-01-17 13:19:20+00:00) -- cgit 0.0.5-2-1-g0f52 From 047f01961f34deedb215e04e039cbc5ea1b12fcd Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Tue, 17 Feb 2026 18:42:49 +0100 Subject: feat: add patches for lwjgl 3.4.1 Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/common/mojang-library-patches.json | 650 ++++++++++++++++++++++++++++++++ 1 file changed, 650 insertions(+) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index e5a7d9bedb..38e270437a 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -2876,6 +2876,32 @@ } ] }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-freetype:3.3.6" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "b5492439c7c9a596655d0d0e06801f93ec491e53", + "size": 1093516, + "url": "https://build.lwjgl.org/release/3.3.6/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.3.6-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, { "_comment": "Add linux-arm64 support for LWJGL 3.3.6", "match": [ @@ -3473,6 +3499,630 @@ ] } ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-freetype:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8f37d0da3386ff602ec54cd06626881895711041", + "size": 1093516, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "e5e87034c47118960746077dba46280e8de864b3", + "size": 141056, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "7891964dfb723209c6d02b0401432348fb707cc0", + "size": 222196, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3729b70cdd42df5571b075e051fa2fc8586dc538", + "size": 656568, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "61a4103e56bbaeb74ad3f19ec14299fd6891c4b0", + "size": 79414, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "3bc107f901f931fea07cb0d80b1d74a34b806a2b", + "size": 256144, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "20771d2b4e01f5295156912ab62e170508aef618", + "size": 44504, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "46883f3b622d8b4d7f27b627ca3360cda3db0e0e", + "size": 117172, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl/lwjgl-natives-linux-arm64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-freetype:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d0bb1ececfdd1e5b75ba75c22d0e075dafe695d1", + "size": 1035183, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "bb243e9a857c4301bf7d5e668538686eaa64101e", + "size": 118670, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "fc9ce35c94743e23855777cacaba34bc145da6ec", + "size": 176503, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "6d4ac5f3d5bab7f2fadfd52c32177d9c12a43b49", + "size": 604338, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "172e575948234ff7920abf0d0083d25e37c91ba6", + "size": 58633, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8f753f3772863989f1172d2b84b4e56ed18e8c35", + "size": 191834, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.3.6", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "62cb99015923df821e2e7a2a5a1e51d1e307126c", + "size": 50599, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-arm32 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "1511ab1ffb1c8d8e00e2acb452663173ae09bca0", + "size": 88490, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl/lwjgl-natives-linux-arm32.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-arm32:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-arm32" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-freetype:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "737708c27a49ba5884ef347565fcb9964e8d85a9", + "size": 1199082, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-freetype/lwjgl-freetype-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-freetype-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-glfw:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "d76ed6846bff9804cfd1adb84b068728645a097b", + "size": 119447, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-glfw/lwjgl-glfw-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-glfw-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-jemalloc:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "ac7be1f86e87df030e668c02df2dec27c44da32b", + "size": 197210, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-jemalloc/lwjgl-jemalloc-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-jemalloc-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-openal:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "652b9424f529dccc79694f2124709083d2712104", + "size": 640228, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-openal/lwjgl-openal-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-openal-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-opengl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "8a6f47236738e3c682e98e15a13cf0358c1da85c", + "size": 57863, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-opengl/lwjgl-opengl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-opengl-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-stb:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "f1d8fe25d44e26c40f4dd4c48189323675467578", + "size": 216086, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-stb/lwjgl-stb-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-stb-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl-tinyfd:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "6aa204e5047e9f272c7271119105833cc0ddfd27", + "size": 46550, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl-tinyfd/lwjgl-tinyfd-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-tinyfd-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] + }, + { + "_comment": "Add linux-riscv64 support for LWJGL 3.4.1", + "match": [ + "org.lwjgl:lwjgl:3.4.1" + ], + "additionalLibraries": [ + { + "downloads": { + "artifact": { + "sha1": "a43b5208883562d31b5a2de1810aa82e2f2bf0ba", + "size": 81930, + "url": "https://build.lwjgl.org/release/3.4.1/bin/lwjgl/lwjgl-natives-linux-riscv64.jar" + } + }, + "name": "org.lwjgl:lwjgl-natives-linux-riscv64:3.4.1-lwjgl.1", + "rules": [ + { + "action": "allow", + "os": { + "name": "linux-riscv64" + } + } + ] + } + ] }, { "_comment": "Replace glfw from 3.3.1 with version from 3.3.2 to prevent stack smashing", -- cgit 0.0.5-2-1-g0f52 From ccc5e854dc13656ace48039fe492ac2688c66380 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:34:18 +0100 Subject: fix: fix lwjgl 3.4.1 on arm64 win and mac Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/common/mojang-library-patches.json | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/common/mojang-library-patches.json b/meta/common/mojang-library-patches.json index 38e270437a..d6386746b6 100644 --- a/meta/common/mojang-library-patches.json +++ b/meta/common/mojang-library-patches.json @@ -25,7 +25,15 @@ "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.3.6", "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.3.6", "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.3.6", - "org.lwjgl:lwjgl-natives-macos-arm64:3.3.6" + "org.lwjgl:lwjgl-natives-macos-arm64:3.3.6", + "org.lwjgl:lwjgl-freetype-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-glfw-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-jemalloc-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-openal-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-opengl-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-stb-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-tinyfd-natives-macos-arm64:3.4.1", + "org.lwjgl:lwjgl-natives-macos-arm64:3.4.1" ], "override": { "rules": [ @@ -64,7 +72,15 @@ "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.3.6", "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.3.6", "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.3.6", - "org.lwjgl:lwjgl-natives-windows-arm64:3.3.6" + "org.lwjgl:lwjgl-natives-windows-arm64:3.3.6", + "org.lwjgl:lwjgl-freetype-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-glfw-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-jemalloc-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-openal-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-opengl-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-stb-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-tinyfd-natives-windows-arm64:3.4.1", + "org.lwjgl:lwjgl-natives-windows-arm64:3.4.1" ], "override": { "rules": [ -- cgit 0.0.5-2-1-g0f52 From cc91037cc769d657b329576b8762eb8a172aa2de Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Sat, 21 Feb 2026 08:16:38 +0100 Subject: feat: add java (auto)download support for riscv64 (java 17+) Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- meta/model/java.py | 1 + meta/run/generate_java.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/model/java.py b/meta/model/java.py index e5760f8bac..b941860726 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -23,6 +23,7 @@ class JavaRuntimeOS(StrEnum): LinuxX86 = "linux-x86" LinuxArm64 = "linux-arm64" LinuxArm32 = "linux-arm32" + LinuxRiscv64 = "linux-riscv64" WindowsX64 = "windows-x64" WindowsX86 = "windows-x86" WindowsArm64 = "windows-arm64" diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index b53fdcdd00..13e01a0496 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -56,6 +56,7 @@ MOJANG_OS_ARCHITECTURES = [ "x86", "arm64", "arm32", + "riscv64", ] MOJANG_OS_ARCHITECTURE_TRANSLATIONS = { @@ -66,6 +67,7 @@ MOJANG_OS_ARCHITECTURE_TRANSLATIONS = { "aarch64": "arm64", "x86_64": "x64", "arm": "arm32", + "riscv64": "riscv64", } @@ -332,7 +334,13 @@ def main(): ] and major in [8, 17, 21, 25] ) - or (runtime.runtime_os == JavaRuntimeOS.LinuxX86 and major in [17, 21, 25]) + or ( + runtime.runtime_os + in [ + JavaRuntimeOS.LinuxX86, + JavaRuntimeOS.LinuxRiscv64 + ] + and major in [17, 21, 25]) ): if major not in extra_mojang_javas: extra_mojang_javas[major] = list[JavaRuntimeMeta]() @@ -468,6 +476,7 @@ def main(): JavaRuntimeOS.WindowsArm32, JavaRuntimeOS.LinuxArm32, JavaRuntimeOS.LinuxArm64, + JavaRuntimeOS.LinuxRiscv64, ]: for comp in [ MojangJavaComponent.JreLegacy, -- cgit 0.0.5-2-1-g0f52 From 0dcfd785140ef95cf447b6a506e8fc73ef808686 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Tue, 3 Mar 2026 23:20:23 +0500 Subject: fix neoforge maven URLs --- meta/model/neoforge.py | 2 +- meta/run/generate_neoforge.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index 53bf67ba43..d2e4fe8846 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -21,7 +21,7 @@ class NeoForgeFile(MetaBase): ) def url(self, long_version): - return "https://maven.neoforged.net/net/neoforged/%s/%s/%s" % ( + return "https://maven.neoforged.net/releases/net/neoforged/%s/%s/%s" % ( self.artifact, long_version, self.filename(long_version), diff --git a/meta/run/generate_neoforge.py b/meta/run/generate_neoforge.py index 41ac950b7d..eab7fb33e3 100644 --- a/meta/run/generate_neoforge.py +++ b/meta/run/generate_neoforge.py @@ -64,7 +64,7 @@ def version_from_build_system_installer( ) installer_lib.downloads = MojangLibraryDownloads() installer_lib.downloads.artifact = MojangArtifact( - url="https://maven.neoforged.net/%s" % (installer_lib.name.path()), + url="https://maven.neoforged.net/releases/%s" % (installer_lib.name.path()), sha1=info.sha1hash, size=info.size, ) -- cgit 0.0.5-2-1-g0f52 From ca67d9498d3bef29c8660f5c3bd4013a45e98245 Mon Sep 17 00:00:00 2001 From: Ludgie Date: Tue, 17 Mar 2026 22:35:39 +0100 Subject: feat: ibm semeru runtime open edition support Signed-off-by: Ludgie --- meta/common/java.py | 3 + meta/model/java.py | 151 ++++++++++++++++++++++++++++------------------ meta/run/generate_java.py | 75 +++++++++++++++++------ meta/run/update_java.py | 82 +++++++++++++++++++++---- update.sh | 4 +- 5 files changed, 224 insertions(+), 91 deletions(-) (limited to 'meta') diff --git a/meta/common/java.py b/meta/common/java.py index ec13b2a55f..8b83f65aa0 100644 --- a/meta/common/java.py +++ b/meta/common/java.py @@ -4,11 +4,14 @@ BASE_DIR = "java_runtime" RELEASE_FILE = join(BASE_DIR, "releases.json") ADOPTIUM_DIR = join(BASE_DIR, "adoptium") +OPENJ9_DIR = join(BASE_DIR, "ibm") AZUL_DIR = join(BASE_DIR, "azul") ADOPTIUM_VERSIONS_DIR = join(ADOPTIUM_DIR, "versions") +OPENJ9_VERSIONS_DIR = join(OPENJ9_DIR, "versions") AZUL_VERSIONS_DIR = join(AZUL_DIR, "versions") JAVA_MINECRAFT_COMPONENT = "net.minecraft.java" JAVA_ADOPTIUM_COMPONENT = "net.adoptium.java" +JAVA_OPENJ9_COMPONENT = "com.ibm.java" JAVA_AZUL_COMPONENT = "com.azul.java" diff --git a/meta/model/java.py b/meta/model/java.py index b941860726..4a7571e491 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -18,7 +18,7 @@ class JavaRuntimeOS(StrEnum): MacOsX64 = "mac-os-x64" MacOsX86 = "mac-os-x86" # rare MacOsArm64 = "mac-os-arm64" - # MacOsArm32 = "mac-os-arm32" # doesn't exsist + # MacOsArm32 = "mac-os-arm32" # doesn't exist LinuxX64 = "linux-x64" LinuxX86 = "linux-x86" LinuxArm64 = "linux-arm64" @@ -123,15 +123,18 @@ class APIQuery(MetaBase): return urlencode(set_parts, doseq=True) -class AdoptiumJvmImpl(StrEnum): - Hostspot = "hotspot" +# Adoptx refers to both Adoptium (Eclipse Temurin) and AdoptOpenJDK (IBM Semeru Runtime Open Edition) +class AdoptxJvmImpl(StrEnum): + Hotspot = "hotspot" + OpenJ9 = "openj9" -class AdoptiumVendor(StrEnum): +class AdoptxVendor(StrEnum): Eclipse = "eclipse" + Ibm = "ibm" -class AdoptiumArchitecture(StrEnum): +class AdoptxArchitecture(StrEnum): X64 = "x64" X86 = "x86" X32 = "x32" @@ -144,22 +147,22 @@ class AdoptiumArchitecture(StrEnum): Riscv64 = "riscv64" -class AdoptiumReleaseType(StrEnum): - GenralAccess = "ga" +class AdoptxReleaseType(StrEnum): + GeneralAccess = "ga" EarlyAccess = "ea" -class AdoptiumSortMethod(StrEnum): +class AdoptxSortMethod(StrEnum): Default = "DEFAULT" Date = "DATE" -class AdoptiumSortOrder(StrEnum): +class AdoptxSortOrder(StrEnum): Asc = "ASC" Desc = "DESC" -class AdoptiumImageType(StrEnum): +class AdoptxImageType(StrEnum): Jdk = "jdk" Jre = "jre" Testimage = "testimage" @@ -169,12 +172,12 @@ class AdoptiumImageType(StrEnum): Sbom = "sbom" -class AdoptiumHeapSize(StrEnum): +class AdoptxHeapSize(StrEnum): Normal = "normal" Large = "large" -class AdoptiumProject(StrEnum): +class AdoptxProject(StrEnum): Jdk = "jdk" Valhalla = "valhalla" Metropolis = "metropolis" @@ -182,12 +185,12 @@ class AdoptiumProject(StrEnum): Shenandoah = "shenandoah" -class AdoptiumCLib(StrEnum): +class AdoptxCLib(StrEnum): Musl = "musl" Glibc = "glibc" -class AdoptiumOs(StrEnum): +class AdoptxOs(StrEnum): Linux = "linux" Windows = "windows" Mac = "mac" @@ -196,43 +199,72 @@ class AdoptiumOs(StrEnum): AlpineLinux = "alpine-linux" -ADOPTIUM_API_BASE = " https://api.adoptium.net" -ADOPTIUM_API_FEATURE_RELEASES = f"{ADOPTIUM_API_BASE}/v3/assets/feature_releases/{{feature_version}}/{{release_type}}" +ADOPTIUM_API_BASE = "https://api.adoptium.net" +OPENJ9_API_BASE = " https://api.adoptopenjdk.net" +ADOPTX_API_FEATURE_RELEASES = f"{{base_url}}/v3/assets/feature_releases/{{feature_version}}/{{release_type}}" # ?image_type={{image_type}}&heap_size={{heap_size}}&project={{project}}&vendor={{vendor}}&page_size={{page_size}}&page={{page}}&sort_method={{sort_method}}&sort_order={{sort_order}} -ADOPTIUM_API_AVAILABLE_RELEASES = f"{ADOPTIUM_API_BASE}/v3/info/available_releases" +ADOPTX_API_AVAILABLE_RELEASES = f"{{base_url}}/v3/info/available_releases" -class AdoptiumAPIFeatureReleasesQuery(APIQuery): - architecture: Optional[AdoptiumArchitecture] = None +class AdoptxAPIFeatureReleasesQuery(APIQuery): + architecture: Optional[AdoptxArchitecture] = None before: Optional[datetime] = None - c_lib: Optional[AdoptiumCLib] = None - heap_size: Optional[AdoptiumHeapSize] = AdoptiumHeapSize.Normal - image_type: Optional[AdoptiumImageType] = None - jvm_impl: Optional[AdoptiumJvmImpl] = None - os: Optional[AdoptiumOs] = None + c_lib: Optional[AdoptxCLib] = None + heap_size: Optional[AdoptxHeapSize] = AdoptxHeapSize.Normal + image_type: Optional[AdoptxImageType] = None + jvm_impl: Optional[AdoptxJvmImpl] = None + os: Optional[AdoptxOs] = None + vendor: Optional[AdoptxVendor] = None page_size: int = 10 page: int = 0 - project: Optional[AdoptiumProject] = AdoptiumProject.Jdk - sort_method: Optional[AdoptiumSortMethod] = AdoptiumSortMethod.Default - sort_order: Optional[AdoptiumSortOrder] = AdoptiumSortOrder.Desc - vendor: Optional[AdoptiumVendor] = AdoptiumVendor.Eclipse + project: Optional[AdoptxProject] = AdoptxProject.Jdk + sort_method: Optional[AdoptxSortMethod] = AdoptxSortMethod.Default + sort_order: Optional[AdoptxSortOrder] = AdoptxSortOrder.Desc -def adoptiumAPIFeatureReleasesUrl( - feature: int, - release_type: AdoptiumReleaseType = AdoptiumReleaseType.GenralAccess, - query: AdoptiumAPIFeatureReleasesQuery = AdoptiumAPIFeatureReleasesQuery(), +def adoptxAPIFeatureReleasesUrl( + base_url: str, + feature_version: int, + release_type: AdoptxReleaseType = AdoptxReleaseType.GeneralAccess, + query: AdoptxAPIFeatureReleasesQuery = AdoptxAPIFeatureReleasesQuery(), ): url = urlparse( - ADOPTIUM_API_FEATURE_RELEASES.format( - feature_version=feature, + ADOPTX_API_FEATURE_RELEASES.format( + base_url=base_url, + feature_version=feature_version, release_type=release_type.value, ) ) return urlunparse(url._replace(query=query.to_query())) -class AdoptiumAvailableReleases(MetaBase): +def adoptiumAPIFeatureReleasesUrl( + feature_version: int, + release_type: AdoptxReleaseType = AdoptxReleaseType.GeneralAccess, + query: AdoptxAPIFeatureReleasesQuery = AdoptxAPIFeatureReleasesQuery(), +): + return adoptxAPIFeatureReleasesUrl( + feature_version=feature_version, + release_type=release_type, + query=query, + base_url=ADOPTIUM_API_BASE, + ) + + +def openj9APIFeatureReleasesUrl( + feature_version: int, + release_type: AdoptxReleaseType = AdoptxReleaseType.GeneralAccess, + query: AdoptxAPIFeatureReleasesQuery = AdoptxAPIFeatureReleasesQuery(), +): + return adoptxAPIFeatureReleasesUrl( + feature_version=feature_version, + release_type=release_type, + query=query, + base_url=OPENJ9_API_BASE, + ) + + +class AdoptxAvailableReleases(MetaBase): available_releases: list[int] available_lts_releases: list[int] most_recent_lts: Optional[int] @@ -241,13 +273,13 @@ class AdoptiumAvailableReleases(MetaBase): tip_version: Optional[int] -class AdoptiumFile(MetaBase): +class AdoptxFile(MetaBase): name: str link: str size: Optional[int] -class AdoptiumPackage(AdoptiumFile): +class AdoptxPackage(AdoptxFile): checksum: Optional[str] checksum_link: Optional[str] signature_link: Optional[str] @@ -255,22 +287,22 @@ class AdoptiumPackage(AdoptiumFile): # we intentionally omit download_count -class AdoptiumBinary(MetaBase): +class AdoptxBinary(MetaBase): os: str - architecture: AdoptiumArchitecture - image_type: AdoptiumImageType - c_lib: Optional[AdoptiumCLib] - jvm_impl: AdoptiumJvmImpl - package: Optional[AdoptiumPackage] - installer: Optional[AdoptiumPackage] - heap_size: AdoptiumHeapSize + architecture: AdoptxArchitecture + image_type: AdoptxImageType + c_lib: Optional[AdoptxCLib] + jvm_impl: AdoptxJvmImpl + package: Optional[AdoptxPackage] + installer: Optional[AdoptxPackage] + heap_size: AdoptxHeapSize updated_at: datetime scm_ref: Optional[str] - project: AdoptiumProject + project: AdoptxProject # we intentionally omit download_count -class AdoptiumVersion(MetaBase): +class AdoptxVersion(MetaBase): major: Optional[int] minor: Optional[int] security: Optional[int] @@ -283,31 +315,31 @@ class AdoptiumVersion(MetaBase): optional: Optional[str] -class AdoptiumRelease(MetaBase): +class AdoptxRelease(MetaBase): release_id: str = Field(alias="id") release_link: str release_name: str timestamp: datetime updated_at: datetime - binaries: list[AdoptiumBinary] + binaries: list[AdoptxBinary] release_type: str - vendor: AdoptiumVendor - version_data: AdoptiumVersion - source: Optional[AdoptiumFile] - release_notes: Optional[AdoptiumFile] + vendor: AdoptxVendor + version_data: AdoptxVersion + source: Optional[AdoptxFile] + release_notes: Optional[AdoptxFile] # we intentionally omit download_count -class AdoptiumReleases(MetaBase): - __root__: list[AdoptiumRelease] +class AdoptxReleases(MetaBase): + __root__: list[AdoptxRelease] - def __iter__(self) -> Generator[tuple[str, AdoptiumRelease], None, None]: + def __iter__(self) -> Generator[tuple[str, AdoptxRelease], None, None]: yield from ((str(i), val) for i, val in enumerate(self.__root__)) - def __getitem__(self, item: int) -> AdoptiumRelease: + def __getitem__(self, item: int) -> AdoptxRelease: return self.__root__[item] - def append(self, rls: AdoptiumRelease): + def append(self, rls: AdoptxRelease): self.__root__.append(rls) @@ -556,7 +588,8 @@ class ZuluPackagesDetail(MetaBase): MOJANG_OS_NAMES = ["mac-os", "linux", "windows"] MOJANG_OS_ARCHITECTURES = [ - "x64" "x86", + "x64", + "x86", "arm64", "arm32", ] diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index 13e01a0496..257326542a 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -9,9 +9,12 @@ from meta.common import ensure_component_dir, launcher_path, upstream_path from meta.common.java import ( JAVA_MINECRAFT_COMPONENT, JAVA_ADOPTIUM_COMPONENT, + JAVA_OPENJ9_COMPONENT, JAVA_AZUL_COMPONENT, ADOPTIUM_DIR, ADOPTIUM_VERSIONS_DIR, + OPENJ9_DIR, + OPENJ9_VERSIONS_DIR, AZUL_DIR, AZUL_VERSIONS_DIR, ) @@ -25,11 +28,11 @@ from meta.model.java import ( JavaChecksumMeta, JavaChecksumType, JavaRuntimeDownloadType, - AdoptiumAvailableReleases, - AdoptiumReleases, - AdoptiumRelease, - AdoptiumImageType, - AdoptiumBinary, + AdoptxAvailableReleases, + AdoptxReleases, + AdoptxRelease, + AdoptxImageType, + AdoptxBinary, ZuluPackageList, ZuluPackageDetail, AzulJavaPackageType, @@ -193,9 +196,9 @@ def mojang_runtime_to_java_runtime( ) -def adoptium_release_binary_to_java_runtime( - rls: AdoptiumRelease, - binary: AdoptiumBinary, +def adoptx_release_binary_to_java_runtime( + rls: AdoptxRelease, + binary: AdoptxBinary, runtime_os: JavaRuntimeOS, ) -> JavaRuntimeMeta: assert binary.package is not None @@ -216,7 +219,13 @@ def adoptium_release_binary_to_java_runtime( ), build=rls.version_data.build, ) - rls_name = f"{rls.vendor}_temurin_{binary.image_type}{version}" + + if rls.vendor == "eclipse": + rls_distribution = "temurin" + elif rls.vendor == "ibm": + rls_distribution = "semeru-open" + + rls_name = f"{rls.vendor}_{rls_distribution}_{binary.image_type}{version}" return JavaRuntimeMeta( name=rls_name, vendor=rls.vendor, @@ -315,7 +324,7 @@ def main(): def add_java_runtime(runtime: JavaRuntimeMeta, major: int): if major not in javas: javas[major] = list[JavaRuntimeMeta]() - print(f"Regestering runtime: {runtime.name} for Java {major}") + print(f"Registering runtime: {runtime.name} for Java {major}") javas[major].append(runtime) # only add specific versions to the list @@ -349,18 +358,18 @@ def main(): print("Processing Adoptium Releases") adoptium_path = os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") if os.path.exists(adoptium_path): - adoptium_available_releases = AdoptiumAvailableReleases.parse_file( + adoptium_available_releases = AdoptxAvailableReleases.parse_file( adoptium_path ) for major in adoptium_available_releases.available_releases: - adoptium_releases = AdoptiumReleases.parse_file( + adoptium_releases = AdoptxReleases.parse_file( os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{major}.json") ) for _, rls in adoptium_releases: for binary in rls.binaries: if ( binary.package is None - or binary.image_type is not AdoptiumImageType.Jre + or binary.image_type is not AdoptxImageType.Jre ): continue binary_arch = translate_arch(str(binary.architecture)) @@ -370,13 +379,44 @@ def main(): continue java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") - runtime = adoptium_release_binary_to_java_runtime( + runtime = adoptx_release_binary_to_java_runtime( rls, binary, java_os ) add_java_runtime(runtime, major) - writeJavas(javas=javas, uid=JAVA_ADOPTIUM_COMPONENT) javas = {} + + print("Processing OpenJ9 Releases") + openj9_path = os.path.join(UPSTREAM_DIR, OPENJ9_DIR, "available_releases.json") + if os.path.exists(openj9_path): + openj9_available_releases = AdoptxAvailableReleases.parse_file( + openj9_path + ) + for major in openj9_available_releases.available_releases: + openj9_releases = AdoptxReleases.parse_file( + os.path.join(UPSTREAM_DIR, OPENJ9_VERSIONS_DIR, f"java{major}.json") + ) + for _, rls in openj9_releases: + for binary in rls.binaries: + if ( + binary.package is None + or binary.image_type is not AdoptxImageType.Jre + ): + continue + binary_arch = translate_arch(str(binary.architecture)) + binary_os = translate_os(str(binary.os)) + if binary_arch is None or binary_os is None: + print(f"Ignoring release for {binary.os} {binary.architecture}") + continue + + java_os = JavaRuntimeOS(f"{binary_os}-{binary_arch}") + runtime = adoptx_release_binary_to_java_runtime( + rls, binary, java_os + ) + add_java_runtime(runtime, major) + writeJavas(javas=javas, uid=JAVA_OPENJ9_COMPONENT) + javas = {} + print("Processing Azul Packages") azul_path = os.path.join(UPSTREAM_DIR, AZUL_DIR, "packages.json") if os.path.exists(azul_path): @@ -410,7 +450,7 @@ def main(): writeJavas(javas=javas, uid=JAVA_AZUL_COMPONENT) javas = {} - # constructs the missing mojang javas based on adoptium or azul + # constructs the missing mojang javas based on adoptium or azul (do not consider openj9 since it is for more niche cases) def get_mojang_extra_java( mojang_component: MojangJavaComponent, java_os: JavaRuntimeOS ) -> JavaRuntimeMeta | None: @@ -434,6 +474,7 @@ def main(): mojang_java_manifest = JavaIndex.parse_file( os.path.join(UPSTREAM_DIR, JAVA_MANIFEST_FILE) ) + # print(mojang_java_manifest) for mojang_os_name in mojang_java_manifest: if mojang_os_name == MojangJavaOsName.Gamecore: continue # empty @@ -471,7 +512,7 @@ def main(): major = int(mojang_runtime.version.name.partition(".")[0]) runtime = mojang_runtime_to_java_runtime(mojang_runtime, comp, java_os) add_java_runtime(runtime, major) - # mojang doesn't provide any versions for the following systems so borrow info from adoptium/azul + # mojang doesn't provide any versions for the following systems so borrow info from adoptium/azul (do not consider openj9 since it is for more niche cases) for java_os in [ JavaRuntimeOS.WindowsArm32, JavaRuntimeOS.LinuxArm32, diff --git a/meta/run/update_java.py b/meta/run/update_java.py index 326fb5f924..bc9ad8db1f 100644 --- a/meta/run/update_java.py +++ b/meta/run/update_java.py @@ -4,18 +4,26 @@ from meta.common import upstream_path, ensure_upstream_dir, default_session from meta.common.java import ( BASE_DIR, ADOPTIUM_DIR, + OPENJ9_DIR, AZUL_DIR, ADOPTIUM_VERSIONS_DIR, + OPENJ9_VERSIONS_DIR, AZUL_VERSIONS_DIR, ) from meta.model.java import ( - ADOPTIUM_API_AVAILABLE_RELEASES, + ADOPTIUM_API_BASE, + OPENJ9_API_BASE, + ADOPTX_API_AVAILABLE_RELEASES, + adoptxAPIFeatureReleasesUrl, adoptiumAPIFeatureReleasesUrl, - AdoptiumImageType, - AdoptiumAPIFeatureReleasesQuery, - AdoptiumAvailableReleases, - AdoptiumRelease, - AdoptiumReleases, + openj9APIFeatureReleasesUrl, + AdoptxJvmImpl, + AdoptxVendor, + AdoptxImageType, + AdoptxAPIFeatureReleasesQuery, + AdoptxAvailableReleases, + AdoptxRelease, + AdoptxReleases, azulApiPackagesUrl, AzulApiPackagesQuery, ZuluPackage, @@ -33,8 +41,10 @@ UPSTREAM_DIR = upstream_path() ensure_upstream_dir(BASE_DIR) ensure_upstream_dir(ADOPTIUM_DIR) +ensure_upstream_dir(OPENJ9_DIR) ensure_upstream_dir(AZUL_DIR) ensure_upstream_dir(ADOPTIUM_VERSIONS_DIR) +ensure_upstream_dir(OPENJ9_VERSIONS_DIR) ensure_upstream_dir(AZUL_VERSIONS_DIR) @@ -43,10 +53,10 @@ sess = default_session() def main(): print("Getting Adoptium Release Manifests ") - r = sess.get(ADOPTIUM_API_AVAILABLE_RELEASES) + r = sess.get(ADOPTX_API_AVAILABLE_RELEASES.format(base_url=ADOPTIUM_API_BASE)) r.raise_for_status() - available = AdoptiumAvailableReleases(**r.json()) + available = AdoptxAvailableReleases(**r.json()) available_releases_file = os.path.join( UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json" @@ -58,11 +68,11 @@ def main(): page_size = 10 - releases_for_feature: list[AdoptiumRelease] = [] + releases_for_feature: list[AdoptxRelease] = [] page = 0 while True: - query = AdoptiumAPIFeatureReleasesQuery( - image_type=AdoptiumImageType.Jre, page_size=page_size, page=page + query = AdoptxAPIFeatureReleasesQuery( + image_type=AdoptxImageType.Jre, page_size=page_size, page=page, jvm_impl=AdoptxJvmImpl.Hotspot, vendor=AdoptxVendor.Eclipse ) api_call = adoptiumAPIFeatureReleasesUrl(feature, query=query) print("Fetching JRE Page:", page, api_call) @@ -72,7 +82,7 @@ def main(): else: r_rls.raise_for_status() - releases = list(AdoptiumRelease(**rls) for rls in r_rls.json()) + releases = list(AdoptxRelease(**rls) for rls in r_rls.json()) releases_for_feature.extend(releases) if len(r_rls.json()) < page_size: @@ -80,12 +90,58 @@ def main(): page += 1 print("Total Adoptium releases for feature:", len(releases_for_feature)) - releases = AdoptiumReleases(__root__=releases_for_feature) + releases = AdoptxReleases(__root__=releases_for_feature) feature_file = os.path.join( UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{feature}.json" ) releases.write(feature_file) + print("Getting OpenJ9 Release Manifests ") + r = sess.get(ADOPTX_API_AVAILABLE_RELEASES.format(base_url=OPENJ9_API_BASE)) + r.raise_for_status() + + available = AdoptxAvailableReleases(**r.json()) + + available_releases_file = os.path.join( + UPSTREAM_DIR, OPENJ9_DIR, "available_releases.json" + ) + available.write(available_releases_file) + + for feature in available.available_releases: + print("Getting Manifests for OpenJ9 feature release:", feature) + + page_size = 10 + + releases_for_feature: list[AdoptxRelease] = [] + page = 0 + while True: + query = AdoptxAPIFeatureReleasesQuery( + image_type=AdoptxImageType.Jre, page_size=page_size, page=page, jvm_impl=AdoptxJvmImpl.OpenJ9, vendor=AdoptxVendor.Ibm + ) + api_call = openj9APIFeatureReleasesUrl(feature, query=query) + print("Fetching JRE Page:", page, api_call) + r_rls = sess.get(api_call) + if r_rls.status_code == 404: + break + else: + r_rls.raise_for_status() + + releases = list(AdoptxRelease(**rls) for rls in r_rls.json()) + releases_for_feature.extend(releases) + + if len(r_rls.json()) < page_size: + break + page += 1 + + print("Total OpenJ9 releases for feature:", len(releases_for_feature)) + releases = AdoptxReleases(__root__=releases_for_feature) + if len(releases_for_feature) == 0: + continue + feature_file = os.path.join( + UPSTREAM_DIR, OPENJ9_VERSIONS_DIR, f"java{feature}.json" + ) + releases.write(feature_file) + print("Getting Azul Release Manifests") zulu_packages: list[ZuluPackage] = [] page = 1 diff --git a/update.sh b/update.sh index e416d81173..205bf01a2b 100755 --- a/update.sh +++ b/update.sh @@ -49,7 +49,7 @@ if [ "${DEPLOY_TO_GIT}" = true ]; then upstream_git add fabric/loader-installer-json/*.json fabric/meta-v2/*.json fabric/jars/*.json || fail_in upstream_git add quilt/loader-installer-json/*.json quilt/meta-v3/*.json quilt/jars/*.json || fail_in upstream_git add liteloader/*.json || fail_in - upstream_git add java_runtime/adoptium/available_releases.json java_runtime/adoptium/versions/*.json java_runtime/azul/packages.json java_runtime/azul/versions/*.json || fail_in + upstream_git add java_runtime/adoptium/available_releases.json java_runtime/adoptium/versions/*.json java_runtime/azul/packages.json java_runtime/azul/versions/*.json java_runtime/ibm/available_releases.json java_runtime/ibm/versions/*.json || fail_in if ! upstream_git diff --cached --exit-code; then upstream_git commit -a -m "Update ${currentDate}" || fail_in upstream_git push || exit 1 @@ -74,7 +74,7 @@ if [ "${DEPLOY_TO_GIT}" = true ]; then launcher_git add net.fabricmc.fabric-loader/* net.fabricmc.intermediary/* || fail_out launcher_git add org.quiltmc.quilt-loader/* || fail_out # TODO: add Quilt hashed, once it is actually used launcher_git add com.mumfrey.liteloader/* || fail_out - launcher_git add net.minecraft.java/* net.adoptium.java/* com.azul.java/* || fail_out + launcher_git add net.minecraft.java/* net.adoptium.java/* com.azul.java/* com.ibm.java/* || fail_out if ! launcher_git diff --cached --exit-code; then launcher_git commit -a -m "Update ${currentDate}" || fail_out -- cgit 0.0.5-2-1-g0f52 From a4ca73c04d9f9becee73c75acbe6c9bf15986c45 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 16 Dec 2024 21:00:29 +0200 Subject: Chache sha1 file Signed-off-by: Trial97 --- meta/common/__init__.py | 25 +++++++++++++++++++++ meta/run/generate_forge.py | 7 +----- meta/run/generate_neoforge.py | 7 +----- meta/run/update_forge.py | 51 +++++++++++++++++++++---------------------- meta/run/update_neoforge.py | 45 ++++++++++++++++++++------------------ 5 files changed, 76 insertions(+), 59 deletions(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 16a4f507bf..8e42933942 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -1,6 +1,8 @@ import os import os.path import datetime +import hashlib +import sys from urllib.parse import urlparse from typing import Any, Optional @@ -95,3 +97,26 @@ def remove_files(file_paths): os.remove(file_path) except Exception as e: print(e) + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def filehash(filename, hashtype, blocksize=65536): + hashtype = hashtype() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + hashtype.update(block) + return hashtype.hexdigest() + + +def get_file_sha1_from_file(file_name, sha1_file): + if os.path.isfile(sha1_file): + with open(sha1_file, "r") as file: + return file.read() + + new_sha1 = filehash(file_name, hashlib.sha1) + with open(sha1_file, "w") as file: + file.write(new_sha1) + return diff --git a/meta/run/generate_forge.py b/meta/run/generate_forge.py index 95b5ac39cb..a01f503ebe 100755 --- a/meta/run/generate_forge.py +++ b/meta/run/generate_forge.py @@ -1,11 +1,10 @@ import os import re -import sys from packaging import version as pversion from operator import attrgetter from typing import Collection -from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common import ensure_component_dir, launcher_path, upstream_path, eprint from meta.common.forge import ( FORGE_COMPONENT, INSTALLER_MANIFEST_DIR, @@ -44,10 +43,6 @@ UPSTREAM_DIR = upstream_path() ensure_component_dir(FORGE_COMPONENT) -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - # Construct a set of libraries out of a Minecraft version file, for filtering. mc_version_cache = {} diff --git a/meta/run/generate_neoforge.py b/meta/run/generate_neoforge.py index eab7fb33e3..5c6f965435 100644 --- a/meta/run/generate_neoforge.py +++ b/meta/run/generate_neoforge.py @@ -1,11 +1,10 @@ from copy import deepcopy import os import re -import sys from operator import attrgetter from typing import Collection -from meta.common import ensure_component_dir, launcher_path, upstream_path +from meta.common import ensure_component_dir, launcher_path, upstream_path, eprint from meta.common.neoforge import ( NEOFORGE_COMPONENT, INSTALLER_MANIFEST_DIR, @@ -38,10 +37,6 @@ UPSTREAM_DIR = upstream_path() ensure_component_dir(NEOFORGE_COMPONENT) -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - def version_from_build_system_installer( installer: MojangVersion, profile: NeoForgeInstallerProfileV2, diff --git a/meta/run/update_forge.py b/meta/run/update_forge.py index 5a86727199..30c701fb32 100755 --- a/meta/run/update_forge.py +++ b/meta/run/update_forge.py @@ -7,7 +7,6 @@ import hashlib import json import os import re -import sys import zipfile from contextlib import suppress from datetime import datetime @@ -21,6 +20,9 @@ from meta.common import ( ensure_upstream_dir, default_session, remove_files, + eprint, + filehash, + get_file_sha1_from_file, ) from meta.common.forge import ( JARS_DIR, @@ -43,6 +45,7 @@ from meta.model.forge import ( InstallerInfo, ForgeLegacyInfo, ) +from meta.common.http import download_binary_file from meta.model.mojang import MojangVersion UPSTREAM_DIR = upstream_path() @@ -58,18 +61,6 @@ LEGACYINFO_PATH = os.path.join(UPSTREAM_DIR, LEGACYINFO_FILE) sess = default_session() -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - -def filehash(filename, hashtype, blocksize=65536): - hashtype = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - hashtype.update(block) - return hashtype.hexdigest() - - def get_single_forge_files_manifest(longversion): print(f"Getting Forge manifest for {longversion}") path_thing = UPSTREAM_DIR + "/forge/files_manifests/%s.json" % longversion @@ -297,15 +288,20 @@ def main(): UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version ) + new_sha1 = None + sha1_file = jar_path + ".sha1" if not os.path.isfile(jar_path): remove_files([profile_path, installer_info_path]) else: - fileSha1 = filehash(jar_path, hashlib.sha1) + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) try: rfile = sess.get(version.url() + ".sha1") rfile.raise_for_status() - if fileSha1 != rfile.text.strip(): - remove_files([jar_path, profile_path, installer_info_path]) + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files( + [jar_path, profile_path, installer_info_path, sha1_file] + ) except Exception as e: eprint("Failed to check sha1 %s" % version.url()) eprint("Error is %s" % e) @@ -318,11 +314,18 @@ def main(): # grab the installer if it's not there if not os.path.isfile(jar_path): eprint("Downloading %s" % version.url()) - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - with open(jar_path, "wb") as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) + download_binary_file(sess, jar_path, version.url()) + if new_sha1 is None: + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + except Exception as e: + eprint("Failed to download new sha1 %s" % version.url()) + eprint("Error is %s" % e) + if new_sha1 is not None: # this is in case the fetch failed + with open(sha1_file, "w") as file: + file.write(new_sha1) eprint("Processing %s" % version.url()) # harvestables from the installer @@ -387,11 +390,7 @@ def main(): if not os.path.isfile(LEGACYINFO_PATH): # grab the jar/zip if it's not there if not os.path.isfile(jar_path): - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() - with open(jar_path, "wb") as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) + download_binary_file(sess, jar_path, version.url()) # find the latest timestamp in the zip file tstamp = datetime.fromtimestamp(0) with zipfile.ZipFile(jar_path) as jar: diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index ee8d6ff950..d9b7cc0f64 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -7,7 +7,6 @@ import hashlib import json import os import re -import sys import zipfile from contextlib import suppress from datetime import datetime @@ -22,7 +21,11 @@ from meta.common import ( ensure_upstream_dir, default_session, remove_files, + eprint, + filehash, + get_file_sha1_from_file, ) +from meta.common.http import download_binary_file from meta.common.neoforge import ( JARS_DIR, INSTALLER_INFO_DIR, @@ -52,18 +55,6 @@ ensure_upstream_dir(FILE_MANIFEST_DIR) sess = default_session() -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - -def filehash(filename, hashtype, blocksize=65536): - hashtype = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - hashtype.update(block) - return hashtype.hexdigest() - - def find_nth(haystack, needle, n): start = haystack.find(needle) while start >= 0 and n > 1: @@ -221,15 +212,20 @@ def main(): UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version ) + new_sha1 = None + sha1_file = jar_path + ".sha1" if not os.path.isfile(jar_path): remove_files([profile_path, installer_info_path]) else: - fileSha1 = filehash(jar_path, hashlib.sha1) + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) try: rfile = sess.get(version.url() + ".sha1") rfile.raise_for_status() - if fileSha1 != rfile.text.strip(): - remove_files([jar_path, profile_path, installer_info_path]) + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files( + [jar_path, profile_path, installer_info_path, sha1_file] + ) except Exception as e: eprint("Failed to check sha1 %s" % version.url()) eprint("Error is %s" % e) @@ -243,16 +239,23 @@ def main(): if not os.path.isfile(jar_path): eprint("Downloading %s" % version.url()) try: - rfile = sess.get(version.url(), stream=True) - rfile.raise_for_status() Path(jar_path).parent.mkdir(parents=True, exist_ok=True) - with open(jar_path, "wb") as f: - for chunk in rfile.iter_content(chunk_size=128): - f.write(chunk) + download_binary_file(sess, jar_path, version.url()) except Exception as e: eprint("Failed to download %s" % version.url()) eprint("Error is %s" % e) continue + if new_sha1 is None: + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + except Exception as e: + eprint("Failed to download new sha1 %s" % version.url()) + eprint("Error is %s" % e) + if new_sha1 is not None: # this is in case the fetch failed + with open(sha1_file, "w") as file: + file.write(new_sha1) eprint("Processing %s" % version.url()) # harvestables from the installer -- cgit 0.0.5-2-1-g0f52 From cc909c32545188e1168fc725c652ff86f74f97a2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 16 Apr 2025 16:19:17 +0300 Subject: chore:add type annotations Signed-off-by: Trial97 --- meta/common/__init__.py | 14 ++++++++------ meta/run/index.py | 17 +++++------------ meta/run/update_fabric.py | 8 -------- meta/run/update_forge.py | 10 +++++----- meta/run/update_neoforge.py | 6 +++--- meta/run/update_quilt.py | 8 -------- 6 files changed, 21 insertions(+), 42 deletions(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 8e42933942..1f358cdbd7 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -4,7 +4,7 @@ import datetime import hashlib import sys from urllib.parse import urlparse -from typing import Any, Optional +from typing import Any, Optional, Callable import requests from cachecontrol import CacheControl # type: ignore @@ -90,7 +90,7 @@ def default_session(): return sess -def remove_files(file_paths): +def remove_files(file_paths: list[str]) -> None: for file_path in file_paths: try: if os.path.isfile(file_path): @@ -103,7 +103,9 @@ def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) -def filehash(filename, hashtype, blocksize=65536): +def file_hash( + filename: str, hashtype: Callable[[], "hashlib._Hash"], blocksize: int = 65536 +) -> str: hashtype = hashtype() with open(filename, "rb") as f: for block in iter(lambda: f.read(blocksize), b""): @@ -111,12 +113,12 @@ def filehash(filename, hashtype, blocksize=65536): return hashtype.hexdigest() -def get_file_sha1_from_file(file_name, sha1_file): +def get_file_sha1_from_file(file_name: str, sha1_file: str) -> Optional[str]: if os.path.isfile(sha1_file): with open(sha1_file, "r") as file: return file.read() - new_sha1 = filehash(file_name, hashlib.sha1) + new_sha1 = file_hash(file_name, hashlib.sha1) with open(sha1_file, "w") as file: file.write(new_sha1) - return + return None diff --git a/meta/run/index.py b/meta/run/index.py index 23dc2336ea..22abea8457 100755 --- a/meta/run/index.py +++ b/meta/run/index.py @@ -2,7 +2,9 @@ import hashlib import os from operator import attrgetter -from meta.common import launcher_path +from meta.common import launcher_path, file_hash + + from meta.model import MetaVersion, MetaPackage from meta.model.index import ( MetaPackageIndex, @@ -14,15 +16,6 @@ from meta.model.index import ( LAUNCHER_DIR = launcher_path() -# take the hash type (like hashlib.md5) and filename, return hex string of hash -def hash_file(hash_fn, file_name): - hash_instance = hash_fn() - with open(file_name, "rb") as f: - for chunk in iter(lambda: f.read(4096), b""): - hash_instance.update(chunk) - return hash_instance.hexdigest() - - # ignore these files when indexing versions ignore = {"index.json", "package.json", ".git", ".github"} @@ -50,7 +43,7 @@ for package in sorted(os.listdir(LAUNCHER_DIR)): continue # parse and hash the version file filepath = LAUNCHER_DIR + "/%s/%s" % (package, filename) - filehash = hash_file(hashlib.sha256, filepath) + filehash = file_hash(filepath, hashlib.sha256) versionFile = MetaVersion.parse_file(filepath) is_recommended = versionFile.version in recommendedVersions @@ -71,7 +64,7 @@ for package in sorted(os.listdir(LAUNCHER_DIR)): # insert entry into the package index packageEntry = MetaPackageIndexEntry( - uid=package, name=sharedData.name, sha256=hash_file(hashlib.sha256, outFilePath) + uid=package, name=sharedData.name, sha256=file_hash(outFilePath, hashlib.sha256) ) packages.packages.append(packageEntry) diff --git a/meta/run/update_fabric.py b/meta/run/update_fabric.py index e0c1d819c9..d19540b5e4 100755 --- a/meta/run/update_fabric.py +++ b/meta/run/update_fabric.py @@ -30,14 +30,6 @@ ensure_upstream_dir(META_DIR) sess = default_session() -def filehash(filename, hashtype, blocksize=65536): - h = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - h.update(block) - return h.hexdigest() - - def get_maven_url(maven_key, server, ext): parts = maven_key.split(":", 3) maven_ver_url = ( diff --git a/meta/run/update_forge.py b/meta/run/update_forge.py index 30c701fb32..7ec9e45023 100755 --- a/meta/run/update_forge.py +++ b/meta/run/update_forge.py @@ -21,7 +21,7 @@ from meta.common import ( default_session, remove_files, eprint, - filehash, + file_hash, get_file_sha1_from_file, ) from meta.common.forge import ( @@ -376,8 +376,8 @@ def main(): # installer info v1 if not os.path.isfile(installer_info_path): installer_info = InstallerInfo() - installer_info.sha1hash = filehash(jar_path, hashlib.sha1) - installer_info.sha256hash = filehash(jar_path, hashlib.sha256) + installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) + installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) installer_info.size = os.path.getsize(jar_path) installer_info.write(installer_info_path) else: @@ -400,8 +400,8 @@ def main(): tstamp = tstamp_new legacy_info = ForgeLegacyInfo() legacy_info.release_time = tstamp - legacy_info.sha1 = filehash(jar_path, hashlib.sha1) - legacy_info.sha256 = filehash(jar_path, hashlib.sha256) + legacy_info.sha1 = file_hash(jar_path, hashlib.sha1) + legacy_info.sha256 = file_hash(jar_path, hashlib.sha256) legacy_info.size = os.path.getsize(jar_path) legacy_info_list.number[key] = legacy_info diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index d9b7cc0f64..186edb253c 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -22,7 +22,7 @@ from meta.common import ( default_session, remove_files, eprint, - filehash, + file_hash, get_file_sha1_from_file, ) from meta.common.http import download_binary_file @@ -305,8 +305,8 @@ def main(): # installer info v1 if not os.path.isfile(installer_info_path): installer_info = InstallerInfo() - installer_info.sha1hash = filehash(jar_path, hashlib.sha1) - installer_info.sha256hash = filehash(jar_path, hashlib.sha256) + installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) + installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) installer_info.size = os.path.getsize(jar_path) installer_info.write(installer_info_path) diff --git a/meta/run/update_quilt.py b/meta/run/update_quilt.py index 5f3c40caa8..2f3160265d 100755 --- a/meta/run/update_quilt.py +++ b/meta/run/update_quilt.py @@ -22,14 +22,6 @@ ensure_upstream_dir(META_DIR) sess = default_session() -def filehash(filename, hashtype, blocksize=65536): - h = hashtype() - with open(filename, "rb") as f: - for block in iter(lambda: f.read(blocksize), b""): - h.update(block) - return h.hexdigest() - - def get_maven_url(maven_key, server, ext): parts = maven_key.split(":", 3) maven_ver_url = ( -- cgit 0.0.5-2-1-g0f52 From a3ec304d1625d4659ed0c49a358a7a29372c9208 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 5 Jul 2024 11:31:41 +0300 Subject: make forge and neoforge concurrent Signed-off-by: Trial97 --- meta/model/java.py | 4 +- meta/model/neoforge.py | 1 + meta/run/generate_java.py | 18 +-- meta/run/generate_neoforge.py | 12 +- meta/run/update_forge.py | 285 +++++++++++++++++++++--------------------- meta/run/update_java.py | 16 ++- meta/run/update_neoforge.py | 252 +++++++++++++++++++------------------ 7 files changed, 299 insertions(+), 289 deletions(-) (limited to 'meta') diff --git a/meta/model/java.py b/meta/model/java.py index 4a7571e491..c3efde9292 100644 --- a/meta/model/java.py +++ b/meta/model/java.py @@ -201,7 +201,9 @@ class AdoptxOs(StrEnum): ADOPTIUM_API_BASE = "https://api.adoptium.net" OPENJ9_API_BASE = " https://api.adoptopenjdk.net" -ADOPTX_API_FEATURE_RELEASES = f"{{base_url}}/v3/assets/feature_releases/{{feature_version}}/{{release_type}}" +ADOPTX_API_FEATURE_RELEASES = ( + f"{{base_url}}/v3/assets/feature_releases/{{feature_version}}/{{release_type}}" +) # ?image_type={{image_type}}&heap_size={{heap_size}}&project={{project}}&vendor={{vendor}}&page_size={{page_size}}&page={{page}}&sort_method={{sort_method}}&sort_order={{sort_order}} ADOPTX_API_AVAILABLE_RELEASES = f"{{base_url}}/v3/info/available_releases" diff --git a/meta/model/neoforge.py b/meta/model/neoforge.py index d2e4fe8846..ccdb325a23 100644 --- a/meta/model/neoforge.py +++ b/meta/model/neoforge.py @@ -46,6 +46,7 @@ class NeoForgeMCVersionInfo(MetaBase): class DerivedNeoForgeIndex(MetaBase): versions: Dict[str, NeoForgeEntry] = Field({}) + class FMLLib( MetaBase ): # old ugly stuff. Maybe merge this with Library or Library later diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index 257326542a..4c6c261719 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -344,12 +344,10 @@ def main(): and major in [8, 17, 21, 25] ) or ( - runtime.runtime_os - in [ - JavaRuntimeOS.LinuxX86, - JavaRuntimeOS.LinuxRiscv64 - ] - and major in [17, 21, 25]) + runtime.runtime_os + in [JavaRuntimeOS.LinuxX86, JavaRuntimeOS.LinuxRiscv64] + and major in [17, 21, 25] + ) ): if major not in extra_mojang_javas: extra_mojang_javas[major] = list[JavaRuntimeMeta]() @@ -358,9 +356,7 @@ def main(): print("Processing Adoptium Releases") adoptium_path = os.path.join(UPSTREAM_DIR, ADOPTIUM_DIR, "available_releases.json") if os.path.exists(adoptium_path): - adoptium_available_releases = AdoptxAvailableReleases.parse_file( - adoptium_path - ) + adoptium_available_releases = AdoptxAvailableReleases.parse_file(adoptium_path) for major in adoptium_available_releases.available_releases: adoptium_releases = AdoptxReleases.parse_file( os.path.join(UPSTREAM_DIR, ADOPTIUM_VERSIONS_DIR, f"java{major}.json") @@ -389,9 +385,7 @@ def main(): print("Processing OpenJ9 Releases") openj9_path = os.path.join(UPSTREAM_DIR, OPENJ9_DIR, "available_releases.json") if os.path.exists(openj9_path): - openj9_available_releases = AdoptxAvailableReleases.parse_file( - openj9_path - ) + openj9_available_releases = AdoptxAvailableReleases.parse_file(openj9_path) for major in openj9_available_releases.available_releases: openj9_releases = AdoptxReleases.parse_file( os.path.join(UPSTREAM_DIR, OPENJ9_VERSIONS_DIR, f"java{major}.json") diff --git a/meta/run/generate_neoforge.py b/meta/run/generate_neoforge.py index 5c6f965435..de32256869 100644 --- a/meta/run/generate_neoforge.py +++ b/meta/run/generate_neoforge.py @@ -139,20 +139,18 @@ def main(): installer = MojangVersion.parse_file(installer_version_filepath) profile = NeoForgeInstallerProfileV2.parse_file(profile_filepath) v = version_from_build_system_installer(installer, profile, version) - - #we can get the minecraft version from the profile json info, so let's just do that instead of hacky regex - v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=profile.minecraft)] + + # we can get the minecraft version from the profile json info, so let's just do that instead of hacky regex + v.requires = [Dependency(uid=MINECRAFT_COMPONENT, equals=profile.minecraft)] # If we do not have the corresponding Minecraft version, we ignore it if not os.path.isfile( - os.path.join( - LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{profile.minecraft}.json" - ) + os.path.join(LAUNCHER_DIR, MINECRAFT_COMPONENT, f"{profile.minecraft}.json") ): eprint( "Skipping %s with no corresponding Minecraft version %s" % (key, profile.minecraft) ) - continue + continue v.write(os.path.join(LAUNCHER_DIR, NEOFORGE_COMPONENT, f"{v.version}.json")) recommended_versions.sort() diff --git a/meta/run/update_forge.py b/meta/run/update_forge.py index 7ec9e45023..59bdbeb29e 100755 --- a/meta/run/update_forge.py +++ b/meta/run/update_forge.py @@ -1,7 +1,8 @@ """ - Get the source files necessary for generating Forge versions +Get the source files necessary for generating Forge versions """ +import concurrent.futures import copy import hashlib import json @@ -136,6 +137,109 @@ def get_single_forge_files_manifest(longversion): return ret_dict +def process_forge_version(version, jar_path): + installer_info_path = ( + UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + "/forge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version + ) + + new_sha1 = None + sha1_file = jar_path + ".sha1" + if not os.path.isfile(jar_path): + remove_files([profile_path, installer_info_path]) + else: + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files([jar_path, profile_path, installer_info_path, sha1_file]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) + + installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile( + installer_info_path + ) + + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + download_binary_file(sess, jar_path, version.url()) + if new_sha1 is None: + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + except Exception as e: + eprint("Failed to download new sha1 %s" % version.url()) + eprint("Error is %s" % e) + if new_sha1 is not None: # this is in case the fetch failed + with open(sha1_file, "w") as file: + file.write(new_sha1) + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + ForgeInstallerProfile.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + try: + ForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) + installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) + + def main(): # get the remote version list fragments r = sess.get( @@ -260,150 +364,49 @@ def main(): print("Grabbing installers and dumping installer profiles...") # get the installer jars - if needed - and get the installer profiles out of them - for key, entry in new_index.versions.items(): - eprint("Updating Forge %s" % key) - if entry.mc_version is None: - eprint("Skipping %d with invalid MC version" % entry.build) - continue - - version = ForgeVersion(entry) - if version.url() is None: - eprint("Skipping %d with no valid files" % version.build) - continue - if version.long_version in BAD_VERSIONS: - eprint(f"Skipping bad version {version.long_version}") - continue + with concurrent.futures.ThreadPoolExecutor() as executor: + for key, entry in new_index.versions.items(): + eprint("Updating Forge %s" % key) + if entry.mc_version is None: + eprint("Skipping %d with invalid MC version" % entry.build) + continue - jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) + version = ForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + continue + if version.long_version in BAD_VERSIONS: + eprint(f"Skipping bad version {version.long_version}") + continue - if version.uses_installer(): - installer_info_path = ( - UPSTREAM_DIR + "/forge/installer_info/%s.json" % version.long_version - ) - profile_path = ( - UPSTREAM_DIR - + "/forge/installer_manifests/%s.json" % version.long_version - ) - version_file_path = ( - UPSTREAM_DIR + "/forge/version_manifests/%s.json" % version.long_version - ) + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) - new_sha1 = None - sha1_file = jar_path + ".sha1" - if not os.path.isfile(jar_path): - remove_files([profile_path, installer_info_path]) + if version.uses_installer(): + executor.submit(process_forge_version, version, jar_path) else: - fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) - try: - rfile = sess.get(version.url() + ".sha1") - rfile.raise_for_status() - new_sha1 = rfile.text.strip() - if fileSha1 != new_sha1: - remove_files( - [jar_path, profile_path, installer_info_path, sha1_file] - ) - except Exception as e: - eprint("Failed to check sha1 %s" % version.url()) - eprint("Error is %s" % e) - - installer_refresh_required = not os.path.isfile( - profile_path - ) or not os.path.isfile(installer_info_path) - - if installer_refresh_required: - # grab the installer if it's not there - if not os.path.isfile(jar_path): - eprint("Downloading %s" % version.url()) - download_binary_file(sess, jar_path, version.url()) - if new_sha1 is None: - try: - rfile = sess.get(version.url() + ".sha1") - rfile.raise_for_status() - new_sha1 = rfile.text.strip() - except Exception as e: - eprint("Failed to download new sha1 %s" % version.url()) - eprint("Error is %s" % e) - if new_sha1 is not None: # this is in case the fetch failed - with open(sha1_file, "w") as file: - file.write(new_sha1) - - eprint("Processing %s" % version.url()) - # harvestables from the installer - if not os.path.isfile(profile_path): - print(jar_path) - with zipfile.ZipFile(jar_path) as jar: - with suppress(KeyError): - with jar.open("version.json") as profile_zip_entry: - version_data = profile_zip_entry.read() - - # Process: does it parse? - MojangVersion.parse_raw(version_data) - - with open(version_file_path, "wb") as versionJsonFile: - versionJsonFile.write(version_data) - versionJsonFile.close() - - with jar.open("install_profile.json") as profile_zip_entry: - install_profile_data = profile_zip_entry.read() - - # Process: does it parse? - is_parsable = False - exception = None - try: - ForgeInstallerProfile.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - try: - ForgeInstallerProfileV2.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - - if not is_parsable: - if version.is_supported(): - raise exception - else: - eprint( - "Version %s is not supported and won't be generated later." - % version.long_version - ) - - with open(profile_path, "wb") as profileFile: - profileFile.write(install_profile_data) - profileFile.close() - - # installer info v1 - if not os.path.isfile(installer_info_path): - installer_info = InstallerInfo() - installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) - installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) - installer_info.size = os.path.getsize(jar_path) - installer_info.write(installer_info_path) - else: - # ignore the two versions without install manifests and jar mod class files - # TODO: fix those versions? - if version.mc_version_sane == "1.6.1": - continue - - # only gather legacy info if it's missing - if not os.path.isfile(LEGACYINFO_PATH): - # grab the jar/zip if it's not there - if not os.path.isfile(jar_path): - download_binary_file(sess, jar_path, version.url()) - # find the latest timestamp in the zip file - tstamp = datetime.fromtimestamp(0) - with zipfile.ZipFile(jar_path) as jar: - for info in jar.infolist(): - tstamp_new = datetime(*info.date_time) - if tstamp_new > tstamp: - tstamp = tstamp_new - legacy_info = ForgeLegacyInfo() - legacy_info.release_time = tstamp - legacy_info.sha1 = file_hash(jar_path, hashlib.sha1) - legacy_info.sha256 = file_hash(jar_path, hashlib.sha256) - legacy_info.size = os.path.getsize(jar_path) - legacy_info_list.number[key] = legacy_info + # ignore the two versions without install manifests and jar mod class files + # TODO: fix those versions? + if version.mc_version_sane == "1.6.1": + continue + + # only gather legacy info if it's missing + if not os.path.isfile(LEGACYINFO_PATH): + # grab the jar/zip if it's not there + if not os.path.isfile(jar_path): + download_binary_file(sess, jar_path, version.url()) + # find the latest timestamp in the zip file + tstamp = datetime.fromtimestamp(0) + with zipfile.ZipFile(jar_path) as jar: + for info in jar.infolist(): + tstamp_new = datetime(*info.date_time) + if tstamp_new > tstamp: + tstamp = tstamp_new + legacy_info = ForgeLegacyInfo() + legacy_info.release_time = tstamp + legacy_info.sha1 = file_hash(jar_path, hashlib.sha1) + legacy_info.sha256 = file_hash(jar_path, hashlib.sha256) + legacy_info.size = os.path.getsize(jar_path) + legacy_info_list.number[key] = legacy_info # only write legacy info if it's missing if not os.path.isfile(LEGACYINFO_PATH): diff --git a/meta/run/update_java.py b/meta/run/update_java.py index bc9ad8db1f..80ca7b4a70 100644 --- a/meta/run/update_java.py +++ b/meta/run/update_java.py @@ -11,8 +11,8 @@ from meta.common.java import ( AZUL_VERSIONS_DIR, ) from meta.model.java import ( - ADOPTIUM_API_BASE, - OPENJ9_API_BASE, + ADOPTIUM_API_BASE, + OPENJ9_API_BASE, ADOPTX_API_AVAILABLE_RELEASES, adoptxAPIFeatureReleasesUrl, adoptiumAPIFeatureReleasesUrl, @@ -72,7 +72,11 @@ def main(): page = 0 while True: query = AdoptxAPIFeatureReleasesQuery( - image_type=AdoptxImageType.Jre, page_size=page_size, page=page, jvm_impl=AdoptxJvmImpl.Hotspot, vendor=AdoptxVendor.Eclipse + image_type=AdoptxImageType.Jre, + page_size=page_size, + page=page, + jvm_impl=AdoptxJvmImpl.Hotspot, + vendor=AdoptxVendor.Eclipse, ) api_call = adoptiumAPIFeatureReleasesUrl(feature, query=query) print("Fetching JRE Page:", page, api_call) @@ -116,7 +120,11 @@ def main(): page = 0 while True: query = AdoptxAPIFeatureReleasesQuery( - image_type=AdoptxImageType.Jre, page_size=page_size, page=page, jvm_impl=AdoptxJvmImpl.OpenJ9, vendor=AdoptxVendor.Ibm + image_type=AdoptxImageType.Jre, + page_size=page_size, + page=page, + jvm_impl=AdoptxJvmImpl.OpenJ9, + vendor=AdoptxVendor.Ibm, ) api_call = openj9APIFeatureReleasesUrl(feature, query=query) print("Fetching JRE Page:", page, api_call) diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 186edb253c..5530540173 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -1,7 +1,8 @@ """ - Get the source files necessary for generating Forge versions +Get the source files necessary for generating Forge versions """ +import concurrent.futures import copy import hashlib import json @@ -115,6 +116,127 @@ def get_single_forge_files_manifest(longversion, artifact: str): return ret_dict +def process_neoforge_version(key, entry): + eprint("Updating NeoForge %s" % key) + if entry.mc_version is None: + eprint("Skipping %d with invalid MC version" % entry.build) + return + + version = NeoForgeVersion(entry) + if version.url() is None: + eprint("Skipping %d with no valid files" % version.build) + return + if not version.uses_installer(): + eprint(f"version {version.long_version} does not use installer") + return + + jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) + + installer_info_path = ( + UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version + ) + profile_path = ( + UPSTREAM_DIR + "/neoforge/installer_manifests/%s.json" % version.long_version + ) + version_file_path = ( + UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version + ) + + new_sha1 = None + sha1_file = jar_path + ".sha1" + if not os.path.isfile(jar_path): + remove_files([profile_path, installer_info_path]) + else: + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files([jar_path, profile_path, installer_info_path, sha1_file]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) + + installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile( + installer_info_path + ) + + if installer_refresh_required: + # grab the installer if it's not there + if not os.path.isfile(jar_path): + eprint("Downloading %s" % version.url()) + try: + Path(jar_path).parent.mkdir(parents=True, exist_ok=True) + download_binary_file(sess, jar_path, version.url()) + except Exception as e: + eprint("Failed to download %s" % version.url()) + eprint("Error is %s" % e) + return + if new_sha1 is None: + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + except Exception as e: + eprint("Failed to download new sha1 %s" % version.url()) + eprint("Error is %s" % e) + if new_sha1 is not None: # this is in case the fetch failed + with open(sha1_file, "w") as file: + file.write(new_sha1) + + eprint("Processing %s" % version.url()) + # harvestables from the installer + if not os.path.isfile(profile_path): + print(jar_path) + with zipfile.ZipFile(jar_path) as jar: + with suppress(KeyError): + with jar.open("version.json") as profile_zip_entry: + version_data = profile_zip_entry.read() + + # Process: does it parse? + MojangVersion.parse_raw(version_data) + + Path(version_file_path).parent.mkdir(parents=True, exist_ok=True) + with open(version_file_path, "wb") as versionJsonFile: + versionJsonFile.write(version_data) + versionJsonFile.close() + + with jar.open("install_profile.json") as profile_zip_entry: + install_profile_data = profile_zip_entry.read() + + # Process: does it parse? + is_parsable = False + exception = None + try: + NeoForgeInstallerProfileV2.parse_raw(install_profile_data) + is_parsable = True + except ValidationError as err: + exception = err + + if not is_parsable: + if version.is_supported(): + raise exception + else: + eprint( + "Version %s is not supported and won't be generated later." + % version.long_version + ) + + Path(profile_path).parent.mkdir(parents=True, exist_ok=True) + with open(profile_path, "wb") as profileFile: + profileFile.write(install_profile_data) + profileFile.close() + + # installer info v1 + if not os.path.isfile(installer_info_path): + installer_info = InstallerInfo() + installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) + installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) + installer_info.size = os.path.getsize(jar_path) + installer_info.write(installer_info_path) + + def main(): # get the 1.20.1 remote version list fragments r = sess.get( @@ -136,7 +258,7 @@ def main(): new_index = DerivedNeoForgeIndex() - #let's keep the regex here to remove the 1.20.1- + # let's keep the regex here to remove the 1.20.1- version_expression = re.compile( r"^(?P[0-9a-zA-Z_\.]+)-(?P[0-9\.]+\.(?P[0-9]+))(-(?P[a-zA-Z0-9\.]+))?$" ) @@ -172,7 +294,7 @@ def main(): files=files, ) new_index.versions[long_version] = entry - + if entry.recommended: new_index.recommended = long_version @@ -188,127 +310,9 @@ def main(): print("Grabbing installers and dumping installer profiles...") # get the installer jars - if needed - and get the installer profiles out of them - for key, entry in new_index.versions.items(): - eprint("Updating NeoForge %s" % key) - - version = NeoForgeVersion(entry) - if version.url() is None: - eprint("Skipping %d with no valid files" % version.build) - continue - if not version.uses_installer(): - eprint(f"version {version.long_version} does not use installer") - continue - - jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) - - installer_info_path = ( - UPSTREAM_DIR + "/neoforge/installer_info/%s.json" % version.long_version - ) - profile_path = ( - UPSTREAM_DIR - + "/neoforge/installer_manifests/%s.json" % version.long_version - ) - version_file_path = ( - UPSTREAM_DIR + "/neoforge/version_manifests/%s.json" % version.long_version - ) - - new_sha1 = None - sha1_file = jar_path + ".sha1" - if not os.path.isfile(jar_path): - remove_files([profile_path, installer_info_path]) - else: - fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) - try: - rfile = sess.get(version.url() + ".sha1") - rfile.raise_for_status() - new_sha1 = rfile.text.strip() - if fileSha1 != new_sha1: - remove_files( - [jar_path, profile_path, installer_info_path, sha1_file] - ) - except Exception as e: - eprint("Failed to check sha1 %s" % version.url()) - eprint("Error is %s" % e) - - installer_refresh_required = not os.path.isfile( - profile_path - ) or not os.path.isfile(installer_info_path) - - if installer_refresh_required: - # grab the installer if it's not there - if not os.path.isfile(jar_path): - eprint("Downloading %s" % version.url()) - try: - Path(jar_path).parent.mkdir(parents=True, exist_ok=True) - download_binary_file(sess, jar_path, version.url()) - except Exception as e: - eprint("Failed to download %s" % version.url()) - eprint("Error is %s" % e) - continue - if new_sha1 is None: - try: - rfile = sess.get(version.url() + ".sha1") - rfile.raise_for_status() - new_sha1 = rfile.text.strip() - except Exception as e: - eprint("Failed to download new sha1 %s" % version.url()) - eprint("Error is %s" % e) - if new_sha1 is not None: # this is in case the fetch failed - with open(sha1_file, "w") as file: - file.write(new_sha1) - - eprint("Processing %s" % version.url()) - # harvestables from the installer - if not os.path.isfile(profile_path): - print(jar_path) - with zipfile.ZipFile(jar_path) as jar: - with suppress(KeyError): - with jar.open("version.json") as profile_zip_entry: - version_data = profile_zip_entry.read() - - # Process: does it parse? - MojangVersion.parse_raw(version_data) - - Path(version_file_path).parent.mkdir( - parents=True, exist_ok=True - ) - with open(version_file_path, "wb") as versionJsonFile: - versionJsonFile.write(version_data) - versionJsonFile.close() - - with jar.open("install_profile.json") as profile_zip_entry: - install_profile_data = profile_zip_entry.read() - - # Process: does it parse? - is_parsable = False - exception = None - try: - NeoForgeInstallerProfileV2.parse_raw(install_profile_data) - is_parsable = True - except ValidationError as err: - exception = err - - if not is_parsable: - if version.is_supported(): - raise exception - else: - eprint( - "Version %s is not supported and won't be generated later." - % version.long_version - ) - - Path(profile_path).parent.mkdir(parents=True, exist_ok=True) - with open(profile_path, "wb") as profileFile: - profileFile.write(install_profile_data) - profileFile.close() - - # installer info v1 - if not os.path.isfile(installer_info_path): - installer_info = InstallerInfo() - installer_info.sha1hash = file_hash(jar_path, hashlib.sha1) - installer_info.sha256hash = file_hash(jar_path, hashlib.sha256) - installer_info.size = os.path.getsize(jar_path) - installer_info.write(installer_info_path) + with concurrent.futures.ThreadPoolExecutor() as executor: + for key, entry in new_index.versions.items(): + executor.submit(process_neoforge_version, key, entry) if __name__ == "__main__": -- cgit 0.0.5-2-1-g0f52 From 295eea4f9b93971419999dd5dc5f755b8bc3a350 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Mar 2026 00:49:01 +0200 Subject: fix javaj9 missing files Signed-off-by: Trial97 --- meta/run/generate_java.py | 9 ++++++--- update.sh | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'meta') diff --git a/meta/run/generate_java.py b/meta/run/generate_java.py index 4c6c261719..9f23e3a4d3 100644 --- a/meta/run/generate_java.py +++ b/meta/run/generate_java.py @@ -387,9 +387,12 @@ def main(): if os.path.exists(openj9_path): openj9_available_releases = AdoptxAvailableReleases.parse_file(openj9_path) for major in openj9_available_releases.available_releases: - openj9_releases = AdoptxReleases.parse_file( - os.path.join(UPSTREAM_DIR, OPENJ9_VERSIONS_DIR, f"java{major}.json") - ) + path = os.path.join(UPSTREAM_DIR, OPENJ9_VERSIONS_DIR, f"java{major}.json") + + if not os.path.exists(path): + continue + + openj9_releases = AdoptxReleases.parse_file(path) for _, rls in openj9_releases: for binary in rls.binaries: if ( diff --git a/update.sh b/update.sh index 205bf01a2b..934a9946af 100755 --- a/update.sh +++ b/update.sh @@ -44,8 +44,8 @@ python -m meta.run.update_java || fail_in if [ "${DEPLOY_TO_GIT}" = true ]; then upstream_git add mojang/version_manifest_v2.json mojang/java_all.json mojang/versions/* || fail_in - upstream_git add forge/*.json forge/version_manifests/*.json forge/installer_manifests/*.json forge/files_manifests/*.json forge/installer_info/*.json || fail_in - upstream_git add neoforge/*.json neoforge/version_manifests/*.json neoforge/installer_manifests/*.json neoforge/files_manifests/*.json neoforge/installer_info/*.json || fail_in + upstream_git add forge/*.json forge/version_manifests/*.json forge/installer_manifests/*.json forge/files_manifests/*.json forge/installer_info/*.json forge/jars/*.sha1|| fail_in + upstream_git add neoforge/*.json neoforge/version_manifests/*.json neoforge/installer_manifests/*.json neoforge/files_manifests/*.json neoforge/installer_info/*.json neoforge/jars/*.sha1|| fail_in upstream_git add fabric/loader-installer-json/*.json fabric/meta-v2/*.json fabric/jars/*.json || fail_in upstream_git add quilt/loader-installer-json/*.json quilt/meta-v3/*.json quilt/jars/*.json || fail_in upstream_git add liteloader/*.json || fail_in -- cgit 0.0.5-2-1-g0f52 From b704d03dc86be9bdbdbd4cb8e130897104e36aae Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Mar 2026 10:50:59 +0200 Subject: harden concurrent task execution Signed-off-by: Trial97 --- meta/run/update_forge.py | 7 ++++++- meta/run/update_mojang.py | 12 ++++++++++-- meta/run/update_neoforge.py | 9 +++++---- meta/run/update_quilt.py | 12 ++++++++++-- 4 files changed, 31 insertions(+), 9 deletions(-) (limited to 'meta') diff --git a/meta/run/update_forge.py b/meta/run/update_forge.py index 59bdbeb29e..23ad333955 100755 --- a/meta/run/update_forge.py +++ b/meta/run/update_forge.py @@ -365,6 +365,7 @@ def main(): print("Grabbing installers and dumping installer profiles...") # get the installer jars - if needed - and get the installer profiles out of them with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [] for key, entry in new_index.versions.items(): eprint("Updating Forge %s" % key) if entry.mc_version is None: @@ -382,7 +383,9 @@ def main(): jar_path = os.path.join(UPSTREAM_DIR, JARS_DIR, version.filename()) if version.uses_installer(): - executor.submit(process_forge_version, version, jar_path) + futures.append( + executor.submit(process_forge_version, version, jar_path) + ) else: # ignore the two versions without install manifests and jar mod class files # TODO: fix those versions? @@ -407,6 +410,8 @@ def main(): legacy_info.sha256 = file_hash(jar_path, hashlib.sha256) legacy_info.size = os.path.getsize(jar_path) legacy_info_list.number[key] = legacy_info + for f in futures: + f.result() # only write legacy info if it's missing if not os.path.isfile(LEGACYINFO_PATH): diff --git a/meta/run/update_mojang.py b/meta/run/update_mojang.py index acdbec95a4..c05b15ce46 100755 --- a/meta/run/update_mojang.py +++ b/meta/run/update_mojang.py @@ -150,8 +150,12 @@ def main(): pending_ids = remote_ids with concurrent.futures.ThreadPoolExecutor() as executor: - for x in pending_ids: + futures = [ executor.submit(fetch_version_concurrent, remote_versions, x) + for x in pending_ids + ] + for f in futures: + f.result() # deal with experimental snapshots separately if os.path.exists(STATIC_EXPERIMENTS_FILE): @@ -178,8 +182,12 @@ def main(): old_snapshots_ids = set(old_snapshots.versions.keys()) with concurrent.futures.ThreadPoolExecutor() as executor: - for x in old_snapshots_ids: + futures = [ executor.submit(fetch_modified_version_concurrent, old_snapshots, x) + for x in old_snapshots_ids + ] + for f in futures: + f.result() remote_versions.index.write(version_manifest_path) diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 5530540173..242ad8a6b1 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -118,9 +118,6 @@ def get_single_forge_files_manifest(longversion, artifact: str): def process_neoforge_version(key, entry): eprint("Updating NeoForge %s" % key) - if entry.mc_version is None: - eprint("Skipping %d with invalid MC version" % entry.build) - return version = NeoForgeVersion(entry) if version.url() is None: @@ -311,8 +308,12 @@ def main(): print("Grabbing installers and dumping installer profiles...") # get the installer jars - if needed - and get the installer profiles out of them with concurrent.futures.ThreadPoolExecutor() as executor: - for key, entry in new_index.versions.items(): + futures = [ executor.submit(process_neoforge_version, key, entry) + for key, entry in new_index.versions.items() + ] + for f in futures: + f.result() if __name__ == "__main__": diff --git a/meta/run/update_quilt.py b/meta/run/update_quilt.py index 2f3160265d..e694fd7b46 100755 --- a/meta/run/update_quilt.py +++ b/meta/run/update_quilt.py @@ -106,8 +106,12 @@ def main(): "https://meta.quiltmc.org/v3/versions/" + component, ) with concurrent.futures.ThreadPoolExecutor() as executor: - for it in index: + futures = [ executor.submit(compute_jar_file_concurrent, component, it) + for it in index + ] + for f in futures: + f.result() # for each loader, download installer JSON file from maven with open( @@ -115,8 +119,12 @@ def main(): ) as loaderVersionIndexFile: loader_version_index = json.load(loaderVersionIndexFile) with concurrent.futures.ThreadPoolExecutor() as executor: - for it in loader_version_index: + futures = [ executor.submit(get_json_file_concurrent, it) + for it in loader_version_index + ] + for f in futures: + f.result() if __name__ == "__main__": -- cgit 0.0.5-2-1-g0f52 From 9109552756f680b53bf512baea1ca8d459ca516e Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 21 Mar 2026 10:46:52 +0100 Subject: fix(common): disable forever cache This caused a lot of cached data that we don't really need. Signed-off-by: Sefa Eyeoglu --- meta/common/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 1f358cdbd7..0f4d3d2ef7 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -82,8 +82,8 @@ def merge_dict(base: dict[Any, Any], overlay: dict[Any, Any]): def default_session(): - forever_cache = FileCache(os.path.join(cache_path(), "http_cache"), forever=True) - sess = CacheControl(requests.Session(), forever_cache) + cache = FileCache(os.path.join(cache_path(), "http_cache")) + sess = CacheControl(requests.Session(), cache) sess.headers.update({"User-Agent": "PrismLauncherMeta/1.0"}) -- cgit 0.0.5-2-1-g0f52 From 9dd74cdf487e19a3cf0b60c224a2c798471a493a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Mar 2026 11:40:11 +0200 Subject: update sha1 cahcing check Signed-off-by: Trial97 --- meta/common/__init__.py | 3 ++- meta/run/update_forge.py | 23 ++++++++++------------- meta/run/update_neoforge.py | 23 ++++++++++------------- 3 files changed, 22 insertions(+), 27 deletions(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 1f358cdbd7..533f832917 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -117,7 +117,8 @@ def get_file_sha1_from_file(file_name: str, sha1_file: str) -> Optional[str]: if os.path.isfile(sha1_file): with open(sha1_file, "r") as file: return file.read() - + if not os.path.isfile(jar_path): + return None new_sha1 = file_hash(file_name, hashlib.sha1) with open(sha1_file, "w") as file: file.write(new_sha1) diff --git a/meta/run/update_forge.py b/meta/run/update_forge.py index 23ad333955..c74865b31f 100755 --- a/meta/run/update_forge.py +++ b/meta/run/update_forge.py @@ -150,19 +150,16 @@ def process_forge_version(version, jar_path): new_sha1 = None sha1_file = jar_path + ".sha1" - if not os.path.isfile(jar_path): - remove_files([profile_path, installer_info_path]) - else: - fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) - try: - rfile = sess.get(version.url() + ".sha1") - rfile.raise_for_status() - new_sha1 = rfile.text.strip() - if fileSha1 != new_sha1: - remove_files([jar_path, profile_path, installer_info_path, sha1_file]) - except Exception as e: - eprint("Failed to check sha1 %s" % version.url()) - eprint("Error is %s" % e) + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files([jar_path, profile_path, installer_info_path, sha1_file]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile( installer_info_path diff --git a/meta/run/update_neoforge.py b/meta/run/update_neoforge.py index 242ad8a6b1..9957aad1bd 100644 --- a/meta/run/update_neoforge.py +++ b/meta/run/update_neoforge.py @@ -141,19 +141,16 @@ def process_neoforge_version(key, entry): new_sha1 = None sha1_file = jar_path + ".sha1" - if not os.path.isfile(jar_path): - remove_files([profile_path, installer_info_path]) - else: - fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) - try: - rfile = sess.get(version.url() + ".sha1") - rfile.raise_for_status() - new_sha1 = rfile.text.strip() - if fileSha1 != new_sha1: - remove_files([jar_path, profile_path, installer_info_path, sha1_file]) - except Exception as e: - eprint("Failed to check sha1 %s" % version.url()) - eprint("Error is %s" % e) + fileSha1 = get_file_sha1_from_file(jar_path, sha1_file) + try: + rfile = sess.get(version.url() + ".sha1") + rfile.raise_for_status() + new_sha1 = rfile.text.strip() + if fileSha1 != new_sha1: + remove_files([jar_path, profile_path, installer_info_path, sha1_file]) + except Exception as e: + eprint("Failed to check sha1 %s" % version.url()) + eprint("Error is %s" % e) installer_refresh_required = not os.path.isfile(profile_path) or not os.path.isfile( installer_info_path -- cgit 0.0.5-2-1-g0f52 From d55bc04feeb79eb7a8febe681bfad8eca27aac6f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 21 Mar 2026 11:49:52 +0200 Subject: fix error Signed-off-by: Trial97 --- meta/common/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta') diff --git a/meta/common/__init__.py b/meta/common/__init__.py index 533f832917..922ff98655 100644 --- a/meta/common/__init__.py +++ b/meta/common/__init__.py @@ -117,7 +117,7 @@ def get_file_sha1_from_file(file_name: str, sha1_file: str) -> Optional[str]: if os.path.isfile(sha1_file): with open(sha1_file, "r") as file: return file.read() - if not os.path.isfile(jar_path): + if not os.path.isfile(file_name): return None new_sha1 = file_hash(file_name, hashlib.sha1) with open(sha1_file, "w") as file: -- cgit 0.0.5-2-1-g0f52 From d6d550b33800af4955af2e4726e674d8c8f77295 Mon Sep 17 00:00:00 2001 From: tildejustin Date: Tue, 31 Mar 2026 17:47:30 -0400 Subject: add traits: legacyLaunch for 13w16a-13w23a and texturepack for 13w16a-13w23b --- meta/run/generate_mojang.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'meta') diff --git a/meta/run/generate_mojang.py b/meta/run/generate_mojang.py index 693afb66da..9d2063263a 100755 --- a/meta/run/generate_mojang.py +++ b/meta/run/generate_mojang.py @@ -1,5 +1,6 @@ import copy import hashlib +import re import os from collections import defaultdict, namedtuple from operator import attrgetter @@ -513,6 +514,15 @@ def main(): if v.additional_traits == None: v.additional_traits = [] v.additional_traits.append("legacyServices") + + # 13w16a-13w23a require legacyLaunch and those + 13w23b require texturepacks + if re.match(r"13w[1,2]\d[a-c]", v.version) and 16 <= int(v.version[3:-1]) <= 23: + if v.additional_traits == None: + v.additional_traits = [] + if v.version != "13w23b": + v.additional_traits.append("legacyLaunch") + v.additional_traits.append("texturepacks") + v.write(out_filename) for lwjglVersionVariant in lwjglVersionVariants: -- cgit 0.0.5-2-1-g0f52