189 lines
8.4 KiB
Python
189 lines
8.4 KiB
Python
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. No backup required.")
|
|
|
|
# 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() |