diff options
author | Dylan Jones <dylanjones2011@gmail.com> | 2020-11-29 18:08:06 -0500 |
---|---|---|
committer | Dylan Jones <dylanjones2011@gmail.com> | 2020-11-29 18:08:06 -0500 |
commit | b29b1bb338e8745c24d5348de8f65f4667b9e22f (patch) | |
tree | e1252ee15b60fd76b695fe029d3c667291a56b87 /util.py | |
parent | f3fafd67f085265a02881ca01474e2b4555495c2 (diff) | |
download | modpackman-b29b1bb338e8745c24d5348de8f65f4667b9e22f.tar.gz modpackman-b29b1bb338e8745c24d5348de8f65f4667b9e22f.zip |
Begin installer code
Diffstat (limited to 'util.py')
-rw-r--r-- | util.py | 153 |
1 files changed, 43 insertions, 110 deletions
@@ -23,6 +23,9 @@ def load_config(): config = config_p._sections config["pack"]["sanitized_name"] = sanitize_text(config["pack"]["name"]) + if "location" not in config["pack"]: + config['pack']['location'] = os.path.join(find_minecraft_directory(), config['pack']['sanitized_name']) + if "whitelist" not in config["pack"]: config["pack"]["whitelist"] = [] else: @@ -30,19 +33,41 @@ def load_config(): config["pack"]["game_version"] = game_version_from_string(config["pack"]["game_version"]) - if "location" not in config["pack"]: - if sys.platform == "linux": - config["pack"]["location"] = os.path.join(os.path.expanduser('~'), ".minecraft", config['pack']['sanitized_name']) - elif sys.platform == "win32": - config["pack"]["location"] = os.path.join(os.environ["APPDATA"], ".minecraft", config['pack']['sanitized_name']) - elif sys.platform == "darwin": - config["pack"]["location"] = os.path.join(os.path.expanduser('~'), "Library", "Application Support", "minecraft", config['pack']['sanitized_name']) - else: - raise RuntimeError(f"Unsupported operating system `{sys.platform}`. Please define a location for the pack in your `local-config.ini` file") - # return the whole config file, pack configuration and modlist return config + +def find_minecraft_directory(): + """ + Find the location of the user's .minecraft folder based on + their operating system. + :returns: the absolute path to the .minecraft directory + """ + if sys.platform == "linux": + return os.path.join(os.path.expanduser('~'), ".minecraft") + elif sys.platform == "win32": + return os.path.join(os.environ["APPDATA"], ".minecraft") + elif sys.platform == "darwin": + return os.path.join(os.path.expanduser('~'), "Library", "Application Support", "minecraft") + else: + raise RuntimeError(f"Unsupported operating system `{sys.platform}`. Please define a location for the pack in your `local-config.ini` file") + + +def find_jre(): + """ + Find a usable install of Java, either from a user-installed JRE or + from the Minecraft Launcher's integrated JRE. + + :return: the absolute path of a working Java executable + """ + if shutil.which("java") is not None: + return shutil.which("java") + if sys.platform == 'win32': # We can try and use the Minecraft Launcher's integrated JRE on Windows + if os.path.exists("C:\\Program Files (x86)\\Minecraft Launcher\\runtime\\jre-x64\\java.exe"): + return "C:\\Program Files (x86)\\Minecraft Launcher\\runtime\\jre-x64\\java.exe" + raise RuntimeError("Unable to detect an installed JRE. Please install Java in order to use modpackman.") + + # take a string and only keep filename-friendly parts def sanitize_text(text): sanitized = "" @@ -87,100 +112,6 @@ def game_version_from_string(string): return (2, 0, 0) -# Apply updates to the actual mod pack -def install(version_file, whitelist, mods_location): - pack_version = get_version_from_file(version_file) - print("Updating pack with version " + str(pack_version) + "...") - print() - - # create the mods folder if it doesn't already exist - pathlib.Path(mods_location).mkdir(parents=True, exist_ok=True) - - # (fname, checksum, url) - mods = read_file(version_file) - names = [mod[0] for mod in mods] - # whitelist client mods (e.g. optifine) - names += whitelist - - i = 0 - for mod in mods: - mod_path = os.path.join(mods_location, mod[0]) - i += 1 - if os.path.exists(mod_path) and os.path.isfile(mod_path) and \ - hashlib.sha1(open(mod_path, 'rb').read()).hexdigest() == mod[1]: - print("Skipping {mod[0]}, already up to date".format(mod=mod)) - else: - print('Installing {mod[0]} from {mod[2]}...'.format(mod=mod)) - print(' ({i} of {x})'.format(i=i,x=len(mods)), end='\r') - download_obj = requests.get(mod[2], stream=True) - with open(mod_path, "wb") as write_file: - shutil.copyfileobj(download_obj.raw, write_file) - print("Done!" + " " * 8) - - print() - print("Removing old mods...") - for jar in os.listdir(mods_location): - if jar not in names and os.path.splitext(jar)[1] == ".jar": - os.remove(os.path.join(mods_location, jar)) - print("Removing '{jar}'".format(jar=jar)) - - print() - print("Finished installing mods!") - - -# Using the latest urls, update downloads.txt to match and have the correct sha1 -def apply_updates(mods, version_file, game_version=(2, 0, 0)): - pack_version = get_version_from_file(version_file) - print("Populating version file...") - print("Getting new versions of all mods...") - mod_urls = find_updated_urls([x for x in mods.values()], game_version, threads=3) - print("Downloading and checksumming all mods...") - checksums = find_checksums(mod_urls) - - # Write information out to version.txt - with open(version_file, 'w') as f: - f.write('# Format: <jarname> <hex digested sha1> <direct download url>\n') - f.write("#VERSION " + str(pack_version + 1) + "\n") - for name, checksum, url in zip((k+'.jar' for k in mods.keys()), checksums, mod_urls): - f.write(f'{name} {checksum} {url}\n') - - print() - print("Done!") - print(f"Updates applied to {version_file}") - print("New pack version is " + str(pack_version + 1)) - print("[!] No mods were installed. To update your mods folder, run 'update.py install'") - - -# Find if any updates are available -def check_updates(mods, version_file, version=(2, 0, 0)): - pack_version = get_version_from_file(version_file) - print("Checking for updates to version " + str(pack_version) + "...") - latest = [(k, mods[k]) for k in mods.keys()] - old = read_file(version_file) - old_urls = [mod[2] for mod in old] - num_updates = 0 - - print("Checking updates...") - ffx = firefox() - - for mod in latest: - print("Checking for updates to {mod[0]}...".format(mod=mod), end="") - sys.stdout.flush() # takes care of line-buffered terminals - if 'curseforge' in mod[1]: - url = find_cdn(ffx, mod[1], version) - else: - url = requests.get(mod[1]).url - if url in old_urls: - print(" No updates") - else: - print(" Found update: " + url.split('/')[-1]) - num_updates += 1 - ffx.close() - - print("Finished checking for updates. {num} mods can be updated".format(num=num_updates)) - if num_updates >= 0: - print("Run 'python update.py apply_updates' to create a new version with these updates applied.") - def threaded_find_url(homepage_url, game_version): """ @@ -292,9 +223,7 @@ def find_cdn(ffx, url, version): return f'https://media.forgecdn.net/files/{int(best_row.cdn_id[:4])}/{int(best_row.cdn_id[4:])}/{filename}' except: - print(url) - open('temp.txt', 'a').write(url) - import traceback; traceback.print_exc() + # import traceback; traceback.print_exc() return None @@ -313,7 +242,11 @@ def firefox(): options.add_argument('-headless') options.add_argument('--window-size 1920,1080') #for ~~cursed~~ windows people, put geckodriver in this folder - if(os.path.exists("./geckodriver")): - return Firefox(executable_path='./geckodriver', options=options) - return Firefox(options=options) + if(os.path.exists("./geckodriver.exe")): + return Firefox(executable_path='./geckodriver') + return Firefox() + +# Configuration is automatically loaded from pack.ini and local-config.ini, +# and made accessible here as a global +config = load_config() |