#!/usr/bin/env python3 import sys oldexcepthook = sys.excepthook def newexcepthook(type,value,traceback): oldexcepthook(type,value,traceback) input("Press ENTER to quit.") sys.excepthook = newexcepthook import os p = os.path.join pUp = os.path.dirname s = False if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): s = os.path.realpath(sys.executable) else: s = os.path.realpath(__file__) sp = pUp(s) import subprocess import json import hashlib import platform p = os.path.join os.environ["appdata"] = p(sp,"appdata") java = p(sp,"java","bin","java.exe") jvmArguments = ["-Xms256M","-Xmx800M"] osName = platform.system().lower() if osName == "darwin": osName = "macos" def readJsonFile(file): fileh = open(file,"r") data = fileh.read() fileh.close() return json.loads(data) def main(): global version global name global osName if len(sys.argv) > 1: for arg in sys.argv[1:]: argSplit = arg.split("=",1) if len(argSplit) > 1: globals()[argSplit[0]] = argSplit[1] if not osName in ["windows","linux","macos"]: print("Warning, unsupported OS detected: " +osName) print("Needs to be either windows, linux or macos. Define it with osName=name in the commandline.") print("") if not "version" in globals(): version = input("Version ID: ") if not "name" in globals(): name = input("Player name: ") gamePath = p(os.environ["appdata"],".minecraft") versionPath = p(gamePath,"versions",version) libraryPath = p(gamePath,"libraries") nativesPath = p(gamePath,"natives") nativesOutPath = p(versionPath,"natives") assetsPath = p(gamePath,"assets") print("Extracting natives...") clientJson = readJsonFile(p(versionPath,version + ".json")) libraryList = "" for library in clientJson["libraries"]: if "artifact" in library["downloads"]: library["downloads"]["artifact"]["path"] = library["downloads"]["artifact"]["path"].replace("/",os.path.sep) libraryList += p(libraryPath,library["downloads"]["artifact"]["path"]) + ";" if "classifiers" in library["downloads"]: if "natives-" +osName in library["downloads"]["classifiers"]: native = library["downloads"]["classifiers"]["natives-" +osName] 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,version + ".jar") #print(libraryList) launcherVariables = {} launcherVariables["auth_player_name"] = name launcherVariables["version_name"] = version launcherVariables["game_directory"] = gamePath launcherVariables["assets_root"] = assetsPath launcherVariables["assets_index_name"] = clientJson["assets"] launcherVariables["auth_access_token"] = "-" launcherVariables["auth_uuid"] = hashlib.md5(name.encode('utf-8')).hexdigest() launcherVariables["user_type"] = "offline" launcherVariables["version_type"] = clientJson["type"] args = jvmArguments args.append("-Djava.library.path=" +nativesOutPath) args.append("-cp") args.append(libraryList) args.append(clientJson["mainClass"]) if "arguments" in clientJson: for arg in clientJson["arguments"]["game"]: if type(arg) != str: continue for var in launcherVariables: 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...") subprocess.call([java] + args) main()