141 lines
5.0 KiB
Python

import platform
from pathlib import PurePath, Path
from os import getenv
import subprocess
import json
import uuid
from zipfile import ZipFile
import datetime
import logging
import argparse
def get_sysroot():
if platform.system() == 'Windows':
if getenv('APPDATA'):
return PurePath(getenv('APPDATA'))
if platform.system() == 'Darwin':
return PurePath(Path.home(), 'Library', 'Application Support')
if platform.system() == 'Linux':
return PurePath(Path.home())
return None
def get_minecraft_folder(sys_root):
return sys_root / f"{'' if platform.system() == 'Darwin' else '.'}minecraft"
def get_installs(minecraft_folder):
with open(minecraft_folder / 'launcher_profiles.json') as f:
json_data = json.load(f)
return json_data.get('profiles')
def get_modpack_id(modpack_name, install_list):
for install in install_list:
if modpack_name in install_list[install]['name']:
return install
return None
def main(modpack_path, manifest_path, forge_installer=None):
# Get Minecraft Install Location
sys_root = get_sysroot()
if not sys_root:
sys_root = input("Unable to locate your minecraft install - please enter the path to it here: ")
logging.debug(f"System path set to: {sys_root}")
# Get Manifest info:
with open(manifest_path, 'r') as f:
manifest_info = json.load(f)
# Get Modpack Name from zipfile:
modpack_name = manifest_info['name']
logging.debug(f"Modpack name extracted as: {modpack_name}")
# Get Minecraft Installs
install_list = get_installs(get_minecraft_folder(sys_root))
modpack_id = get_modpack_id(modpack_name, install_list) or uuid.uuid4().hex
logging.debug(f"Modpack ID extracted as: {modpack_id}")
install_path = sys_root / '.moddedminecraft' / modpack_name.replace(' ', '_')
logging.debug(f"Modpack install path set to: {install_path}")
if forge_installer:
install_forge(forge_installer)
else:
logging.info("Forge installer not found/specified, assuming forge is already installed...")
# Check if modpack is already installed
if modpack_id not in install_list:
logging.info(f"Modpack {modpack_name} ({modpack_id}) not found in install list - creating...")
install_list[modpack_id] = {
'created': datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z',
'gameDir': str(install_path),
'icon': manifest_info['icon'],
'javaArgs': manifest_info['javaArgs'],
'lastUsed': '',
'lastVersionId': manifest_info['lastVersionId'],
'name': modpack_name,
'type': 'custom'
}
with open(get_minecraft_folder(sys_root) / 'launcher_profiles.json', 'r') as f:
full_profile_setup = json.load(f)
with open(get_minecraft_folder(sys_root) / 'launcher_profiles.json', 'w') as f:
full_profile_setup['profiles'] = install_list
json.dump(full_profile_setup, f, indent=2)
logging.info(f"Successfully added mod to installed profile list.")
# Validate file structure compared to mod zip
with ZipFile(modpack_path, 'r') as zip:
logging.info("Validating mod files...")
Path(install_path).mkdir(parents=True, exist_ok=True)
zip.extractall(install_path)
logging.info("Validation Completed.")
def find_modpack_files(path_to_search=PurePath()):
path = Path(path_to_search)
modpack_zip = None
modpack_manifest = None
forge_installer = None
for p in path.glob("*"):
if p.is_dir():
continue
elif '.jar' in p.name.lower():
forge_installer = p
elif '.zip' in p.name.lower():
modpack_zip = p
elif '.json' in p.name.lower():
modpack_manifest = p
return modpack_zip, modpack_manifest, forge_installer
def install_forge(forge_installer_path):
logging.info(f"Forge installer found, launching...")
subprocess.call(['java', '-jar', Path(forge_installer_path).resolve()])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--log_level", type=str, default='INFO', help='set logging level of this program', nargs='?')
parser.add_argument("--modpackpath", type=str, default=PurePath(), nargs='?')
parser.add_argument("--replace", type=bool, default=True, nargs='?', help='Overwrite contents of the mod folder')
args = parser.parse_args()
logging.basicConfig(filename='piston.log',
filemode='w',
level=getattr(logging, args.log_level.upper()),
format='[%(asctime)s] [%(levelname)s] %(message)s',
datefmt='%Y-%m-%dT%H:%M:%S')
target_dir = args.modpackpath or PurePath()
modpack_zip, modpack_manifest, forge_installer = find_modpack_files(target_dir)
main(modpack_zip, modpack_manifest, forge_installer)
logging.info("Done baking your cake - you can open your minecraft launcher now!")