summaryrefslogtreecommitdiff
path: root/meta
diff options
context:
space:
mode:
authorSefa Eyeoglu <contact@scrumplex.net>2022-04-02 19:35:02 +0200
committerSefa Eyeoglu <contact@scrumplex.net>2022-04-05 14:35:07 +0200
commit2ca56cafdf767c32fd8397bc4089c1e8513272d5 (patch)
tree42daeedfe76da8dec9d7e92f9e74076ef5c82d7a /meta
parent5895e5accfbb1268500f9dd35003abf207a548c8 (diff)
downloadProject-Tick-2ca56cafdf767c32fd8397bc4089c1e8513272d5.tar.gz
Project-Tick-2ca56cafdf767c32fd8397bc4089c1e8513272d5.zip
refactor: move generateMojang to pydantic models
Diffstat (limited to 'meta')
-rw-r--r--meta/common/__init__.py5
-rw-r--r--meta/common/mojang.py6
-rw-r--r--meta/metautil.py169
-rw-r--r--meta/model/__init__.py42
-rw-r--r--meta/model/mojang.py140
5 files changed, 174 insertions, 188 deletions
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)