Merge pull request #6 from Scrumplex/quilt

This commit is contained in:
Sefa Eyeoglu 2022-04-15 11:23:39 +02:00 committed by GitHub
commit cd7d6c0cc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 254 additions and 0 deletions

View File

@ -1,4 +1,5 @@
.git/
.idea/
caches/
.idea/

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
.idea/
public/*/
caches/

110
generateQuilt.py Executable file
View File

@ -0,0 +1,110 @@
import json
import os
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
PMC_DIR = polymc_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="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:
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 = 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"))
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(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"))
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(PMC_DIR, INTERMEDIARY_COMPONENT, "package.json"))
if __name__ == '__main__':
main()

17
meta/common/quilt.py Normal file
View File

@ -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.hashed"
if not USE_QUILT_MAPPINGS:
INTERMEDIARY_COMPONENT = FABRIC_INTERMEDIARY_COMPONENT

View File

@ -44,6 +44,7 @@ upstream_git checkout "${BRANCH}" || exit 1
python updateMojang.py || fail_in
python updateForge.py || fail_in
python updateFabric.py || fail_in
python updateQuilt.py || fail_in
python updateLiteloader.py || fail_in
if [ "${DEPLOY_TO_GIT}" = true ] ; then
@ -63,6 +64,7 @@ polymc_git checkout "${BRANCH}" || exit 1
python generateMojang.py || fail_out
python generateForge.py || fail_out
python generateFabric.py || fail_out
python generateQuilt.py || fail_out
python generateLiteloader.py || fail_out
python index.py || fail_out

122
updateQuilt.py Executable file
View File

@ -0,0 +1,122 @@
import hashlib
import json
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.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 = 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 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 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()
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)
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 :(
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
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.write(path + ".json")
def main():
# get the version list for each component we are interested in
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:
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()