Update base json datatypes and mojang version separation logic

This commit is contained in:
Petr Mrázek 2017-03-04 00:21:34 +01:00
parent 6220a0b491
commit e1ec941403
6 changed files with 145 additions and 118 deletions

View File

@ -2,6 +2,7 @@ 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__ = [
@ -9,5 +10,5 @@ __all__ = [
'StringProperty', 'BooleanProperty',
'DateProperty', 'DateTimeProperty', 'TimeProperty',
'ObjectProperty', 'ListProperty', 'DictProperty',
'JsonObject', 'JsonArray', 'ISOTimestampProperty',
'JsonObject', 'JsonArray', 'AbstractDateProperty', 'JsonProperty'
]

View File

@ -93,7 +93,7 @@ class JsonProperty(object):
return self
def exclude(self, value):
return self.exclude_if_none and not value
return self.exclude_if_none and value == None
def empty(self, value):
return value is None

View File

@ -1,7 +1,7 @@
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):
@ -22,6 +22,10 @@ class JsonArray(list):
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)

View File

@ -5,7 +5,6 @@ import sys
import datetime
import time
import decimal
import iso8601
from .base_properties import (
AbstractDateProperty,
AssertTypeProperty,
@ -124,21 +123,6 @@ class TimeProperty(AbstractDateProperty):
return value, value.isoformat()
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 ObjectProperty(JsonContainerProperty):
default = lambda self: self.item_type()

View File

@ -1,6 +1,60 @@
import json
from pprint import pprint
from jsonobject import *
import datetime
import iso8601
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):
components = name.split(':')
self.group = components[0]
self.artifact = components[1]
self.version = components[2]
if len(components) == 4:
self.classifier = components[3]
else:
self.classifier = None
def toString(self):
if self.classifier:
return "%s:%s:%s:%s" % (self.group, self.artifact, self.version, self.classifier)
else:
return "%s:%s:%s" % (self.group, self.artifact, self.version)
def isLwjgl(self):
return self.group in ("org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils")
def __lt__(self, other):
return self.toString() < other.toString()
class GradleSpecifierProperty(JsonProperty):
def wrap(self, value):
return GradleSpecifier(value)
def unwrap(self, value):
return value, value.toString()
'''
Mojang index files look like this:
@ -44,6 +98,66 @@ class MojangIndexWrap:
self.versions = versionsDict
class MojangArtifactBase (JsonObject):
sha1 = StringProperty()
size = IntegerProperty()
url = StringProperty()
class MojangArtifact (MojangArtifactBase):
path = StringProperty()
class MojangAssets (MojangArtifactBase):
id = StringProperty()
totalSize = IntegerProperty()
class MojangLibraryDownloads(JsonObject):
artifact = MojangArtifact(exclude_if_none=True)
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"])
class MojangRule (JsonObject):
action = StringProperty(choices=["allow", "disallow"])
os = ObjectProperty(OSRule, exclude_if_none=True, default=None)
class MojangLibrary (JsonObject):
extract = ObjectProperty(MojangLibraryExtractRules, exclude_if_none=True, default=None)
name = GradleSpecifierProperty()
downloads = ObjectProperty(MojangLibraryDownloads)
natives = DictProperty(StringProperty, exclude_if_none=True, default=None)
rules = ListProperty(MojangRule, exclude_if_none=True, default=None)
class MojangVersionFile (JsonObject):
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)
mainClass = StringProperty(exclude_if_none=True, default=None)
minecraftArguments = StringProperty(exclude_if_none=True, default=None)
minimumLauncherVersion = IntegerProperty(exclude_if_none=True, default=None)
releaseTime = ISOTimestampProperty()
time = ISOTimestampProperty(exclude_if_none=True, default=None)
type = StringProperty(exclude_if_none=True, default=None)
'''
The MultiMC static override file for legacy looks like this:
{
@ -82,76 +196,3 @@ class LegacyOverrideIndexWrap:
for version in self.index.versions:
versionsDict[version.id] = version
self.versions = versionsDict
class GradleSpecifier:
'A gradle specifier - a maven coordinate'
def __init__(self, name):
components = name.split(':')
self.group = components[0]
self.artifact = components[1]
self.version = components[2]
if len(components) == 4:
self.classifier = components[3]
else:
self.classifier = None
def toString(self):
if self.classifier:
return "%s:%s:%s:%s" % (self.group, self.artifact, self.version, self.classifier)
else:
return "%s:%s:%s" % (self.group, self.artifact, self.version)
def isLwjgl(self):
return self.group in ("org.lwjgl.lwjgl", "net.java.jinput", "net.java.jutils")
class VersionPatch:
'A version patch structure'
def __init__(self, uid, name):
self.uid = uid
if name == None:
self.name = self.uid
else:
self.name = name
self.libraries = []
self.version = None
self.rules = []
self.releaseType = None
self.releaseTime = None
def printout(self):
print ("UID: " + self.uid)
if self.name:
print ("Name: " + self.name)
if self.version:
print ("Version: " + self.version)
print ("Libraries:")
pprint(self.libraries)
print ("Rules:")
pprint(self.rules)
def write(self, filename):
out = {}
out["fileId"] = self.uid
out["name"] = self.name
if self.releaseTime:
out["releaseTime"] = self.releaseTime.isoformat()
if self.libraries and len(self.libraries) > 0:
out["libraries"] = self.libraries
if self.rules and len(self.rules) > 0:
out["rules"] = self.rules
if self.version:
out["version"] = self.version
if self.releaseType:
out["type"] = "release"
with open(filename, 'w') as outfile:
json.dump(out, outfile, sort_keys=True, indent=4)

View File

@ -15,27 +15,24 @@ from metautil import *
def addOrGetBucket(buckets, rules):
ruleHash = None
if rules:
ruleHash = hash(json.dumps(rules))
ruleHash = hash(json.dumps(rules.to_json()))
bucket = None
if ruleHash in buckets:
bucket = buckets[ruleHash]
else:
bucket = VersionPatch("org.lwjgl", "LWJGL")
bucket.releaseType = "release"
bucket = MojangVersionFile()
bucket.name = "LWJGL"
bucket.type = "release"
buckets[ruleHash] = bucket
bucket.rules = rules
return bucket
def addLWJGLVersion(versions, bucket):
if bucket.version in versions:
if versions[bucket.version].rules:
if not bucket.rules:
versions[bucket.version].rules = None
return
if bucket.releaseTime < versions[bucket.version].releaseTime:
versions[bucket.version].releaseTime = bucket.releaseTime
versions[bucket.version] = bucket
else:
versions[bucket.version] = bucket
# get the local version list
staticVersionlist = None
@ -49,29 +46,28 @@ legacyIDs = set(staticVersionlist.versions.keys())
lwjglVersions = {}
for filename in os.listdir('mojang/versions'):
with open("mojang/versions/" + filename) as json_file:
json_data = json.load(json_file)
libs = json_data["libraries"]
versionFile = MojangVersionFile(json.load(json_file))
libs_minecraft = []
buckets = {}
for lib in libs:
specifier = GradleSpecifier(lib["name"])
for lib in versionFile.libraries:
libCopy = copy.deepcopy(lib)
specifier = libCopy.name
ruleHash = None
if specifier.isLwjgl():
rules = None
if "rules" in lib:
rules = lib["rules"]
lib.pop("rules", None)
if libCopy.rules:
rules = libCopy.rules
libCopy.rules = None
bucket = addOrGetBucket(buckets, rules)
if specifier.group == "org.lwjgl.lwjgl" and specifier.artifact == "lwjgl":
bucket.version = specifier.version
bucket.libraries.append(lib)
bucket.libraries.append(libCopy)
# set the LWJGL release time to the oldest Minecraft release it appeared in
if bucket.releaseTime == None:
bucket.releaseTime = iso8601.parse_date(json_data["releaseTime"])
bucket.releaseTime = versionFile.releaseTime
else:
newDate = iso8601.parse_date(json_data["releaseTime"])
if newDate < bucket.releaseTime:
bucket.releaseTime = newDate
if versionFile.releaseTime < bucket.releaseTime:
bucket.releaseTime = versionFile.releaseTime
else:
libs_minecraft.append(lib)
if len(buckets) == 1:
@ -86,13 +82,14 @@ for filename in os.listdir('mojang/versions'):
else:
keyBucket.libraries = sorted(keyBucket.libraries, key=itemgetter('name'))
addLWJGLVersion(lwjglVersions, keyBucket)
json_data["libraries"] = libs_minecraft
json_data["name"] = "Minecraft"
filenameOut = "multimc/net.minecraft/%s.json" % json_data["id"]
versionFile.libraries = libs_minecraft
versionFile.name = "Minecraft"
filenameOut = "multimc/net.minecraft/%s.json" % versionFile.id
with open(filenameOut, 'w') as outfile:
json.dump(json_data, outfile, sort_keys=True, indent=4)
json.dump(versionFile.to_json(), outfile, sort_keys=True, indent=4)
for version in lwjglVersions:
versionObj = lwjglVersions[version]
filename = "multimc/org.lwjgl/%s.json" % version
versionObj.write(filename)
with open(filename, 'w') as outfile:
json.dump(versionObj.to_json(), outfile, sort_keys=True, indent=4)