Add files via upload

This commit is contained in:
Nix 2025-03-25 06:59:47 -03:00 committed by GitHub
parent ba8072c669
commit 18120360cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 153 additions and 158 deletions

30
modulecli.py Normal file
View File

@ -0,0 +1,30 @@
import click
from picomc.cli.main import picomc_cli
from io import StringIO
import sys
def run_command(command="picomc"):
# Redirect stdout and stderr to capture the command output
old_stdout, old_stderr = sys.stdout, sys.stderr
sys.stdout = mystdout = StringIO()
sys.stderr = mystderr = StringIO()
try:
picomc_cli.main(args=command.split())
except SystemExit as e:
if e.code != 0:
print(f"Command exited with code {e.code}", file=sys.stderr)
except Exception as e:
print(f"Unexpected error: {e}", file=sys.stderr)
finally:
# Restore stdout and stderr
sys.stdout = old_stdout
sys.stderr = old_stderr
output = mystdout.getvalue().strip()
error = mystderr.getvalue().strip()
if not output:
return f"Error: No output from command. Stderr: {error}"
return output

View File

@ -13,13 +13,14 @@ import time
from authser import MinecraftAuthenticator from authser import MinecraftAuthenticator
from healthcheck import HealthCheck from healthcheck import HealthCheck
import modulecli
from PyQt5.QtWidgets import QApplication, QComboBox, QWidget, QInputDialog, QVBoxLayout, QListWidget, QPushButton, QMessageBox, QDialog, QHBoxLayout, QLabel, QLineEdit, QCheckBox, QTabWidget, QFrame, QSpacerItem, QSizePolicy, QMainWindow, QGridLayout, QTextEdit, QListWidget, QListWidgetItem, QMenu from PyQt5.QtWidgets import QApplication, QComboBox, QWidget, QInputDialog, QVBoxLayout, QListWidget, QPushButton, QMessageBox, QDialog, QHBoxLayout, QLabel, QLineEdit, QCheckBox, QTabWidget, QFrame, QSpacerItem, QSizePolicy, QMainWindow, QGridLayout, QTextEdit, QListWidget, QListWidgetItem, QMenu
from PyQt5.QtGui import QFont, QIcon, QColor, QPalette, QMovie, QPixmap, QDesktopServices, QBrush from PyQt5.QtGui import QFont, QIcon, QColor, QPalette, QMovie, QPixmap, QDesktopServices, QBrush
from PyQt5.QtCore import Qt, QObject, pyqtSignal, QThread, QUrl, QMetaObject, Q_ARG, QByteArray, QSize from PyQt5.QtCore import Qt, QObject, pyqtSignal, QThread, QUrl, QMetaObject, Q_ARG, QByteArray, QSize
from datetime import datetime from datetime import datetime
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.ERROR, format='%(levelname)s - %(message)s')
class PicomcVersionSelector(QWidget): class PicomcVersionSelector(QWidget):
def __init__(self): def __init__(self):
@ -126,11 +127,13 @@ class PicomcVersionSelector(QWidget):
try: try:
self.config_path = "config.json" self.config_path = "config.json"
print("Running picomc instance create default command...") print("Running picomc instance create default command...")
# Run the command using subprocess
result = subprocess.run(["picomc", "instance", "create", "default"], check=True, capture_output=True, text=True) # Run the command using modulecli
command = "instance create default"
result = modulecli.run_command(command)
# Print the output of the command # Print the output of the command
print("Command output:", result.stdout) print("Command output:", result)
# Change the value of IsFirstLaunch to False # Change the value of IsFirstLaunch to False
self.config["IsFirstLaunch"] = False self.config["IsFirstLaunch"] = False
@ -141,9 +144,9 @@ class PicomcVersionSelector(QWidget):
json.dump(self.config, f, indent=4) json.dump(self.config, f, indent=4)
print("Configuration saved to", self.config_path) print("Configuration saved to", self.config_path)
except subprocess.CalledProcessError as e: except Exception as e:
print("An error occurred while creating the instance.") print("An error occurred while creating the instance.")
print("Error output:", e.stderr) print("Error output:", str(e))
def resize_event(self, event): def resize_event(self, event):
if hasattr(self, 'movie_label'): if hasattr(self, 'movie_label'):
@ -394,8 +397,8 @@ class PicomcVersionSelector(QWidget):
discord_rcp_checkbox.isChecked(), discord_rcp_checkbox.isChecked(),
check_updates_checkbox.isChecked(), check_updates_checkbox.isChecked(),
theme_background_checkbox.isChecked(), theme_background_checkbox.isChecked(),
self.selected_theme, # Pass the selected theme here self.selected_theme,
bleeding_edge_checkbox.isChecked() # Pass the bleeding edge setting here bleeding_edge_checkbox.isChecked()
) )
) )
@ -659,20 +662,6 @@ class PicomcVersionSelector(QWidget):
) )
self.__init__() self.__init__()
def get_palette(self, palette_type):
"""Retrieve the corresponding palette based on the palette type."""
palettes = {
"Dark": self.create_dark_palette,
"Obsidian": self.create_obsidian_palette,
"Redstone": self.create_redstone_palette,
"Alpha": self.create_alpha_palette,
"Strawberry": self.create_strawberry_palette,
"Native": self.create_native_palette,
"Christmas": self.create_christmas_palette,
}
# Default to dark palette if the type is not specified or invalid
return palettes.get(palette_type, self.create_dark_palette)()
def get_system_info(self): def get_system_info(self):
# Get system information # Get system information
java_version = subprocess.getoutput("java -version 2>&1 | head -n 1") java_version = subprocess.getoutput("java -version 2>&1 | head -n 1")
@ -712,16 +701,16 @@ class PicomcVersionSelector(QWidget):
def open_game_directory(self): def open_game_directory(self):
try: try:
# Run the command and capture the output # Run the command using modulecli
result = subprocess.run(['picomc', 'instance', 'dir'], capture_output=True, text=True, check=True) command = "instance dir"
game_directory = result.stdout.strip() result = modulecli.run_command(command)
game_directory = result.strip()
# Open the directory in the system's file explorer # Open the directory in the system's file explorer
QDesktopServices.openUrl(QUrl.fromLocalFile(game_directory)) QDesktopServices.openUrl(QUrl.fromLocalFile(game_directory))
except subprocess.CalledProcessError as e: except Exception as e:
print(f"Error running picomc command: {e}") print(f"Error running picomc command: {e}")
def populate_installed_versions(self): def populate_installed_versions(self):
config_path = "config.json" config_path = "config.json"
@ -742,20 +731,17 @@ class PicomcVersionSelector(QWidget):
# Run the command and capture the output # Run the command and capture the output
try: try:
process = subprocess.Popen(['picomc', 'version', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = "version list"
output, error = process.communicate() output = modulecli.run_command(command)
if process.returncode != 0: if not output:
raise subprocess.CalledProcessError(process.returncode, process.args, output=output, stderr=error) raise Exception("Failed to get output from modulecli")
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please ensure it's installed and in your PATH.") logging.error("Error running 'picomc': %s", e)
return
except subprocess.CalledProcessError as e:
logging.error("Error running 'picomc': %s", e.stderr)
return return
# Parse the output and replace '[local]' with a space # Parse the output and replace '[local]' with a space
versions = [version.replace('[local]', ' ').strip() for version in output.splitlines()] versions = [version.replace('[local]', ' ').strip() for version in output.splitlines() if version.strip()]
# Get the last played version from the config # Get the last played version from the config
last_played = self.config.get("LastPlayed", "") last_played = self.config.get("LastPlayed", "")
@ -768,32 +754,26 @@ class PicomcVersionSelector(QWidget):
# Populate the installed versions combo box # Populate the installed versions combo box
self.installed_version_combo.clear() self.installed_version_combo.clear()
self.installed_version_combo.addItems(versions) self.installed_version_combo.addItems(versions)
def populate_installed_versions_normal_order(self): def populate_installed_versions_normal_order(self):
# Run the 'picomc instance create default' command at the start # Run the 'picomc instance create default' command at the start
try: try:
process = subprocess.Popen(['picomc', 'instance', 'create', 'default'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = "instance create default"
output, error = process.communicate() output = modulecli.run_command(command)
if process.returncode != 0: if not output:
raise subprocess.CalledProcessError(process.returncode, process.args, error) raise Exception("Failed to get output from modulecli for 'instance create default'")
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.") logging.error("Error creating default instance: %s", str(e))
return
except subprocess.CalledProcessError as e:
logging.error("Error creating default instance: %s", e.stderr)
return return
# Run the 'picomc version list' command and get the output # Run the 'picomc version list' command and get the output
try: try:
process = subprocess.Popen(['picomc', 'version', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = "version list"
output, error = process.communicate() output = modulecli.run_command(command)
if process.returncode != 0: if not output:
raise subprocess.CalledProcessError(process.returncode, process.args, error) raise Exception("Failed to get output from modulecli for 'version list'")
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.") logging.error("Error: %s", str(e))
return
except subprocess.CalledProcessError as e:
logging.error("Error: %s", e.stderr)
return return
# Parse the output and replace '[local]' with a space # Parse the output and replace '[local]' with a space
@ -820,7 +800,7 @@ class PicomcVersionSelector(QWidget):
# Check if there are any accounts # Check if there are any accounts
try: try:
account_list_output = subprocess.check_output(["picomc", "account", "list"]).decode("utf-8").strip() account_list_output = modulecli.run_command("account list").strip()
if not account_list_output: if not account_list_output:
QMessageBox.warning(self, "No Account Available", "Please create an account first.") QMessageBox.warning(self, "No Account Available", "Please create an account first.")
return return
@ -829,18 +809,25 @@ class PicomcVersionSelector(QWidget):
if '*' not in account_list_output: if '*' not in account_list_output:
QMessageBox.warning(self, "No Account Selected", "Please select an account.") QMessageBox.warning(self, "No Account Selected", "Please select an account.")
return return
except subprocess.CalledProcessError as e: except Exception as e:
error_message = f"Error fetching accounts: {str(e)}" error_message = f"Error fetching accounts: {str(e)}"
logging.error(error_message) logging.error(error_message)
QMessageBox.critical(self, "Error", error_message) QMessageBox.critical(self, "Error", error_message)
return return
selected_instance = self.installed_version_combo.currentText() selected_instance = self.installed_version_combo.currentText()
logging.info(f"Selected instance: {selected_instance}") logging.info(f"Selected instance from dropdown: {selected_instance}")
# Verify the selected instance value before starting the game
if not selected_instance:
logging.error("No instance selected.")
QMessageBox.warning(self, "No Instance Selected", "Please select an instance.")
return
play_thread = threading.Thread(target=self.run_game, args=(selected_instance,)) play_thread = threading.Thread(target=self.run_game, args=(selected_instance,))
play_thread.start() play_thread.start()
def run_game(self, selected_instance): def run_game(self, selected_instance):
try: try:
# Set current_state to the selected instance # Set current_state to the selected instance
@ -855,10 +842,14 @@ class PicomcVersionSelector(QWidget):
update_thread = threading.Thread(target=self.update_last_played, args=(selected_instance,)) update_thread = threading.Thread(target=self.update_last_played, args=(selected_instance,))
update_thread.start() update_thread.start()
# Run the game subprocess with the instance_value from config.json # Run the game using the modulecli module
subprocess.run(['picomc', 'instance', 'launch', '--version-override', selected_instance, instance_value], check=True) command = f"instance launch --version-override {selected_instance} {instance_value}"
output = modulecli.run_command(command)
if not output:
raise Exception("Failed to get output from modulecli")
except subprocess.CalledProcessError as e: except Exception as e:
error_message = f"Error playing {selected_instance}: {e}" error_message = f"Error playing {selected_instance}: {e}"
logging.error(error_message) logging.error(error_message)
# Use QMetaObject.invokeMethod to call showError safely # Use QMetaObject.invokeMethod to call showError safely
@ -870,6 +861,7 @@ class PicomcVersionSelector(QWidget):
# Reset current_state to "menu" after the game closes # Reset current_state to "menu" after the game closes
self.current_state = "menu" self.current_state = "menu"
def update_last_played(self, selected_instance): def update_last_played(self, selected_instance):
config_path = "config.json" config_path = "config.json"
self.config["LastPlayed"] = selected_instance self.config["LastPlayed"] = selected_instance
@ -967,16 +959,16 @@ class PicomcVersionSelector(QWidget):
return return
try: try:
command = ['picomc', 'account', 'create', username] command = f"account create {username}"
if is_microsoft: if is_microsoft:
command.append('--ms') command += " --ms"
subprocess.run(command, check=True) modulecli.run_command(command)
QMessageBox.information(dialog, "Success", f"Account '{username}' created successfully!") QMessageBox.information(dialog, "Success", f"Account '{username}' created successfully!")
self.populate_accounts_for_all_dialogs() self.populate_accounts_for_all_dialogs()
dialog.accept() dialog.accept()
except subprocess.CalledProcessError as e: except Exception as e:
error_message = f"Error creating account: {e.stderr.decode()}" error_message = f"Error creating account: {str(e)}"
logging.error(error_message) logging.error(error_message)
QMessageBox.critical(dialog, "Error", error_message) QMessageBox.critical(dialog, "Error", error_message)
@ -1029,23 +1021,21 @@ class PicomcVersionSelector(QWidget):
confirm_dialog = QMessageBox.question(dialog, "Confirm Removal", confirm_message, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) confirm_dialog = QMessageBox.question(dialog, "Confirm Removal", confirm_message, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if confirm_dialog == QMessageBox.Yes: if confirm_dialog == QMessageBox.Yes:
try: try:
subprocess.run(['picomc', 'account', 'remove', username], check=True) command = f"account remove {username}"
modulecli.run_command(command)
QMessageBox.information(dialog, "Success", f"Account '{username}' removed successfully!") QMessageBox.information(dialog, "Success", f"Account '{username}' removed successfully!")
self.populate_accounts_for_all_dialogs() self.populate_accounts_for_all_dialogs()
except subprocess.CalledProcessError as e: except Exception as e:
error_message = f"Error removing account: {e.stderr.decode()}" error_message = f"Error removing account: {str(e)}"
logging.error(error_message) logging.error(error_message)
QMessageBox.critical(dialog, "Error", error_message) QMessageBox.critical(dialog, "Error", error_message)
def populate_accounts(self, account_combo): def populate_accounts(self, account_combo):
# Populate the account dropdown # Populate the account dropdown
try: try:
process = subprocess.Popen(['picomc', 'account', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = "account list"
output, error = process.communicate() output = modulecli.run_command(command)
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
# Process accounts, keeping the one with "*" at the top # Process accounts, keeping the one with "*" at the top
accounts = output.splitlines() accounts = output.splitlines()
starred_account = None starred_account = None
@ -1069,10 +1059,8 @@ class PicomcVersionSelector(QWidget):
for account in normal_accounts: for account in normal_accounts:
account_combo.addItem(account) account_combo.addItem(account)
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.") logging.error(f"Error: {str(e)}")
except subprocess.CalledProcessError as e:
logging.error(f"Error: {e.stderr}")
def populate_accounts_for_all_dialogs(self): def populate_accounts_for_all_dialogs(self):
# Update account dropdowns in all open dialogs # Update account dropdowns in all open dialogs
@ -1089,14 +1077,16 @@ class PicomcVersionSelector(QWidget):
return return
try: try:
subprocess.run(['picomc', 'account', 'setdefault', account_name], check=True) command = f"account setdefault {account_name}"
modulecli.run_command(command)
QMessageBox.information(self, "Success", f"Account '{account_name}' set as default!") QMessageBox.information(self, "Success", f"Account '{account_name}' set as default!")
self.populate_accounts_for_all_dialogs() self.populate_accounts_for_all_dialogs()
except subprocess.CalledProcessError as e: except Exception as e:
error_message = f"Error setting default account '{account_name}': {e.stderr.decode()}" error_message = f"Error setting default account '{account_name}': {str(e)}"
logging.error(error_message) logging.error(error_message)
QMessageBox.critical(self, "Error", error_message) QMessageBox.critical(self, "Error", error_message)
def show_about_dialog(self): def show_about_dialog(self):
# Load the version number from version.json # Load the version number from version.json
try: try:
@ -1326,10 +1316,11 @@ class DownloadThread(QThread):
def run(self): def run(self):
try: try:
subprocess.run(['picomc', 'version', 'prepare', self.version], check=True) command = f"version prepare {self.version}"
modulecli.run_command(command)
self.completed.emit(True, f"Version {self.version} prepared successfully!") self.completed.emit(True, f"Version {self.version} prepared successfully!")
except subprocess.CalledProcessError as e: except Exception as e:
error_message = f"Error preparing {self.version}: {e.stderr.decode()}" error_message = f"Error preparing {self.version}: {str(e)}"
self.completed.emit(False, error_message) self.completed.emit(False, error_message)
class ModLoaderAndVersionMenu(QDialog): class ModLoaderAndVersionMenu(QDialog):
@ -1346,11 +1337,11 @@ class ModLoaderAndVersionMenu(QDialog):
# Create tabs # Create tabs
install_mod_tab = QWidget() install_mod_tab = QWidget()
download_version_tab = QWidget() download_version_tab = QWidget()
instances_tab = QWidget() # New tab for instances instances_tab = QWidget()
tab_widget.addTab(download_version_tab, "Download Version") tab_widget.addTab(download_version_tab, "Download Version")
tab_widget.addTab(install_mod_tab, "Install Mod Loader") tab_widget.addTab(install_mod_tab, "Install Mod Loader")
tab_widget.addTab(instances_tab, "Instances") # Add the new tab tab_widget.addTab(instances_tab, "Instances")
# Add content to "Install Mod Loader" tab # Add content to "Install Mod Loader" tab
self.setup_install_mod_loader_tab(install_mod_tab) self.setup_install_mod_loader_tab(install_mod_tab)
@ -1402,11 +1393,8 @@ class ModLoaderAndVersionMenu(QDialog):
if instance_name: if instance_name:
try: try:
# Run the "picomc instance create" command # Run the "picomc instance create" command
process = subprocess.Popen(['picomc', 'instance', 'create', instance_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = f"instance create {instance_name}"
output, error = process.communicate() modulecli.run_command(command)
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
# Notify the user that the instance was created # Notify the user that the instance was created
QMessageBox.information(self, "Instance Created", f"Instance '{instance_name}' has been created successfully.") QMessageBox.information(self, "Instance Created", f"Instance '{instance_name}' has been created successfully.")
@ -1417,11 +1405,9 @@ class ModLoaderAndVersionMenu(QDialog):
# Optionally select the newly created instance # Optionally select the newly created instance
self.on_instance_selected(self.instances_list_widget.item(self.instances_list_widget.count() - 1)) self.on_instance_selected(self.instances_list_widget.item(self.instances_list_widget.count() - 1))
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.") logging.error("Error creating instance: %s", str(e))
except subprocess.CalledProcessError as e: QMessageBox.critical(self, "Error", f"Failed to create instance: {str(e)}")
logging.error("Error creating instance: %s", e.stderr)
QMessageBox.critical(self, "Error", f"Failed to create instance: {e.stderr}")
else: else:
QMessageBox.warning(self, "Invalid Input", "Please enter a valid instance name.") QMessageBox.warning(self, "Invalid Input", "Please enter a valid instance name.")
@ -1432,14 +1418,8 @@ class ModLoaderAndVersionMenu(QDialog):
try: try:
# Run the "picomc instance rename" command # Run the "picomc instance rename" command
process = subprocess.Popen( command = f"instance rename {old_instance_name} {new_instance_name}"
['picomc', 'instance', 'rename', old_instance_name, new_instance_name], modulecli.run_command(command)
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
output, error = process.communicate()
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
QMessageBox.information(self, "Instance Renamed", f"Instance '{old_instance_name}' has been renamed to '{new_instance_name}' successfully.") QMessageBox.information(self, "Instance Renamed", f"Instance '{old_instance_name}' has been renamed to '{new_instance_name}' successfully.")
@ -1451,11 +1431,9 @@ class ModLoaderAndVersionMenu(QDialog):
if matching_items: if matching_items:
self.instances_list_widget.setCurrentItem(matching_items[0]) self.instances_list_widget.setCurrentItem(matching_items[0])
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.") logging.error("Error renaming instance: %s", str(e))
except subprocess.CalledProcessError as e: QMessageBox.critical(self, "Error", f"Failed to rename instance: {str(e)}")
logging.error("Error renaming instance: %s", e.stderr)
QMessageBox.critical(self, "Error", f"Failed to rename instance: {e.stderr}")
def delete_instance(self, instance_name): def delete_instance(self, instance_name):
if instance_name == "default": if instance_name == "default":
@ -1470,11 +1448,8 @@ class ModLoaderAndVersionMenu(QDialog):
if confirm_delete == QMessageBox.Yes: if confirm_delete == QMessageBox.Yes:
try: try:
# Run the "picomc instance delete" command # Run the "picomc instance delete" command
process = subprocess.Popen(['picomc', 'instance', 'delete', instance_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = f"instance delete {instance_name}"
output, error = process.communicate() modulecli.run_command(command)
if process.returncode != 0:
raise subprocess.CalledProcessError(process.returncode, process.args, error)
# Notify the user that the instance was deleted # Notify the user that the instance was deleted
QMessageBox.information(self, "Instance Deleted", f"Instance '{instance_name}' has been deleted successfully.") QMessageBox.information(self, "Instance Deleted", f"Instance '{instance_name}' has been deleted successfully.")
@ -1482,19 +1457,16 @@ class ModLoaderAndVersionMenu(QDialog):
# Reload the instances list # Reload the instances list
self.load_instances() self.load_instances()
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.") logging.error("Error deleting instance: %s", str(e))
except subprocess.CalledProcessError as e: QMessageBox.critical(self, "Error", f"Failed to delete instance: {str(e)}")
logging.error("Error deleting instance: %s", e.stderr)
QMessageBox.critical(self, "Error", f"Failed to delete instance: {e.stderr}")
def load_instances(self): def load_instances(self):
try: try:
process = subprocess.Popen(['picomc', 'instance', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # Run the "picomc instance list" command
output, error = process.communicate() command = "instance list"
if process.returncode != 0: output = modulecli.run_command(command)
raise subprocess.CalledProcessError(process.returncode, process.args, error)
# Parse the output and add each instance to the list widget # Parse the output and add each instance to the list widget
instances = output.splitlines() instances = output.splitlines()
self.instances_list_widget.clear() # Clear the previous list self.instances_list_widget.clear() # Clear the previous list
@ -1503,10 +1475,9 @@ class ModLoaderAndVersionMenu(QDialog):
self.instances_list_widget.addItem(item) self.instances_list_widget.addItem(item)
self.add_instance_buttons(item, instance) self.add_instance_buttons(item, instance)
except FileNotFoundError: except Exception as e:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.") logging.error("Error fetching instances: %s", str(e))
except subprocess.CalledProcessError as e:
logging.error("Error fetching instances: %s", e.stderr)
def add_instance_buttons(self, list_item, instance_name): def add_instance_buttons(self, list_item, instance_name):
widget = QWidget() widget = QWidget()
@ -1662,21 +1633,19 @@ class ModLoaderAndVersionMenu(QDialog):
options.append('--beta') options.append('--beta')
if options: if options:
try: try:
process = subprocess.Popen(['picomc', 'version', 'list'] + options, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = 'version list ' + ' '.join(options)
output, error = process.communicate() output = modulecli.run_command(command)
if process.returncode != 0: if "Error" in output:
raise subprocess.CalledProcessError(process.returncode, process.args, error) logging.error(output)
except FileNotFoundError: return
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.")
return
except subprocess.CalledProcessError as e:
logging.error("Error: %s", e.stderr)
return
# Parse the output and replace '[local]' with a space # Parse the output and replace '[local]' with a space
versions = output.splitlines() versions = output.splitlines()
versions = [version.replace('[local]', ' ').strip() for version in versions] versions = [version.replace('[local]', ' ').strip() for version in versions]
self.version_combo.addItems(versions) self.version_combo.addItems(versions)
except Exception as e:
logging.error("Unexpected error: %s", e)
return
# Update the download button state whenever versions are updated # Update the download button state whenever versions are updated
self.update_download_button_state() self.update_download_button_state()
@ -1693,7 +1662,7 @@ class ModLoaderAndVersionMenu(QDialog):
# Connect the combo box signal to the update function # Connect the combo box signal to the update function
self.version_combo.currentIndexChanged.connect(self.update_download_button_state) self.version_combo.currentIndexChanged.connect(self.update_download_button_state)
def update_download_button_state(self): def update_download_button_state(self):
self.download_button.setEnabled(self.version_combo.currentIndex() != -1) self.download_button.setEnabled(self.version_combo.currentIndex() != -1)
@ -1733,15 +1702,10 @@ class ModLoaderAndVersionMenu(QDialog):
def populate_available_releases(self, version_combo, install_forge, install_fabric): def populate_available_releases(self, version_combo, install_forge, install_fabric):
try: try:
process = subprocess.Popen(['picomc', 'version', 'list', '--release'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) command = "version list --release"
output, error = process.communicate() output = modulecli.run_command(command)
if process.returncode != 0: except Exception as e:
raise subprocess.CalledProcessError(process.returncode, process.args, error) logging.error("Error: %s", str(e))
except FileNotFoundError:
logging.error("'picomc' command not found. Please make sure it's installed and in your PATH.")
return
except subprocess.CalledProcessError as e:
logging.error("Error: %s", e.stderr)
return return
if install_fabric: if install_fabric:
@ -1771,12 +1735,13 @@ class ModLoaderAndVersionMenu(QDialog):
try: try:
if mod_loader == 'forge': if mod_loader == 'forge':
subprocess.run(['picomc', 'mod', 'loader', 'forge', 'install', '--game', version], check=True) command = f"mod loader forge install --game {version}"
elif mod_loader == 'fabric': elif mod_loader == 'fabric':
subprocess.run(['picomc', 'mod', 'loader', 'fabric', 'install', version], check=True) command = f"mod loader fabric install {version}"
modulecli.run_command(command)
QMessageBox.information(self, "Success", f"{mod_loader.capitalize()} installed successfully for version {version}!") QMessageBox.information(self, "Success", f"{mod_loader.capitalize()} installed successfully for version {version}!")
except subprocess.CalledProcessError as e: except Exception as e:
error_message = f"Error installing {mod_loader} for version {version}: {e.stderr.decode()}" error_message = f"Error installing {mod_loader} for version {version}: {str(e)}"
QMessageBox.critical(self, "Error", error_message) QMessageBox.critical(self, "Error", error_message)
logging.error(error_message) logging.error(error_message)