Support for inherited JSONs and their libs, specifically fabric
This commit is contained in:
parent
696ab35bad
commit
c81275856a
@ -22,6 +22,39 @@ import subprocess
|
|||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
import platform
|
import platform
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
def download(url,decode = "utf-8"):
|
||||||
|
request = urllib.request.Request(url,headers={"User-Agent":"Mozilla/5.0"})
|
||||||
|
response = urllib.request.urlopen(request)
|
||||||
|
rt = response.read()
|
||||||
|
if decode == False: return rt
|
||||||
|
return response.read().decode(decode)
|
||||||
|
|
||||||
|
def readFile(file,decode = "utf-8"):
|
||||||
|
fileh = False
|
||||||
|
fileh = open(file,"rb")
|
||||||
|
data = fileh.read()
|
||||||
|
fileh.close()
|
||||||
|
if decode == False: return data
|
||||||
|
return data.decode(decode)
|
||||||
|
|
||||||
|
def fileDl(url,file,read = True,decode = "utf-8"):
|
||||||
|
if os.path.isfile(file):
|
||||||
|
if read == True:
|
||||||
|
return readFile(file,decode)
|
||||||
|
return
|
||||||
|
|
||||||
|
print(url)
|
||||||
|
data = download(url,False)
|
||||||
|
fileh = open(tmpFile,"wb")
|
||||||
|
fileh.write(data)
|
||||||
|
fileh.close()
|
||||||
|
if pUp(file) != "" and not os.path.isdir(pUp(file)): os.makedirs(pUp(file))
|
||||||
|
os.rename(tmpFile,file)
|
||||||
|
if read == False: return
|
||||||
|
if decode == False: return data
|
||||||
|
return data.decode(decode)
|
||||||
|
|
||||||
def readJsonFile(file):
|
def readJsonFile(file):
|
||||||
fileh = open(file,"r")
|
fileh = open(file,"r")
|
||||||
@ -29,10 +62,112 @@ def readJsonFile(file):
|
|||||||
fileh.close()
|
fileh.close()
|
||||||
return json.loads(data)
|
return json.loads(data)
|
||||||
|
|
||||||
|
def findInChain(versionsPath,version,path):
|
||||||
|
versionPath = p(versionsPath,version)
|
||||||
|
clientJson = readJsonFile(p(versionPath,version + ".json"))
|
||||||
|
curPath = clientJson.copy()
|
||||||
|
success = True
|
||||||
|
for dir in path:
|
||||||
|
if dir in curPath:
|
||||||
|
curPath = curPath[dir]
|
||||||
|
else:
|
||||||
|
success = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if success == False:
|
||||||
|
return findInChain(versionsPath,clientJson["inheritsFrom"],path)
|
||||||
|
return curPath
|
||||||
|
|
||||||
|
def findInChainDeepest(versionsPath,version,path):
|
||||||
|
found = False
|
||||||
|
while True:
|
||||||
|
versionPath = p(versionsPath,version)
|
||||||
|
clientJson = readJsonFile(p(versionPath,version + ".json"))
|
||||||
|
curPath = clientJson.copy()
|
||||||
|
for dir in path:
|
||||||
|
if dir in curPath:
|
||||||
|
curPath = curPath[dir]
|
||||||
|
else:
|
||||||
|
if "inheritsFrom" in clientJson:
|
||||||
|
version = clientJson["inheritsFrom"]
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
curPath = False
|
||||||
|
break
|
||||||
|
|
||||||
|
found = curPath
|
||||||
|
if "inheritsFrom" in clientJson:
|
||||||
|
version = clientJson["inheritsFrom"]
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
if found == False: raise
|
||||||
|
return found
|
||||||
|
|
||||||
|
def processVersion(versionsPath,libraryPath,nativePath,version):
|
||||||
|
versionPath = p(versionsPath,version)
|
||||||
|
clientJson = readJsonFile(p(versionPath,version + ".json"))
|
||||||
|
libraries = []
|
||||||
|
natives = []
|
||||||
|
arguments = []
|
||||||
|
downloadLibraries = {}
|
||||||
|
|
||||||
|
if "inheritsFrom" in clientJson:
|
||||||
|
_,libraries,downloadLibraries,natives,arguments = processVersion(versionsPath,libraryPath,nativePath,clientJson["inheritsFrom"])
|
||||||
|
|
||||||
|
for library in clientJson["libraries"]:
|
||||||
|
if "downloads" in library:
|
||||||
|
if "artifact" in library["downloads"]:
|
||||||
|
library["downloads"]["artifact"]["path"] = library["downloads"]["artifact"]["path"].replace("/",os.path.sep)
|
||||||
|
libraries.append(p(libraryPath,library["downloads"]["artifact"]["path"]))
|
||||||
|
if "classifiers" in library["downloads"]:
|
||||||
|
native = False
|
||||||
|
if "natives-" +lv["osName"] in library["downloads"]["classifiers"]:
|
||||||
|
native = library["downloads"]["classifiers"]["natives-" +lv["osName"]]
|
||||||
|
|
||||||
|
if lv["osName"] == "macos" and native == False and "natives-osx" in library["downloads"]["classifiers"]:
|
||||||
|
native = library["downloads"]["classifiers"]["natives-osx"]
|
||||||
|
|
||||||
|
if native != False:
|
||||||
|
native["path"] = native["path"].replace("/",os.path.sep)
|
||||||
|
natives.append(p(nativePath,native["path"]))
|
||||||
|
elif "name" in library:
|
||||||
|
#net.fabricmc:sponge-mixin:0.9.2+mixin.0.8.2
|
||||||
|
libSplit = library["name"].rsplit(":",1)
|
||||||
|
libVersion = libSplit[1]
|
||||||
|
libName = libSplit[0].rsplit(":",1)[1]
|
||||||
|
libPath = libSplit[0].replace(".","/").replace(":","/") + "/" + libVersion + "/" +libName+ "-" +libVersion+ ".jar"
|
||||||
|
library["path"] = libPath.replace("/",os.path.sep)
|
||||||
|
libraries.append(p(libraryPath,library["path"]))
|
||||||
|
|
||||||
|
if "url" in library:
|
||||||
|
fullUrl = library["url"]
|
||||||
|
while len(fullUrl) > 0 and fullUrl[-1] == "/": fullUrl = fullUrl[:-1]
|
||||||
|
fullUrl = fullUrl + "/" + libPath
|
||||||
|
downloadLibraries[p(libraryPath,library["path"])] = fullUrl
|
||||||
|
|
||||||
|
libraries.append(p(versionPath,version + ".jar"))
|
||||||
|
|
||||||
|
if "arguments" in clientJson:
|
||||||
|
for arg in clientJson["arguments"]["game"]:
|
||||||
|
if type(arg) != str: continue
|
||||||
|
arguments.append(arg)
|
||||||
|
elif "minecraftArguments" in clientJson:
|
||||||
|
margs = clientJson["minecraftArguments"].replace('"',"").split(" ")
|
||||||
|
for arg in margs:
|
||||||
|
if type(arg) != str: continue
|
||||||
|
arguments.append(arg)
|
||||||
|
|
||||||
|
return clientJson,libraries,downloadLibraries,natives,arguments
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
print("Reading config...")
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(os.path.splitext(s)[0] + ".ini")
|
config.read(os.path.splitext(s)[0] + ".ini")
|
||||||
|
|
||||||
|
global lv
|
||||||
|
|
||||||
lv = config["default"]
|
lv = config["default"]
|
||||||
for var in lv:
|
for var in lv:
|
||||||
glbs = globals()
|
glbs = globals()
|
||||||
@ -58,48 +193,43 @@ def main():
|
|||||||
if not lv["osName"] in ["windows","linux","macos"]:
|
if not lv["osName"] in ["windows","linux","macos"]:
|
||||||
print("Warning, unsupported OS detected: " +lv["osName"])
|
print("Warning, unsupported OS detected: " +lv["osName"])
|
||||||
print("Needs to be either windows, linux or macos. Define it with osName=name in the config.")
|
print("Needs to be either windows, linux or macos. Define it with osName=name in the config.")
|
||||||
print("")
|
|
||||||
|
print("")
|
||||||
if not "version" in lv: lv["version"] = input("Version ID: ")
|
if not "version" in lv: lv["version"] = input("Version ID: ")
|
||||||
if not "name" in lv: lv["name"] = input("Player name: ")
|
if not "name" in lv: lv["name"] = input("Player name: ")
|
||||||
|
global tmpFile
|
||||||
|
tmpFile = p(lv["gamePath"],"file.tmp")
|
||||||
|
if os.path.isfile(tmpFile): os.remove(tmpFile)
|
||||||
|
|
||||||
|
print("Scanning .json(s)...")
|
||||||
|
versionsPath = p(lv["gamePath"],"versions")
|
||||||
|
libraryPath = p(lv["gamePath"],"libraries")
|
||||||
|
nativePath = p(lv["gamePath"],"natives")
|
||||||
|
clientJson,libraries,downloadLibraries,natives,arguments = processVersion(versionsPath,libraryPath,nativePath,lv["version"])
|
||||||
|
|
||||||
versionPath = p(lv["gamePath"],"versions",lv["version"])
|
versionPath = p(lv["gamePath"],"versions",lv["version"])
|
||||||
libraryPath = p(lv["gamePath"],"libraries")
|
|
||||||
nativesPath = p(lv["gamePath"],"natives")
|
|
||||||
nativesOutPath = p(versionPath,"natives-" +lv["osName"])
|
nativesOutPath = p(versionPath,"natives-" +lv["osName"])
|
||||||
assetsPath = p(lv["gamePath"],"assets")
|
assetsPath = p(lv["gamePath"],"assets")
|
||||||
|
|
||||||
print("Extracting natives...")
|
|
||||||
clientJson = readJsonFile(p(versionPath,lv["version"] + ".json"))
|
|
||||||
libraryList = ""
|
|
||||||
separator = ";"
|
separator = ";"
|
||||||
if lv["osName"] != "windows": separator = ":"
|
if lv["osName"] != "windows": separator = ":"
|
||||||
|
libraryList = separator.join(libraries)
|
||||||
|
|
||||||
for library in clientJson["libraries"]:
|
print("Downloading libraries...")
|
||||||
if "artifact" in library["downloads"]:
|
for library in downloadLibraries:
|
||||||
library["downloads"]["artifact"]["path"] = library["downloads"]["artifact"]["path"].replace("/",os.path.sep)
|
fileDl(downloadLibraries[library],library,read = False)
|
||||||
libraryList += p(libraryPath,library["downloads"]["artifact"]["path"]) + separator
|
|
||||||
if "classifiers" in library["downloads"]:
|
|
||||||
native = False
|
|
||||||
if "natives-" +lv["osName"] in library["downloads"]["classifiers"]:
|
|
||||||
native = library["downloads"]["classifiers"]["natives-" +lv["osName"]]
|
|
||||||
|
|
||||||
if lv["osName"] == "macos" and native == False and "natives-osx" in library["downloads"]["classifiers"]:
|
|
||||||
native = library["downloads"]["classifiers"]["natives-osx"]
|
|
||||||
|
|
||||||
if native != False:
|
|
||||||
native["path"] = native["path"].replace("/",os.path.sep)
|
|
||||||
if not os.path.isdir(nativesOutPath): os.makedirs(nativesOutPath)
|
|
||||||
subprocess.run(["7z","x",p(nativesPath,native["path"]),"-o" +nativesOutPath,"-aos"],check=True,stdout=subprocess.DEVNULL)
|
|
||||||
|
|
||||||
libraryList += p(versionPath,lv["version"] + ".jar")
|
print("Extracting natives...")
|
||||||
#print(libraryList)
|
if not os.path.isdir(nativesOutPath): os.makedirs(nativesOutPath)
|
||||||
|
for native in natives:
|
||||||
|
subprocess.run(["7z","x",native,"-o" +nativesOutPath,"-aos"],check=True,stdout=subprocess.DEVNULL)
|
||||||
|
|
||||||
launcherVariables = {}
|
launcherVariables = {}
|
||||||
launcherVariables["auth_player_name"] = lv["name"]
|
launcherVariables["auth_player_name"] = lv["name"]
|
||||||
launcherVariables["version_name"] = lv["version"]
|
launcherVariables["version_name"] = findInChainDeepest(versionsPath,lv["version"],["id"])
|
||||||
launcherVariables["game_directory"] = lv["gamePath"]
|
launcherVariables["game_directory"] = lv["gamePath"]
|
||||||
launcherVariables["assets_root"] = assetsPath
|
launcherVariables["assets_root"] = assetsPath
|
||||||
launcherVariables["assets_index_name"] = clientJson["assets"]
|
launcherVariables["assets_index_name"] = findInChain(versionsPath,lv["version"],["assets"])
|
||||||
launcherVariables["auth_access_token"] = "-"
|
launcherVariables["auth_access_token"] = "-"
|
||||||
launcherVariables["auth_uuid"] = hashlib.md5(lv["name"].encode('utf-8')).hexdigest()
|
launcherVariables["auth_uuid"] = hashlib.md5(lv["name"].encode('utf-8')).hexdigest()
|
||||||
launcherVariables["user_type"] = "offline"
|
launcherVariables["user_type"] = "offline"
|
||||||
@ -115,19 +245,10 @@ def main():
|
|||||||
args.append(libraryList)
|
args.append(libraryList)
|
||||||
args.append(clientJson["mainClass"])
|
args.append(clientJson["mainClass"])
|
||||||
|
|
||||||
if "arguments" in clientJson:
|
for arg in arguments:
|
||||||
for arg in clientJson["arguments"]["game"]:
|
for var in launcherVariables:
|
||||||
if type(arg) != str: continue
|
arg = arg.replace("${" +var+ "}",launcherVariables[var])
|
||||||
for var in launcherVariables:
|
args.append(arg)
|
||||||
arg = arg.replace("${" +var+ "}",launcherVariables[var])
|
|
||||||
args.append(arg)
|
|
||||||
elif "minecraftArguments" in clientJson:
|
|
||||||
margs = clientJson["minecraftArguments"].replace('"',"").split(" ")
|
|
||||||
for arg in margs:
|
|
||||||
if type(arg) != str: continue
|
|
||||||
for var in launcherVariables:
|
|
||||||
arg = arg.replace("${" +var+ "}",launcherVariables[var])
|
|
||||||
args.append(arg)
|
|
||||||
|
|
||||||
print("Launching Minecraft...")
|
print("Launching Minecraft...")
|
||||||
if lv["console"] == "1":
|
if lv["console"] == "1":
|
||||||
|
Loading…
Reference in New Issue
Block a user