#!/usr/bin/env python3
import os
import sys
if hasattr(sys, '_MEIPASS'): # we're running in a bundle, go where we have our bundled assets
os.chdir(sys._MEIPASS)
import subprocess
import requests
import tempfile
import shutil
import subprocess
import json
import uuid
import pathlib
from modpackman import install
from util import config
import util
def install_forge():
"""
:param java_path: path to a working Java executable
Downloads and runs the Forge installer specified in pack.ini.
"""
with tempfile.TemporaryDirectory() as working_dir:
forge_path = os.path.join(working_dir, "forge_installer.jar")
util.download_file(config['pack']['forge_url'], forge_path)
try:
subprocess.check_output([util.find_jre(), "-jar", forge_path])
except RuntimeError:
if sys.platform == 'win32':
# if we can't find java, see if Windows can...
subprocess.check_output([f'cmd /C start "" "{forge_path}"'])
else:
raise
def setup_forge(profile_id):
path_to_profiles = os.path.join(util.find_minecraft_directory(), "launcher_profiles.json")
# first, find current profiles so we can figure out which forge installs
with open(path_to_profiles, "r") as f:
profiles = json.load(f)
old_profile_ids = set(profiles["profiles"].keys())
# install forge, should add a new profile
install_forge()
with open(path_to_profiles, "r") as f:
profiles = json.load(f)
difference = set(profiles["profiles"].keys()) - old_profile_ids
if difference:
forge_profile_id = next(iter(difference))
forge_game_version = profiles["profiles"][forge_profile_id]["lastVersionId"]
del profiles["profiles"][forge_profile_id]
else:
# this will probably break soon :(
game_version, forge_version = config["pack"]["forge_url"].split("/")[-2].split('-')
forge_game_version = f"{game_version}-forge-{forge_version}"
if profile_id not in profiles["profiles"]:
profile = {
"name": config["pack"]["name"],
"gameDir": config["pack"]["location"],
"lastVersionId": forge_game_version,
"type": "custom",
"javaArgs": config["pack"]["java_args"],
"icon": util.generate_base64_icon("icon.png")
}
profiles["profiles"][profile_id] = profile
else:
profile = profiles["profiles"][profile_id]
profile["lastVersionId"] = forge_game_version
profile["icon"] = util.generate_base64_icon("icon.png")
with open(path_to_profiles, "w") as f:
json.dump(profiles, f, indent=2)
def main():
# if we're in a bundle, download the latest pack data from remote source
if hasattr(sys, "_MEIPASS"):
util.update_self()
persistent_data_path = os.path.join(config["pack"]["location"], "modpackman.json")
if os.path.exists(persistent_data_path):
with open(persistent_data_path, "r") as f:
persistent_data = json.load(f)
else:
# this is the first time this pack is installed
pathlib.Path(config["pack"]["location"]).mkdir(parents=True, exist_ok=True)
persistent_data = {"last_forge_url": "no", "profile_id": str(uuid.uuid4()).replace('-', '')}
if os.path.exists(os.path.join(util.find_minecraft_directory(), 'options.txt')):
shutil.copyfile(os.path.join(util.find_minecraft_directory(), 'options.txt'), os.path.join(config["pack"]["location"], "options.txt"))
if config["pack"]["forge_url"] != persistent_data["last_forge_url"]:
setup_forge(persistent_data["profile_id"])
persistent_data["last_forge_url"] = config["pack"]["forge_url"]
with open(persistent_data_path, "w") as f:
json.dump(persistent_data, f, indent=2)
##todo install mods
install()
if __name__ == '__main__':
main()