aboutsummaryrefslogtreecommitdiff
path: root/util.py
diff options
context:
space:
mode:
authorDylan Jones <dylanjones2011@gmail.com>2020-11-29 18:08:06 -0500
committerDylan Jones <dylanjones2011@gmail.com>2020-11-29 18:08:06 -0500
commitb29b1bb338e8745c24d5348de8f65f4667b9e22f (patch)
treee1252ee15b60fd76b695fe029d3c667291a56b87 /util.py
parentf3fafd67f085265a02881ca01474e2b4555495c2 (diff)
downloadmodpackman-b29b1bb338e8745c24d5348de8f65f4667b9e22f.tar.gz
modpackman-b29b1bb338e8745c24d5348de8f65f4667b9e22f.zip
Begin installer code
Diffstat (limited to 'util.py')
-rw-r--r--util.py153
1 files changed, 43 insertions, 110 deletions
diff --git a/util.py b/util.py
index 3e9e918..fba40fe 100644
--- a/util.py
+++ b/util.py
@@ -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()