summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSefa Eyeoglu <contact@scrumplex.net>2022-04-05 14:29:44 +0200
committerSefa Eyeoglu <contact@scrumplex.net>2022-04-05 14:39:03 +0200
commiteda318131d1e938ee331cc2149a0518e25b7aa76 (patch)
treef49dcfd9cb3d6fe6a0ce3b883cb0441cc1945a99
parent7ab37c8658c4c8614a85e5ff729aa4ef3592801f (diff)
downloadProject-Tick-eda318131d1e938ee331cc2149a0518e25b7aa76.tar.gz
Project-Tick-eda318131d1e938ee331cc2149a0518e25b7aa76.zip
refactor: move forge to pydantic models
-rwxr-xr-xgenerateForge.py478
-rw-r--r--meta/common/forge.py17
-rw-r--r--meta/forgeutil.py323
-rw-r--r--meta/model/forge.py306
-rw-r--r--static/forge/forge-legacyinfo.json (renamed from static/forge-legacyinfo.json)0
-rwxr-xr-xupdateForge.py517
6 files changed, 793 insertions, 848 deletions
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.<br>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.<br>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/forge-legacyinfo.json
index 28e45244f8..28e45244f8 100644
--- a/static/forge-legacyinfo.json
+++ b/static/forge/forge-legacyinfo.json
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<mc>[^-]+)-(?P<promotion>(latest)|(recommended))(-(?P<branch>[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<mc>[0-9a-zA-Z_\\.]+)-(?P<ver>[0-9\\.]+\\.(?P<build>[0-9]+))(-(?P<branch>[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<mc>[^-]+)-(?P<promotion>(latest)|(recommended))(-(?P<branch>[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<mc>[0-9a-zA-Z_\\.]+)-(?P<ver>[0-9\\.]+\\.(?P<build>[0-9]+))(-(?P<branch>[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()