from ftplib import FTP import os import io import json import tempfile import subprocess import time import tkinter as tk from tkinter import filedialog import configparser import customtkinter from customtkinter import * # Initialize a configparser object for managing the configuration file config = configparser.ConfigParser() config_file_path = 'config.ini' # Path to the configuration file def select_prism_instance_path(): global prism_instance_path_entry directory = filedialog.askdirectory() prism_instance_path_entry.delete(0, tk.END) prism_instance_path_entry.insert(0, directory) # Store the selected path in the configuration file config['PRISM'] = {'InstancePath': directory} with open(config_file_path, 'w') as configfile: config.write(configfile) def main(): global prism_instance_path_entry instance_name = "Familycraft Season 7" prism_command = "prismlauncher" # Default paths based on OS if os.name == 'nt': prism_command = os.getenv('LOCALAPPDATA') + "/Programs/PrismLauncher/prismlauncher.exe" default_prism_instance_path = os.getenv("APPDATA") + "/PrismLauncher/instances" else: prism_command = "prismlauncher" # Update with the correct path for Linux/Mac default_prism_instance_path = os.getenv("HOME") + "/.local/share/PrismLauncher/instances" # Load stored Prism instance path from the configuration file if os.path.exists(config_file_path): config.read(config_file_path) if 'PRISM' in config and 'InstancePath' in config['PRISM']: stored_prism_instance_path = config['PRISM']['InstancePath'] else: stored_prism_instance_path = default_prism_instance_path else: stored_prism_instance_path = default_prism_instance_path # GUI for selecting Prism instance path app = CTk() app.title("FamilyCraft Launcher") set_appearance_mode("dark") #root.title("Select Prism Instance Path") # Label for instructions label = CTkLabel(master=app, text="Select Prism instance path:", font=("Impact", 30)) label.pack(pady=10) # Entry widget for Prism instance path prism_instance_path_entry = CTkEntry(master=app, width=350, font=("Arial", 14)) prism_instance_path_entry.pack(pady=5) # If a stored Prism instance path exists, pre-fill the entry widget if stored_prism_instance_path: prism_instance_path_entry.insert(0, stored_prism_instance_path) # Button to select directory select_button = CTkButton(master=app, text="Browse...", command=select_prism_instance_path) select_button.pack(pady=5) # Function to proceed with installation def start_installation(): prism_instance_path = prism_instance_path_entry.get() app.destroy() # Close the GUI window perform_installation(instance_name, prism_command, prism_instance_path) # Button to start installation install_button = CTkButton(master=app, text="Launch Minecraft", command=start_installation) install_button.pack(pady=10) app.mainloop() def perform_installation(instance_name, prism_command, prism_instance_path): ftp = FTP("gitea.piwalker.net") ftp.login() # Fetching versions.json from FTP bio = io.BytesIO() ftp.retrbinary("RETR versions.json", bio.write) bio.seek(0) versions = json.load(bio) bio.close() # Checking current version version = "0.0.0" version_file_path = os.path.join(prism_instance_path, instance_name, ".minecraft", "version.txt") if os.path.exists(version_file_path): with open(version_file_path, 'r') as fp: version = fp.readline().rstrip() # Checking if update is needed if version != versions[-1]["Version"]: print(f"Current version: {version}") print(f"Latest version: {versions[-1]['Version']}") # Downloading modpack with tempfile.TemporaryDirectory() as temp_dir: modpack_file_path = os.path.join(temp_dir, instance_name + ".mrpack") with open(modpack_file_path, 'wb') as modpack: ftp.retrbinary("RETR " + versions[-1]["File"], modpack.write) # Running PrismLauncher with modpack p = subprocess.Popen([prism_command, '-I', modpack_file_path]) # Waiting for installation to complete while True: time.sleep(5) if os.path.exists(version_file_path): with open(version_file_path, 'r') as fp: version = fp.readline().rstrip() if version == versions[-1]["Version"]: break # Launching PrismLauncher with the instance subprocess.run([prism_command, '-l', instance_name]) if __name__ == "__main__": main()