import os import shutil import requests import zipfile from pathlib import Path from tqdm import tqdm # Minecraft installation folder. minecraft_dir = os.path.join(os.getenv('APPDATA'), ".minecraft") # Forge variables. forge_version = "1.12.2-forge-14.23.5.2859" forge_dir = os.path.join(minecraft_dir, f"versions/{forge_version}") forge_url = f"https://git.jisoonet.com/publicprojects/{forge_version}/-/archive/main/{forge_version}-main.zip" # Forge libraries variables. forge_libraries_version = "1.12.2-14.23.5.2859" forge_libraries_dir = os.path.join(minecraft_dir, f"libraries/net/minecraftforge/forge/{forge_libraries_version}") forge_libraries_url = f"https://git.jisoonet.com/publicprojects/{forge_libraries_version}/-/archive/main/{forge_libraries_version}-main.zip" # Backup folder for mods. mods_backup_dir = os.path.join(minecraft_dir, "mods-backup") # Modpack variables. modpack_name = "apocaz-modpack" modpack_dir = os.path.join(minecraft_dir, "mods") modpack_url = f"https://git.jisoonet.com/publicprojects/{modpack_name}/-/archive/main/{modpack_name}-main.zip" # Function to check for the prescence of Minecraft installation folder. def check_minecraft_installation(minecraft_dir): print("Checking for existing Minecraft installation...") if not Path(minecraft_dir).exists(): print("Error: Minecraft not found. Please install Minecraft first.") else: print("Minecraft is already installed.") # Diplays a progress bar. def download_with_progress_bar(url, destination_path): response = requests.get(url, stream=True) total_size_in_bytes = int(response.headers.get('content-length', 0)) block_size = 1024 progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True) with open(destination_path, 'wb') as file: for data in response.iter_content(block_size): progress_bar.update(len(data)) file.write(data) progress_bar.close() if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes: print("ERROR, something went wrong") # Installs forge files and places them in the correct version folder. def install_forge(forge_dir, forge_url): print("Checking for existing Forge installation...") if not Path(forge_dir).exists(): print("Forge not found, beginning installation...") os.makedirs(forge_dir) try: print("Downloading Forge...") zip_path = os.path.join(forge_dir, "forge.zip") download_with_progress_bar(forge_url, zip_path) with zipfile.ZipFile(zip_path) as z: print("Extracting Forge...") common_prefix = os.path.commonprefix(z.namelist()) for file_info in z.infolist(): target_path = os.path.join(forge_dir, file_info.filename[len(common_prefix):]) if file_info.filename.endswith('/'): os.makedirs(target_path, exist_ok=True) else: with z.open(file_info) as source, open(target_path, 'wb') as target: shutil.copyfileobj(source, target) print("Forge installed successfully.") os.remove(zip_path) # Don't forget to remove the temporary zip file except Exception as e: print(f"An error occurred during Forge installation: {e}") else: print("Forge is already installed.") # Installs forge files and places them in the correct version folder. def install_forge_libraries(forge_libraries_dir, forge_libraries_url): print("Checking for existing Forge libraries installation...") if not Path(forge_libraries_dir).exists(): print("Forge libraries not found, beginning download and installation...") os.makedirs(forge_libraries_dir) try: print("Downloading Forge libraries...") zip_path = os.path.join(forge_libraries_dir, "forge_libraries.zip") download_with_progress_bar(forge_libraries_url, zip_path) with zipfile.ZipFile(zip_path) as z: print("Extracting Forge libraries...") common_prefix = os.path.commonprefix(z.namelist()) for file_info in z.infolist(): target_path = os.path.join(forge_libraries_dir, file_info.filename[len(common_prefix):]) if file_info.filename.endswith('/'): os.makedirs(target_path, exist_ok=True) else: with z.open(file_info) as source_file, open(target_path, 'wb') as dest_file: shutil.copyfileobj(source_file, dest_file) print("Forge libraries installed successfully.") os.remove(zip_path) except Exception as e: print(f"An error occurred during Forge libraries installation: {e}") else: print("Forge libraries are already installed.") # Backups the mods from the mods folder to the backup folder. def backup_mods(modpack_dir, mods_backup_dir): print("Backing up existing mods...") if Path(modpack_dir).exists(): os.makedirs(mods_backup_dir, exist_ok=True) for item in os.listdir(modpack_dir): source_path = os.path.join(modpack_dir, item) destination_path = os.path.join(mods_backup_dir, item) if not os.path.exists(destination_path): shutil.move(source_path, destination_path) else: os.remove(source_path) print(f"Mods backed up to '{mods_backup_dir}'.") else: print("No mods directory found. Creating one now.") os.makedirs(modpack_dir, exist_ok=True) # Helper function to save the list of mod filenames as a manifest. def save_modpack_manifest(modpack_dir, mod_filenames): manifest_path = os.path.join(modpack_dir, 'modpack_manifest.txt') with open(manifest_path, 'w') as manifest_file: for filename in mod_filenames: manifest_file.write(f"{filename}\n") # Function to check if modpack is already installed based on the manifest. def is_modpack_installed(modpack_dir): manifest_path = os.path.join(modpack_dir, 'modpack_manifest.txt') if not os.path.exists(manifest_path): return False with open(manifest_path, 'r') as manifest_file: manifest_files = {line.strip() for line in manifest_file} existing_files = {file for file in os.listdir(modpack_dir) if os.path.isfile(os.path.join(modpack_dir, file))} return manifest_files.issubset(existing_files) and not manifest_files == set() # Updated install_modpack function. def install_modpack(modpack_url, modpack_dir, mods_backup_dir): if is_modpack_installed(modpack_dir): print("Modpack is already installed according to the manifest. Skipping download and installation.") return print("Modpack needs to be downloaded or updated. Proceeding with the installation.") try: backup_mods(modpack_dir, mods_backup_dir) zip_path = os.path.join(modpack_dir, "modpack.zip") download_with_progress_bar(modpack_url, zip_path) print("Extracting modpack...") modpack_files = set() with zipfile.ZipFile(zip_path) as modpack_zip: for member in modpack_zip.namelist(): if not member.endswith("/"): filename = os.path.basename(member) if filename: target_path = os.path.join(modpack_dir, filename) modpack_files.add(filename) source = modpack_zip.open(member) target = open(target_path, "wb") with source, target: shutil.copyfileobj(source, target) print("Modpack installed successfully.") os.remove(zip_path) save_modpack_manifest(modpack_dir, modpack_files) except Exception as e: print(f"An error occurred during modpack installation: {e}") # Entry point of the script. def main(): try: check_minecraft_installation(minecraft_dir) install_forge(forge_dir, forge_url) install_forge_libraries(forge_libraries_dir, forge_libraries_url) install_modpack(modpack_url, modpack_dir, mods_backup_dir) except KeyboardInterrupt: print("\033[91m\nSession ended by user.\033[0m") except Exception as e: print(f"\033[91m\nAn unexpected error occurred: {e}\033[0m") finally: input("\033[94mPress Enter to exit...\033[0m") if __name__ == "__main__": main()