mirror of
https://github.com/nixietab/picodulce.git
synced 2025-04-10 10:28:56 +01:00
Update picodulce.py
This commit is contained in:
parent
6515a6dcc7
commit
0ea436f868
499
picodulce.py
499
picodulce.py
@ -10,35 +10,48 @@ import requests
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from updateManager import UpdateChecker
|
||||||
from authser import MinecraftAuthenticator
|
from authser import MinecraftAuthenticator
|
||||||
|
from healtcheck import HealthCheck
|
||||||
|
|
||||||
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, QTranslator, QLocale
|
||||||
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='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
|
||||||
class PicomcVersionSelector(QWidget):
|
class PicomcVersionSelector(QWidget):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
super().__init__() # Initialize the parent class properly
|
||||||
self.current_state = "menu"
|
self.current_state = "menu"
|
||||||
self.open_dialogs = []
|
self.open_dialogs = []
|
||||||
self.check_config_file()
|
|
||||||
self.themes_integrity()
|
|
||||||
themes_folder = "themes"
|
|
||||||
|
|
||||||
|
# Load translations before initializing UI
|
||||||
|
self.translators = []
|
||||||
|
self.load_locale("./locales")
|
||||||
|
|
||||||
|
self.update_checker = UpdateChecker(self)
|
||||||
|
|
||||||
|
# Set up and use the health_check module
|
||||||
|
health_checker = HealthCheck()
|
||||||
|
health_checker.themes_integrity()
|
||||||
|
health_checker.check_config_file()
|
||||||
|
self.config = health_checker.config
|
||||||
|
|
||||||
|
themes_folder = "themes"
|
||||||
theme_file = self.config.get("Theme", "Dark.json")
|
theme_file = self.config.get("Theme", "Dark.json")
|
||||||
|
|
||||||
# Ensure the theme file exists in the themes directory
|
|
||||||
theme_file_path = os.path.join(themes_folder, theme_file)
|
theme_file_path = os.path.join(themes_folder, theme_file)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Load and apply the theme from the file
|
|
||||||
self.load_theme_from_file(theme_file_path, app)
|
self.load_theme_from_file(theme_file_path, app)
|
||||||
print(f"Theme '{theme_file}' loaded successfully.")
|
print(f"Theme '{theme_file}' loaded successfully.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error: Could not load theme '{theme_file}'. Falling back to default theme. {e}")
|
print(f"Error: Could not load theme '{theme_file}'. Falling back to default theme. {e}")
|
||||||
|
|
||||||
super().__init__()
|
|
||||||
self.init_ui()
|
self.init_ui()
|
||||||
|
|
||||||
if self.config.get("CheckUpdate", False):
|
if self.config.get("CheckUpdate", False):
|
||||||
@ -46,7 +59,7 @@ class PicomcVersionSelector(QWidget):
|
|||||||
|
|
||||||
if self.config.get("IsRCPenabled", False):
|
if self.config.get("IsRCPenabled", False):
|
||||||
discord_rcp_thread = Thread(target=self.start_discord_rcp)
|
discord_rcp_thread = Thread(target=self.start_discord_rcp)
|
||||||
discord_rcp_thread.daemon = True # Make the thread a daemon so it terminates when the main program exits
|
discord_rcp_thread.daemon = True
|
||||||
discord_rcp_thread.start()
|
discord_rcp_thread.start()
|
||||||
|
|
||||||
if self.config.get("IsFirstLaunch", False):
|
if self.config.get("IsFirstLaunch", False):
|
||||||
@ -55,6 +68,46 @@ class PicomcVersionSelector(QWidget):
|
|||||||
self.authenticator = MinecraftAuthenticator(self)
|
self.authenticator = MinecraftAuthenticator(self)
|
||||||
self.authenticator.auth_finished.connect(self._on_auth_finished)
|
self.authenticator.auth_finished.connect(self._on_auth_finished)
|
||||||
|
|
||||||
|
def load_locale(self, locale_dir_path):
|
||||||
|
self.config_path = "config.json"
|
||||||
|
if not os.path.exists(locale_dir_path):
|
||||||
|
print(f"Warning: Locale directory {locale_dir_path} does not exist")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Try to load and read config.json
|
||||||
|
try:
|
||||||
|
with open(self.config_path, 'r', encoding='utf-8') as config_file:
|
||||||
|
config = json.load(config_file)
|
||||||
|
locale_code = config.get("Locale", "")
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"Warning: Config file {self.config_path} not found")
|
||||||
|
return
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
print(f"Error: Invalid JSON in {self.config_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not locale_code:
|
||||||
|
print("Warning: No locale specified in config.json")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Look for matching locale file
|
||||||
|
locale_pattern = f"*_{locale_code}.qm" # Pattern like *_es.qm for Spanish
|
||||||
|
found_matching_locale = False
|
||||||
|
|
||||||
|
for filename in os.listdir(locale_dir_path):
|
||||||
|
if filename.endswith(".qm") and f"_{locale_code}" in filename:
|
||||||
|
locale_file_path = os.path.join(locale_dir_path, filename)
|
||||||
|
translator = QTranslator()
|
||||||
|
if translator.load(locale_file_path):
|
||||||
|
QApplication.instance().installTranslator(translator)
|
||||||
|
self.translators.append(translator)
|
||||||
|
print(f"Loaded locale: {locale_file_path}")
|
||||||
|
found_matching_locale = True
|
||||||
|
else:
|
||||||
|
print(f"Failed to load locale: {locale_file_path}")
|
||||||
|
|
||||||
|
if not found_matching_locale:
|
||||||
|
print(f"Warning: No matching locale file found for language code: {locale_code}")
|
||||||
|
|
||||||
def load_theme_from_file(self, file_path, app):
|
def load_theme_from_file(self, file_path, app):
|
||||||
self.theme = {}
|
self.theme = {}
|
||||||
@ -115,73 +168,6 @@ class PicomcVersionSelector(QWidget):
|
|||||||
else:
|
else:
|
||||||
print("Theme dosn't seem to have a stylesheet")
|
print("Theme dosn't seem to have a stylesheet")
|
||||||
|
|
||||||
def themes_integrity(self):
|
|
||||||
# Define folder and file paths
|
|
||||||
themes_folder = "themes"
|
|
||||||
dark_theme_file = os.path.join(themes_folder, "Dark.json")
|
|
||||||
native_theme_file = os.path.join(themes_folder, "Native.json")
|
|
||||||
|
|
||||||
# Define the default content for Dark.json
|
|
||||||
dark_theme_content = {
|
|
||||||
"manifest": {
|
|
||||||
"name": "Dark",
|
|
||||||
"description": "The default picodulce launcher theme",
|
|
||||||
"author": "Nixietab",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"palette": {
|
|
||||||
"Window": "#353535",
|
|
||||||
"WindowText": "#ffffff",
|
|
||||||
"Base": "#191919",
|
|
||||||
"AlternateBase": "#353535",
|
|
||||||
"ToolTipBase": "#ffffff",
|
|
||||||
"ToolTipText": "#ffffff",
|
|
||||||
"Text": "#ffffff",
|
|
||||||
"Button": "#353535",
|
|
||||||
"ButtonText": "#ffffff",
|
|
||||||
"BrightText": "#ff0000",
|
|
||||||
"Link": "#2a82da",
|
|
||||||
"Highlight": "#4bb679",
|
|
||||||
"HighlightedText": "#ffffff"
|
|
||||||
},
|
|
||||||
"background_image_base64": ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# Define the default content for Native.json
|
|
||||||
native_theme_content = {
|
|
||||||
"manifest": {
|
|
||||||
"name": "Native",
|
|
||||||
"description": "The native looks of your OS",
|
|
||||||
"author": "Your Qt Style",
|
|
||||||
"license": "Any"
|
|
||||||
},
|
|
||||||
"palette": {}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Step 1: Ensure the themes folder exists
|
|
||||||
if not os.path.exists(themes_folder):
|
|
||||||
print(f"Creating folder: {themes_folder}")
|
|
||||||
os.makedirs(themes_folder)
|
|
||||||
|
|
||||||
# Step 2: Ensure Dark.json exists
|
|
||||||
if not os.path.isfile(dark_theme_file):
|
|
||||||
print(f"Creating file: {dark_theme_file}")
|
|
||||||
with open(dark_theme_file, "w", encoding="utf-8") as file:
|
|
||||||
json.dump(dark_theme_content, file, indent=2)
|
|
||||||
print("Dark.json has been created successfully.")
|
|
||||||
|
|
||||||
# Step 3: Ensure Native.json exists
|
|
||||||
if not os.path.isfile(native_theme_file):
|
|
||||||
print(f"Creating file: {native_theme_file}")
|
|
||||||
with open(native_theme_file, "w", encoding="utf-8") as file:
|
|
||||||
json.dump(native_theme_content, file, indent=2)
|
|
||||||
print("Native.json has been created successfully.")
|
|
||||||
|
|
||||||
# Check if both files exist and print OK message
|
|
||||||
if os.path.isfile(dark_theme_file) and os.path.isfile(native_theme_file):
|
|
||||||
print("Theme Integrity OK")
|
|
||||||
|
|
||||||
|
|
||||||
def FirstLaunch(self):
|
def FirstLaunch(self):
|
||||||
try:
|
try:
|
||||||
self.config_path = "config.json"
|
self.config_path = "config.json"
|
||||||
@ -277,7 +263,7 @@ class PicomcVersionSelector(QWidget):
|
|||||||
title_label.setFont(QFont("Arial", 24, QFont.Bold))
|
title_label.setFont(QFont("Arial", 24, QFont.Bold))
|
||||||
|
|
||||||
# Create installed versions section
|
# Create installed versions section
|
||||||
installed_versions_label = QLabel('Installed Versions:')
|
installed_versions_label = QLabel(self.tr('Installed Versions:'))
|
||||||
installed_versions_label.setFont(QFont("Arial", 14))
|
installed_versions_label.setFont(QFont("Arial", 14))
|
||||||
self.installed_version_combo = QComboBox()
|
self.installed_version_combo = QComboBox()
|
||||||
self.installed_version_combo.setMinimumWidth(200)
|
self.installed_version_combo.setMinimumWidth(200)
|
||||||
@ -287,32 +273,32 @@ class PicomcVersionSelector(QWidget):
|
|||||||
buttons_layout = QVBoxLayout()
|
buttons_layout = QVBoxLayout()
|
||||||
|
|
||||||
# Create play button for installed versions
|
# Create play button for installed versions
|
||||||
self.play_button = QPushButton('Play')
|
self.play_button = QPushButton(self.tr('Play'))
|
||||||
self.play_button.clicked.connect(self.play_instance)
|
self.play_button.clicked.connect(self.play_instance)
|
||||||
highlight_color = self.palette().color(QPalette.Highlight)
|
highlight_color = self.palette().color(QPalette.Highlight)
|
||||||
self.play_button.setStyleSheet(f"background-color: {highlight_color.name()}; color: white;")
|
self.play_button.setStyleSheet(f"background-color: {highlight_color.name()}; color: white;")
|
||||||
buttons_layout.addWidget(self.play_button)
|
buttons_layout.addWidget(self.play_button)
|
||||||
|
|
||||||
# Version Manager Button
|
# Version Manager Button
|
||||||
self.open_menu_button = QPushButton('Version Manager')
|
self.open_menu_button = QPushButton(self.tr('Version Manager'))
|
||||||
self.open_menu_button.clicked.connect(self.open_mod_loader_and_version_menu)
|
self.open_menu_button.clicked.connect(self.open_mod_loader_and_version_menu)
|
||||||
buttons_layout.addWidget(self.open_menu_button)
|
buttons_layout.addWidget(self.open_menu_button)
|
||||||
|
|
||||||
# Create button to manage accounts
|
# Create button to manage accounts
|
||||||
self.manage_accounts_button = QPushButton('Manage Accounts')
|
self.manage_accounts_button = QPushButton(self.tr('Manage Accounts'))
|
||||||
self.manage_accounts_button.clicked.connect(self.manage_accounts)
|
self.manage_accounts_button.clicked.connect(self.manage_accounts)
|
||||||
buttons_layout.addWidget(self.manage_accounts_button)
|
buttons_layout.addWidget(self.manage_accounts_button)
|
||||||
|
|
||||||
# Create a button for the marroc mod loader
|
# Create a button for the marroc mod loader
|
||||||
self.open_marroc_button = QPushButton('Marroc Mod Manager')
|
self.open_marroc_button = QPushButton(self.tr('Marroc Mod Manager'))
|
||||||
self.open_marroc_button.clicked.connect(self.open_marroc_script)
|
self.open_marroc_button.clicked.connect(self.open_marroc_script)
|
||||||
buttons_layout.addWidget(self.open_marroc_button)
|
buttons_layout.addWidget(self.open_marroc_button)
|
||||||
|
|
||||||
# Create grid layout for Settings and About buttons
|
# Create grid layout for Settings and About buttons
|
||||||
grid_layout = QGridLayout()
|
grid_layout = QGridLayout()
|
||||||
self.settings_button = QPushButton('Settings')
|
self.settings_button = QPushButton(self.tr('Settings'))
|
||||||
self.settings_button.clicked.connect(self.open_settings_dialog)
|
self.settings_button.clicked.connect(self.open_settings_dialog)
|
||||||
self.about_button = QPushButton('About')
|
self.about_button = QPushButton(self.tr('About'))
|
||||||
self.about_button.clicked.connect(self.show_about_dialog)
|
self.about_button.clicked.connect(self.show_about_dialog)
|
||||||
|
|
||||||
grid_layout.addWidget(self.settings_button, 0, 0)
|
grid_layout.addWidget(self.settings_button, 0, 0)
|
||||||
@ -350,53 +336,9 @@ class PicomcVersionSelector(QWidget):
|
|||||||
else:
|
else:
|
||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
def check_config_file(self):
|
|
||||||
config_path = "config.json"
|
|
||||||
default_config = {
|
|
||||||
"IsRCPenabled": False,
|
|
||||||
"CheckUpdate": False,
|
|
||||||
"IsBleeding": False,
|
|
||||||
"LastPlayed": "",
|
|
||||||
"IsFirstLaunch": True,
|
|
||||||
"Instance": "default",
|
|
||||||
"Theme": "Dark.json",
|
|
||||||
"ThemeBackground": True,
|
|
||||||
"ThemeRepository": "https://raw.githubusercontent.com/nixietab/picodulce-themes/main/repo.json"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Step 1: Check if the file exists; if not, create it with default values
|
|
||||||
if not os.path.exists(config_path):
|
|
||||||
with open(config_path, "w") as config_file:
|
|
||||||
json.dump(default_config, config_file, indent=4)
|
|
||||||
self.config = default_config
|
|
||||||
return
|
|
||||||
|
|
||||||
# Step 2: Try loading the config file, handle invalid JSON
|
|
||||||
try:
|
|
||||||
with open(config_path, "r") as config_file:
|
|
||||||
self.config = json.load(config_file)
|
|
||||||
except (json.JSONDecodeError, ValueError):
|
|
||||||
# File is corrupted, overwrite it with default configuration
|
|
||||||
with open(config_path, "w") as config_file:
|
|
||||||
json.dump(default_config, config_file, indent=4)
|
|
||||||
self.config = default_config
|
|
||||||
return
|
|
||||||
|
|
||||||
# Step 3: Check for missing keys and add defaults if necessary
|
|
||||||
updated = False
|
|
||||||
for key, value in default_config.items():
|
|
||||||
if key not in self.config: # Field is missing
|
|
||||||
self.config[key] = value
|
|
||||||
updated = True
|
|
||||||
|
|
||||||
# Step 4: Save the repaired config back to the file
|
|
||||||
if updated:
|
|
||||||
with open(config_path, "w") as config_file:
|
|
||||||
json.dump(self.config, config_file, indent=4)
|
|
||||||
|
|
||||||
def open_settings_dialog(self):
|
def open_settings_dialog(self):
|
||||||
dialog = QDialog(self)
|
dialog = QDialog(self)
|
||||||
dialog.setWindowTitle('Settings')
|
dialog.setWindowTitle(self.tr('Settings'))
|
||||||
|
|
||||||
# Make the window resizable
|
# Make the window resizable
|
||||||
dialog.setMinimumSize(400, 300)
|
dialog.setMinimumSize(400, 300)
|
||||||
@ -408,17 +350,17 @@ class PicomcVersionSelector(QWidget):
|
|||||||
settings_tab = QWidget()
|
settings_tab = QWidget()
|
||||||
settings_layout = QVBoxLayout()
|
settings_layout = QVBoxLayout()
|
||||||
|
|
||||||
title_label = QLabel('Settings')
|
title_label = QLabel(self.tr('Settings'))
|
||||||
title_label.setFont(QFont("Arial", 14))
|
title_label.setFont(QFont("Arial", 14))
|
||||||
|
|
||||||
# Create checkboxes for settings tab
|
# Create checkboxes for settings tab
|
||||||
discord_rcp_checkbox = QCheckBox('Discord Rich Presence')
|
discord_rcp_checkbox = QCheckBox(self.tr('Discord Rich Presence'))
|
||||||
discord_rcp_checkbox.setChecked(self.config.get("IsRCPenabled", False))
|
discord_rcp_checkbox.setChecked(self.config.get("IsRCPenabled", False))
|
||||||
|
|
||||||
check_updates_checkbox = QCheckBox('Check Updates on Start')
|
check_updates_checkbox = QCheckBox(self.tr('Check Updates on Start'))
|
||||||
check_updates_checkbox.setChecked(self.config.get("CheckUpdate", False))
|
check_updates_checkbox.setChecked(self.config.get("CheckUpdate", False))
|
||||||
|
|
||||||
bleeding_edge_checkbox = QCheckBox('Bleeding Edge')
|
bleeding_edge_checkbox = QCheckBox(self.tr('Bleeding Edge'))
|
||||||
bleeding_edge_checkbox.setChecked(self.config.get("IsBleeding", False))
|
bleeding_edge_checkbox.setChecked(self.config.get("IsBleeding", False))
|
||||||
bleeding_edge_checkbox.stateChanged.connect(lambda: self.show_bleeding_edge_popup(bleeding_edge_checkbox))
|
bleeding_edge_checkbox.stateChanged.connect(lambda: self.show_bleeding_edge_popup(bleeding_edge_checkbox))
|
||||||
|
|
||||||
@ -428,13 +370,13 @@ class PicomcVersionSelector(QWidget):
|
|||||||
settings_layout.addWidget(bleeding_edge_checkbox)
|
settings_layout.addWidget(bleeding_edge_checkbox)
|
||||||
|
|
||||||
# Add buttons in the settings tab
|
# Add buttons in the settings tab
|
||||||
update_button = QPushButton('Check for updates')
|
update_button = QPushButton(self.tr('Check for updates'))
|
||||||
update_button.clicked.connect(self.check_for_update)
|
update_button.clicked.connect(self.check_for_update)
|
||||||
|
|
||||||
open_game_directory_button = QPushButton('Open game directory')
|
open_game_directory_button = QPushButton(self.tr('Open game directory'))
|
||||||
open_game_directory_button.clicked.connect(self.open_game_directory)
|
open_game_directory_button.clicked.connect(self.open_game_directory)
|
||||||
|
|
||||||
stats_button = QPushButton('Stats for Nerds')
|
stats_button = QPushButton(self.tr('Stats for Nerds'))
|
||||||
stats_button.clicked.connect(self.show_system_info)
|
stats_button.clicked.connect(self.show_system_info)
|
||||||
|
|
||||||
settings_layout.addWidget(update_button)
|
settings_layout.addWidget(update_button)
|
||||||
@ -448,15 +390,15 @@ class PicomcVersionSelector(QWidget):
|
|||||||
customization_layout = QVBoxLayout()
|
customization_layout = QVBoxLayout()
|
||||||
|
|
||||||
# Create theme background checkbox for customization tab
|
# Create theme background checkbox for customization tab
|
||||||
theme_background_checkbox = QCheckBox('Theme Background')
|
theme_background_checkbox = QCheckBox(self.tr('Theme Background'))
|
||||||
theme_background_checkbox.setChecked(self.config.get("ThemeBackground", False))
|
theme_background_checkbox.setChecked(self.config.get("ThemeBackground", False))
|
||||||
|
|
||||||
# Label to show currently selected theme
|
# Label to show currently selected theme
|
||||||
theme_filename = self.config.get('Theme', 'Dark.json')
|
theme_filename = self.config.get('Theme', 'Dark.json')
|
||||||
current_theme_label = QLabel(f"Current Theme: {theme_filename}")
|
current_theme_label = QLabel(self.tr(f"Current Theme: {theme_filename}"))
|
||||||
|
|
||||||
# QListWidget to display available themes
|
# QListWidget to display available themes
|
||||||
json_files_label = QLabel('Installed Themes:')
|
json_files_label = QLabel(self.tr('Installed Themes:'))
|
||||||
self.json_files_list_widget = QListWidget()
|
self.json_files_list_widget = QListWidget()
|
||||||
|
|
||||||
# Track selected theme
|
# Track selected theme
|
||||||
@ -480,7 +422,7 @@ class PicomcVersionSelector(QWidget):
|
|||||||
customization_layout.addWidget(self.json_files_list_widget)
|
customization_layout.addWidget(self.json_files_list_widget)
|
||||||
|
|
||||||
# Button to download themes
|
# Button to download themes
|
||||||
download_themes_button = QPushButton("Download More Themes")
|
download_themes_button = QPushButton(self.tr("Download More Themes"))
|
||||||
download_themes_button.clicked.connect(self.download_themes_window)
|
download_themes_button.clicked.connect(self.download_themes_window)
|
||||||
|
|
||||||
customization_layout.addWidget(download_themes_button)
|
customization_layout.addWidget(download_themes_button)
|
||||||
@ -488,11 +430,11 @@ class PicomcVersionSelector(QWidget):
|
|||||||
customization_tab.setLayout(customization_layout)
|
customization_tab.setLayout(customization_layout)
|
||||||
|
|
||||||
# Add the tabs to the TabWidget
|
# Add the tabs to the TabWidget
|
||||||
tab_widget.addTab(settings_tab, "Settings")
|
tab_widget.addTab(settings_tab, self.tr("Settings"))
|
||||||
tab_widget.addTab(customization_tab, "Customization")
|
tab_widget.addTab(customization_tab, self.tr("Customization"))
|
||||||
|
|
||||||
# Save button
|
# Save button
|
||||||
save_button = QPushButton('Save')
|
save_button = QPushButton(self.tr('Save'))
|
||||||
save_button.clicked.connect(
|
save_button.clicked.connect(
|
||||||
lambda: self.save_settings(
|
lambda: self.save_settings(
|
||||||
discord_rcp_checkbox.isChecked(),
|
discord_rcp_checkbox.isChecked(),
|
||||||
@ -571,13 +513,13 @@ class PicomcVersionSelector(QWidget):
|
|||||||
selected_item = json_files_list_widget.currentItem()
|
selected_item = json_files_list_widget.currentItem()
|
||||||
if selected_item:
|
if selected_item:
|
||||||
self.selected_theme = selected_item.data(Qt.UserRole)
|
self.selected_theme = selected_item.data(Qt.UserRole)
|
||||||
current_theme_label.setText(f"Current Theme: {self.selected_theme}")
|
current_theme_label.setText(self.tr(f"Current Theme: {self.selected_theme}"))
|
||||||
|
|
||||||
## REPOSITORY BLOCK BEGGINS
|
## REPOSITORY BLOCK BEGGINS
|
||||||
|
|
||||||
def download_themes_window(self):
|
def download_themes_window(self):
|
||||||
dialog = QDialog(self)
|
dialog = QDialog(self)
|
||||||
dialog.setWindowTitle("Themes Repository")
|
dialog.setWindowTitle(self.tr("Themes Repository"))
|
||||||
dialog.setGeometry(100, 100, 800, 600)
|
dialog.setGeometry(100, 100, 800, 600)
|
||||||
|
|
||||||
main_layout = QHBoxLayout(dialog)
|
main_layout = QHBoxLayout(dialog)
|
||||||
@ -599,7 +541,7 @@ class PicomcVersionSelector(QWidget):
|
|||||||
self.image_label.setStyleSheet("padding: 10px;")
|
self.image_label.setStyleSheet("padding: 10px;")
|
||||||
right_layout.addWidget(self.image_label)
|
right_layout.addWidget(self.image_label)
|
||||||
|
|
||||||
download_button = QPushButton("Download Theme", dialog)
|
download_button = QPushButton(self.tr("Download Theme"), dialog)
|
||||||
download_button.clicked.connect(self.theme_download)
|
download_button.clicked.connect(self.theme_download)
|
||||||
right_layout.addWidget(download_button)
|
right_layout.addWidget(download_button)
|
||||||
|
|
||||||
@ -612,7 +554,6 @@ class PicomcVersionSelector(QWidget):
|
|||||||
|
|
||||||
dialog.finished.connect(lambda: self.update_themes_list())
|
dialog.finished.connect(lambda: self.update_themes_list())
|
||||||
|
|
||||||
|
|
||||||
self.load_themes()
|
self.load_themes()
|
||||||
dialog.exec_()
|
dialog.exec_()
|
||||||
|
|
||||||
@ -626,18 +567,18 @@ class PicomcVersionSelector(QWidget):
|
|||||||
config = json.load(config_file)
|
config = json.load(config_file)
|
||||||
url = config.get("ThemeRepository")
|
url = config.get("ThemeRepository")
|
||||||
if not url:
|
if not url:
|
||||||
raise ValueError("ThemeRepository is not defined in config.json")
|
raise ValueError(self.tr("ThemeRepository is not defined in config.json"))
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
return response.json()
|
return response.json()
|
||||||
except (FileNotFoundError, json.JSONDecodeError) as config_error:
|
except (FileNotFoundError, json.JSONDecodeError) as config_error:
|
||||||
self.show_error_popup("Error reading configuration", f"An error occurred while reading config.json: {config_error}")
|
self.show_error_popup(self.tr("Error reading configuration"), self.tr(f"An error occurred while reading config.json: {config_error}"))
|
||||||
return {}
|
return {}
|
||||||
except requests.exceptions.RequestException as fetch_error:
|
except requests.exceptions.RequestException as fetch_error:
|
||||||
self.show_error_popup("Error fetching themes", f"An error occurred while fetching themes: {fetch_error}")
|
self.show_error_popup(self.tr("Error fetching themes"), self.tr(f"An error occurred while fetching themes: {fetch_error}"))
|
||||||
return {}
|
return {}
|
||||||
except ValueError as value_error:
|
except ValueError as value_error:
|
||||||
self.show_error_popup("Configuration Error", str(value_error))
|
self.show_error_popup(self.tr("Configuration Error"), self.tr(str(value_error)))
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def download_theme_json(self, theme_url, theme_name):
|
def download_theme_json(self, theme_url, theme_name):
|
||||||
@ -649,15 +590,15 @@ class PicomcVersionSelector(QWidget):
|
|||||||
theme_filename = os.path.join('themes', f'{theme_name}.json')
|
theme_filename = os.path.join('themes', f'{theme_name}.json')
|
||||||
with open(theme_filename, 'wb') as f:
|
with open(theme_filename, 'wb') as f:
|
||||||
f.write(response.content)
|
f.write(response.content)
|
||||||
print(f"Downloaded {theme_name} theme to {theme_filename}")
|
print(self.tr(f"Downloaded {theme_name} theme to {theme_filename}"))
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
self.show_error_popup("Error downloading theme", f"An error occurred while downloading {theme_name}: {e}")
|
self.show_error_popup(self.tr("Error downloading theme"), self.tr(f"An error occurred while downloading {theme_name}: {e}"))
|
||||||
|
|
||||||
def show_error_popup(self, title, message):
|
def show_error_popup(self, title, message):
|
||||||
msg = QMessageBox()
|
msg = QMessageBox()
|
||||||
msg.setIcon(QMessageBox.Critical)
|
msg.setIcon(QMessageBox.Critical)
|
||||||
msg.setWindowTitle(title)
|
msg.setWindowTitle(self.tr(title))
|
||||||
msg.setText(message)
|
msg.setText(self.tr(message))
|
||||||
msg.exec_()
|
msg.exec_()
|
||||||
|
|
||||||
def is_theme_installed(self, theme_name):
|
def is_theme_installed(self, theme_name):
|
||||||
@ -671,7 +612,7 @@ class PicomcVersionSelector(QWidget):
|
|||||||
for theme in themes:
|
for theme in themes:
|
||||||
theme_display_name = f"{theme['name']} by {theme['author']}"
|
theme_display_name = f"{theme['name']} by {theme['author']}"
|
||||||
if self.is_theme_installed(theme['name']):
|
if self.is_theme_installed(theme['name']):
|
||||||
theme_display_name += " [I]"
|
theme_display_name += self.tr(" [I]")
|
||||||
installed_themes.append(theme_display_name)
|
installed_themes.append(theme_display_name)
|
||||||
else:
|
else:
|
||||||
uninstalled_themes.append(theme_display_name)
|
uninstalled_themes.append(theme_display_name)
|
||||||
@ -691,11 +632,11 @@ class PicomcVersionSelector(QWidget):
|
|||||||
theme = self.find_theme_by_name(theme_name)
|
theme = self.find_theme_by_name(theme_name)
|
||||||
if theme:
|
if theme:
|
||||||
self.details_label.setText(
|
self.details_label.setText(
|
||||||
f"<b>Name:</b> {theme['name']}<br>"
|
self.tr(f"<b>Name:</b> {theme['name']}<br>"
|
||||||
f"<b>Description:</b> {theme['description']}<br>"
|
f"<b>Description:</b> {theme['description']}<br>"
|
||||||
f"<b>Author:</b> {theme['author']}<br>"
|
f"<b>Author:</b> {theme['author']}<br>"
|
||||||
f"<b>License:</b> {theme['license']}<br>"
|
f"<b>License:</b> {theme['license']}<br>"
|
||||||
f"<b>Link:</b> <a href='{theme['link']}'>{theme['link']}</a><br>"
|
f"<b>Link:</b> <a href='{theme['link']}'>{theme['link']}</a><br>")
|
||||||
)
|
)
|
||||||
self.details_label.setTextFormat(Qt.RichText)
|
self.details_label.setTextFormat(Qt.RichText)
|
||||||
self.details_label.setOpenExternalLinks(True)
|
self.details_label.setOpenExternalLinks(True)
|
||||||
@ -715,7 +656,7 @@ class PicomcVersionSelector(QWidget):
|
|||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
return response.content
|
return response.content
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
self.show_error_popup("Error fetching image", f"An error occurred while fetching the image: {e}")
|
self.show_error_popup(self.tr("Error fetching image"), self.tr(f"An error occurred while fetching the image: {e}"))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def find_theme_by_name(self, theme_name):
|
def find_theme_by_name(self, theme_name):
|
||||||
@ -735,7 +676,7 @@ class PicomcVersionSelector(QWidget):
|
|||||||
theme_url = theme["link"]
|
theme_url = theme["link"]
|
||||||
self.download_theme_json(theme_url, theme_name)
|
self.download_theme_json(theme_url, theme_name)
|
||||||
self.load_themes()
|
self.load_themes()
|
||||||
|
|
||||||
## REPOSITORY BLOCK ENDS
|
## REPOSITORY BLOCK ENDS
|
||||||
|
|
||||||
|
|
||||||
@ -763,20 +704,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")
|
||||||
@ -988,11 +915,11 @@ class PicomcVersionSelector(QWidget):
|
|||||||
# Main account management dialog
|
# Main account management dialog
|
||||||
dialog = QDialog(self)
|
dialog = QDialog(self)
|
||||||
self.open_dialogs.append(dialog)
|
self.open_dialogs.append(dialog)
|
||||||
dialog.setWindowTitle('Manage Accounts')
|
dialog.setWindowTitle(self.tr('Manage Accounts'))
|
||||||
dialog.setFixedSize(400, 250)
|
dialog.setFixedSize(400, 250)
|
||||||
|
|
||||||
# Title
|
# Title
|
||||||
title_label = QLabel('Manage Accounts')
|
title_label = QLabel(self.tr('Manage Accounts'))
|
||||||
title_label.setFont(QFont("Arial", 14))
|
title_label.setFont(QFont("Arial", 14))
|
||||||
title_label.setAlignment(Qt.AlignCenter) # Center the text
|
title_label.setAlignment(Qt.AlignCenter) # Center the text
|
||||||
# Dropdown for selecting accounts
|
# Dropdown for selecting accounts
|
||||||
@ -1000,17 +927,17 @@ class PicomcVersionSelector(QWidget):
|
|||||||
self.populate_accounts(account_combo)
|
self.populate_accounts(account_combo)
|
||||||
|
|
||||||
# Buttons
|
# Buttons
|
||||||
create_account_button = QPushButton('Create Account')
|
create_account_button = QPushButton(self.tr('Create Account'))
|
||||||
create_account_button.clicked.connect(self.open_create_account_dialog)
|
create_account_button.clicked.connect(self.open_create_account_dialog)
|
||||||
|
|
||||||
authenticate_button = QPushButton('Authenticate Account')
|
authenticate_button = QPushButton(self.tr('Authenticate Account'))
|
||||||
authenticate_button.clicked.connect(lambda: self.authenticate_account(dialog, account_combo.currentText()))
|
authenticate_button.clicked.connect(lambda: self.authenticate_account(dialog, account_combo.currentText()))
|
||||||
|
|
||||||
remove_account_button = QPushButton('Remove Account')
|
remove_account_button = QPushButton(self.tr('Remove Account'))
|
||||||
remove_account_button.clicked.connect(lambda: self.remove_account(dialog, account_combo.currentText()))
|
remove_account_button.clicked.connect(lambda: self.remove_account(dialog, account_combo.currentText()))
|
||||||
|
|
||||||
# New button to set the account idk
|
# New button to set the account idk
|
||||||
set_default_button = QPushButton('Select')
|
set_default_button = QPushButton(self.tr('Select'))
|
||||||
set_default_button.setFixedWidth(100) # Set button width to a quarter
|
set_default_button.setFixedWidth(100) # Set button width to a quarter
|
||||||
set_default_button.clicked.connect(lambda: self.set_default_account(account_combo.currentText(), dialog))
|
set_default_button.clicked.connect(lambda: self.set_default_account(account_combo.currentText(), dialog))
|
||||||
|
|
||||||
@ -1038,15 +965,15 @@ class PicomcVersionSelector(QWidget):
|
|||||||
# Dialog for creating a new account
|
# Dialog for creating a new account
|
||||||
dialog = QDialog(self)
|
dialog = QDialog(self)
|
||||||
self.open_dialogs.append(dialog)
|
self.open_dialogs.append(dialog)
|
||||||
dialog.setWindowTitle('Create Account')
|
dialog.setWindowTitle(self.tr('Create Account'))
|
||||||
dialog.setFixedSize(300, 150)
|
dialog.setFixedSize(300, 150)
|
||||||
|
|
||||||
username_input = QLineEdit()
|
username_input = QLineEdit()
|
||||||
username_input.setPlaceholderText('Enter Username')
|
username_input.setPlaceholderText(self.tr('Enter Username'))
|
||||||
|
|
||||||
microsoft_checkbox = QCheckBox('Microsoft Account')
|
microsoft_checkbox = QCheckBox(self.tr('Microsoft Account'))
|
||||||
|
|
||||||
create_button = QPushButton('Create')
|
create_button = QPushButton(self.tr('Create'))
|
||||||
create_button.clicked.connect(lambda: self.create_account(dialog, username_input.text(), microsoft_checkbox.isChecked()))
|
create_button.clicked.connect(lambda: self.create_account(dialog, username_input.text(), microsoft_checkbox.isChecked()))
|
||||||
|
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
@ -1063,11 +990,12 @@ class PicomcVersionSelector(QWidget):
|
|||||||
username = username.strip()
|
username = username.strip()
|
||||||
|
|
||||||
if not username:
|
if not username:
|
||||||
QMessageBox.warning(dialog, "Warning", "Username cannot be blank.")
|
QMessageBox.warning(dialog, self.tr("Warning"), self.tr("Username cannot be blank."))
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.is_valid_username(username):
|
if not self.is_valid_username(username):
|
||||||
QMessageBox.warning(dialog, "Warning", "Invalid username. Usernames must be 3-16 characters long and can only contain letters, numbers, and underscores.")
|
QMessageBox.warning(dialog, self.tr("Warning"),
|
||||||
|
self.tr("Invalid username. Usernames must be 3-16 characters long and can only contain letters, numbers, and underscores."))
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1076,13 +1004,14 @@ class PicomcVersionSelector(QWidget):
|
|||||||
command.append('--ms')
|
command.append('--ms')
|
||||||
|
|
||||||
subprocess.run(command, check=True)
|
subprocess.run(command, check=True)
|
||||||
QMessageBox.information(dialog, "Success", f"Account '{username}' created successfully!")
|
QMessageBox.information(dialog, self.tr("Success"),
|
||||||
|
self.tr("Account '{username}' created successfully!").format(username=username))
|
||||||
self.populate_accounts_for_all_dialogs()
|
self.populate_accounts_for_all_dialogs()
|
||||||
dialog.accept()
|
dialog.accept()
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
error_message = f"Error creating account: {e.stderr.decode()}"
|
error_message = self.tr("Error creating account: {error}").format(error=e.stderr.decode())
|
||||||
logging.error(error_message)
|
logging.error(error_message)
|
||||||
QMessageBox.critical(dialog, "Error", error_message)
|
QMessageBox.critical(dialog, self.tr("Error"), error_message)
|
||||||
|
|
||||||
def is_valid_username(self, username):
|
def is_valid_username(self, username):
|
||||||
# Validate the username according to Minecraft's rules
|
# Validate the username according to Minecraft's rules
|
||||||
@ -1094,7 +1023,8 @@ class PicomcVersionSelector(QWidget):
|
|||||||
# Clean up the account name
|
# Clean up the account name
|
||||||
account_name = account_name.strip().lstrip(" * ")
|
account_name = account_name.strip().lstrip(" * ")
|
||||||
if not account_name:
|
if not account_name:
|
||||||
QMessageBox.warning(dialog, "Warning", "Please select an account to authenticate.")
|
QMessageBox.warning(dialog, self.tr("Warning"),
|
||||||
|
self.tr("Please select an account to authenticate."))
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1107,15 +1037,18 @@ class PicomcVersionSelector(QWidget):
|
|||||||
self.authenticator.authenticate(account_name)
|
self.authenticator.authenticate(account_name)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = f"Error authenticating account '{account_name}': {str(e)}"
|
error_message = self.tr("Error authenticating account '{account}': {error}").format(
|
||||||
|
account=account_name, error=str(e))
|
||||||
logging.error(error_message)
|
logging.error(error_message)
|
||||||
QMessageBox.critical(dialog, "Error", error_message)
|
QMessageBox.critical(dialog, self.tr("Error"), error_message)
|
||||||
|
|
||||||
def _on_auth_finished(self, success):
|
def _on_auth_finished(self, success):
|
||||||
if success:
|
if success:
|
||||||
QMessageBox.information(self, "Success", "Account authenticated successfully!")
|
QMessageBox.information(self, self.tr("Success"),
|
||||||
|
self.tr("Account authenticated successfully!"))
|
||||||
else:
|
else:
|
||||||
QMessageBox.critical(self, "Error", "Failed to authenticate account")
|
QMessageBox.critical(self, self.tr("Error"),
|
||||||
|
self.tr("Failed to authenticate account"))
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
if self.authenticator:
|
if self.authenticator:
|
||||||
@ -1126,20 +1059,23 @@ class PicomcVersionSelector(QWidget):
|
|||||||
# Remove a selected account
|
# Remove a selected account
|
||||||
username = username.strip().lstrip(" * ")
|
username = username.strip().lstrip(" * ")
|
||||||
if not username:
|
if not username:
|
||||||
QMessageBox.warning(dialog, "Warning", "Please select an account to remove.")
|
QMessageBox.warning(dialog, self.tr("Warning"),
|
||||||
|
self.tr("Please select an account to remove."))
|
||||||
return
|
return
|
||||||
|
|
||||||
confirm_message = f"Are you sure you want to remove the account '{username}'?\nThis action cannot be undone."
|
confirm_message = self.tr("Are you sure you want to remove the account '{username}'?\nThis action cannot be undone.").format(username=username)
|
||||||
confirm_dialog = QMessageBox.question(dialog, "Confirm Removal", confirm_message, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
confirm_dialog = QMessageBox.question(dialog, self.tr("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)
|
subprocess.run(['picomc', 'account', 'remove', username], check=True)
|
||||||
QMessageBox.information(dialog, "Success", f"Account '{username}' removed successfully!")
|
QMessageBox.information(dialog, self.tr("Success"),
|
||||||
|
self.tr("Account '{username}' removed successfully!").format(username=username))
|
||||||
self.populate_accounts_for_all_dialogs()
|
self.populate_accounts_for_all_dialogs()
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
error_message = f"Error removing account: {e.stderr.decode()}"
|
error_message = self.tr("Error removing account: {error}").format(error=e.stderr.decode())
|
||||||
logging.error(error_message)
|
logging.error(error_message)
|
||||||
QMessageBox.critical(dialog, "Error", error_message)
|
QMessageBox.critical(dialog, self.tr("Error"), error_message)
|
||||||
|
|
||||||
|
|
||||||
def populate_accounts(self, account_combo):
|
def populate_accounts(self, account_combo):
|
||||||
@ -1224,148 +1160,23 @@ class PicomcVersionSelector(QWidget):
|
|||||||
if is_bleeding and version_bleeding:
|
if is_bleeding and version_bleeding:
|
||||||
version_number = version_bleeding
|
version_number = version_bleeding
|
||||||
|
|
||||||
about_message = (
|
# Create the about message without translation for the version placeholder
|
||||||
f"PicoDulce Launcher (v{version_number})\n\n"
|
about_message = self.tr(
|
||||||
|
"PicoDulce Launcher (v{0})\n\n"
|
||||||
"A simple Minecraft launcher built using Qt, based on the picomc project.\n\n"
|
"A simple Minecraft launcher built using Qt, based on the picomc project.\n\n"
|
||||||
"Credits:\n"
|
"Credits:\n"
|
||||||
"Nixietab: Code and UI design\n"
|
"Nixietab: Code and UI design\n"
|
||||||
"Wabaano: Graphic design\n"
|
"Wabaano: Graphic design\n"
|
||||||
"Olinad: Christmas!!!!"
|
"Olinad: Christmas!!!!"
|
||||||
)
|
).format(version_number)
|
||||||
QMessageBox.about(self, "About", about_message)
|
|
||||||
|
|
||||||
def check_for_update_start(self):
|
QMessageBox.about(self, self.tr("About"), about_message)
|
||||||
try:
|
|
||||||
with open("version.json") as f:
|
|
||||||
local_version_info = json.load(f)
|
|
||||||
local_version = local_version_info.get("version")
|
|
||||||
local_version_bleeding = local_version_info.get("versionBleeding")
|
|
||||||
logging.info(f"Local version: {local_version}")
|
|
||||||
logging.info(f"Local bleeding version: {local_version_bleeding}")
|
|
||||||
|
|
||||||
with open("config.json") as config_file:
|
|
||||||
config = json.load(config_file)
|
|
||||||
is_bleeding = config.get("IsBleeding", False)
|
|
||||||
|
|
||||||
if local_version:
|
|
||||||
remote_version_info = self.fetch_remote_version()
|
|
||||||
remote_version = remote_version_info.get("version")
|
|
||||||
remote_version_bleeding = remote_version_info.get("versionBleeding")
|
|
||||||
logging.info(f"Remote version: {remote_version}")
|
|
||||||
logging.info(f"Remote bleeding version: {remote_version_bleeding}")
|
|
||||||
|
|
||||||
if is_bleeding:
|
|
||||||
remote_version_to_check = remote_version_bleeding
|
|
||||||
local_version_to_check = local_version_bleeding
|
|
||||||
else:
|
|
||||||
remote_version_to_check = remote_version
|
|
||||||
local_version_to_check = local_version
|
|
||||||
|
|
||||||
if remote_version_to_check and (remote_version_to_check != local_version_to_check):
|
|
||||||
if is_bleeding:
|
|
||||||
update_message = f"Do you want to update to the bleeding edge version ({remote_version_bleeding})?"
|
|
||||||
else:
|
|
||||||
update_message = f"A new version ({remote_version}) is available!\nDo you want to download it now?"
|
|
||||||
update_dialog = QMessageBox.question(self, "Update Available", update_message, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
|
||||||
if update_dialog == QMessageBox.Yes:
|
|
||||||
# Download and apply the update
|
|
||||||
self.download_update(remote_version_info)
|
|
||||||
else:
|
|
||||||
print(f"You already have the latest version!")
|
|
||||||
else:
|
|
||||||
logging.error("Failed to read local version information.")
|
|
||||||
QMessageBox.critical(self, "Error", "Failed to check for updates.")
|
|
||||||
except Exception as e:
|
|
||||||
logging.error("Error checking for updates: %s", str(e))
|
|
||||||
QMessageBox.critical(self, "Error", "Failed to check for updates.")
|
|
||||||
|
|
||||||
def check_for_update(self):
|
def check_for_update(self):
|
||||||
try:
|
self.update_checker.check_for_update()
|
||||||
with open("version.json") as f:
|
|
||||||
local_version_info = json.load(f)
|
|
||||||
local_version = local_version_info.get("version")
|
|
||||||
local_version_bleeding = local_version_info.get("versionBleeding")
|
|
||||||
logging.info(f"Local version: {local_version}")
|
|
||||||
logging.info(f"Local bleeding version: {local_version_bleeding}")
|
|
||||||
|
|
||||||
with open("config.json") as config_file:
|
def check_for_update_start(self):
|
||||||
config = json.load(config_file)
|
self.update_checker.check_for_update_start()
|
||||||
is_bleeding = config.get("IsBleeding", False)
|
|
||||||
|
|
||||||
if local_version:
|
|
||||||
remote_version_info = self.fetch_remote_version()
|
|
||||||
remote_version = remote_version_info.get("version")
|
|
||||||
remote_version_bleeding = remote_version_info.get("versionBleeding")
|
|
||||||
logging.info(f"Remote version: {remote_version}")
|
|
||||||
logging.info(f"Remote bleeding version: {remote_version_bleeding}")
|
|
||||||
|
|
||||||
if is_bleeding:
|
|
||||||
remote_version_to_check = remote_version_bleeding
|
|
||||||
local_version_to_check = local_version_bleeding
|
|
||||||
else:
|
|
||||||
remote_version_to_check = remote_version
|
|
||||||
local_version_to_check = local_version
|
|
||||||
|
|
||||||
if remote_version_to_check and (remote_version_to_check != local_version_to_check):
|
|
||||||
if is_bleeding:
|
|
||||||
update_message = f"Do you want to update to the bleeding edge version ({remote_version_bleeding})?"
|
|
||||||
else:
|
|
||||||
update_message = f"A new version ({remote_version}) is available!\nDo you want to download it now?"
|
|
||||||
update_dialog = QMessageBox.question(self, "Update Available", update_message, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
|
||||||
if update_dialog == QMessageBox.Yes:
|
|
||||||
# Download and apply the update
|
|
||||||
self.download_update(remote_version_info)
|
|
||||||
else:
|
|
||||||
QMessageBox.information(self, "Up to Date", "You already have the latest version!")
|
|
||||||
else:
|
|
||||||
logging.error("Failed to read local version information.")
|
|
||||||
QMessageBox.critical(self, "Error", "Failed to check for updates.")
|
|
||||||
except Exception as e:
|
|
||||||
logging.error("Error checking for updates: %s", str(e))
|
|
||||||
QMessageBox.critical(self, "Error", "Failed to check for updates.")
|
|
||||||
|
|
||||||
def fetch_remote_version(self):
|
|
||||||
try:
|
|
||||||
update_url = "https://raw.githubusercontent.com/nixietab/picodulce/main/version.json"
|
|
||||||
response = requests.get(update_url)
|
|
||||||
if response.status_code == 200:
|
|
||||||
remote_version_info = response.json()
|
|
||||||
return remote_version_info
|
|
||||||
else:
|
|
||||||
logging.error("Failed to fetch update information.")
|
|
||||||
return None
|
|
||||||
except Exception as e:
|
|
||||||
logging.error("Error fetching remote version: %s", str(e))
|
|
||||||
return None
|
|
||||||
|
|
||||||
def download_update(self, version_info):
|
|
||||||
try:
|
|
||||||
update_folder = "update"
|
|
||||||
if not os.path.exists(update_folder):
|
|
||||||
os.makedirs(update_folder)
|
|
||||||
for link in version_info.get("links", []):
|
|
||||||
filename = os.path.basename(link)
|
|
||||||
response = requests.get(link, stream=True)
|
|
||||||
if response.status_code == 200:
|
|
||||||
with open(os.path.join(update_folder, filename), 'wb') as f:
|
|
||||||
for chunk in response.iter_content(chunk_size=1024):
|
|
||||||
f.write(chunk)
|
|
||||||
else:
|
|
||||||
QMessageBox.critical(self, "Error", f"Failed to download update file: {filename}")
|
|
||||||
|
|
||||||
# Move downloaded files one directory up
|
|
||||||
for file in os.listdir(update_folder):
|
|
||||||
src = os.path.join(update_folder, file)
|
|
||||||
dst = os.path.join(os.path.dirname(update_folder), file)
|
|
||||||
shutil.move(src, dst)
|
|
||||||
|
|
||||||
# Remove the update folder
|
|
||||||
shutil.rmtree(update_folder)
|
|
||||||
|
|
||||||
QMessageBox.information(self, "Update", "Updates downloaded successfully.")
|
|
||||||
except Exception as e:
|
|
||||||
logging.error("Error downloading updates: %s", str(e))
|
|
||||||
QMessageBox.critical(self, "Error", "Failed to download updates.")
|
|
||||||
|
|
||||||
def start_discord_rcp(self):
|
def start_discord_rcp(self):
|
||||||
from pypresence import Presence
|
from pypresence import Presence
|
||||||
@ -1698,7 +1509,7 @@ class ModLoaderAndVersionMenu(QDialog):
|
|||||||
layout = QVBoxLayout(install_mod_tab)
|
layout = QVBoxLayout(install_mod_tab)
|
||||||
|
|
||||||
# Create title label
|
# Create title label
|
||||||
title_label = QLabel('Mod Loader Installer')
|
title_label = QLabel(self.tr('Mod Loader Installer'))
|
||||||
title_label.setFont(QFont("Arial", 14))
|
title_label.setFont(QFont("Arial", 14))
|
||||||
layout.addWidget(title_label)
|
layout.addWidget(title_label)
|
||||||
|
|
||||||
@ -1723,7 +1534,7 @@ class ModLoaderAndVersionMenu(QDialog):
|
|||||||
self.fabric_checkbox.clicked.connect(update_versions)
|
self.fabric_checkbox.clicked.connect(update_versions)
|
||||||
|
|
||||||
# Create install button
|
# Create install button
|
||||||
install_button = QPushButton('Install')
|
install_button = QPushButton(self.tr('Install'))
|
||||||
install_button.clicked.connect(lambda: self.install_mod_loader(
|
install_button.clicked.connect(lambda: self.install_mod_loader(
|
||||||
self.version_combo_mod.currentText(),
|
self.version_combo_mod.currentText(),
|
||||||
self.forge_checkbox.isChecked(),
|
self.forge_checkbox.isChecked(),
|
||||||
@ -1735,15 +1546,15 @@ class ModLoaderAndVersionMenu(QDialog):
|
|||||||
layout = QVBoxLayout(download_version_tab)
|
layout = QVBoxLayout(download_version_tab)
|
||||||
|
|
||||||
# Create title label
|
# Create title label
|
||||||
title_label = QLabel('Download Version')
|
title_label = QLabel(self.tr('Download Version'))
|
||||||
title_label.setFont(QFont("Arial", 14))
|
title_label.setFont(QFont("Arial", 14))
|
||||||
layout.addWidget(title_label)
|
layout.addWidget(title_label)
|
||||||
|
|
||||||
# Create checkboxes for different version types
|
# Create checkboxes for different version types
|
||||||
self.release_checkbox = QCheckBox('Releases')
|
self.release_checkbox = QCheckBox(self.tr('Releases'))
|
||||||
self.snapshot_checkbox = QCheckBox('Snapshots')
|
self.snapshot_checkbox = QCheckBox(self.tr('Snapshots'))
|
||||||
self.alpha_checkbox = QCheckBox('Alpha')
|
self.alpha_checkbox = QCheckBox(self.tr('Alpha'))
|
||||||
self.beta_checkbox = QCheckBox('Beta')
|
self.beta_checkbox = QCheckBox(self.tr('Beta'))
|
||||||
layout.addWidget(self.release_checkbox)
|
layout.addWidget(self.release_checkbox)
|
||||||
layout.addWidget(self.snapshot_checkbox)
|
layout.addWidget(self.snapshot_checkbox)
|
||||||
layout.addWidget(self.alpha_checkbox)
|
layout.addWidget(self.alpha_checkbox)
|
||||||
@ -1803,10 +1614,10 @@ class ModLoaderAndVersionMenu(QDialog):
|
|||||||
|
|
||||||
def show_popup(self):
|
def show_popup(self):
|
||||||
self.popup = QDialog(self)
|
self.popup = QDialog(self)
|
||||||
self.popup.setWindowTitle("Installing Version")
|
self.popup.setWindowTitle(self.tr("Installing Version"))
|
||||||
layout = QVBoxLayout(self.popup)
|
layout = QVBoxLayout(self.popup)
|
||||||
|
|
||||||
label = QLabel("The version is being installed...")
|
label = QLabel(self.tr("The version is being installed..."))
|
||||||
layout.addWidget(label)
|
layout.addWidget(label)
|
||||||
|
|
||||||
movie = QMovie("drums.gif")
|
movie = QMovie("drums.gif")
|
||||||
@ -1860,7 +1671,7 @@ class ModLoaderAndVersionMenu(QDialog):
|
|||||||
|
|
||||||
def install_mod_loader(self, version, install_forge, install_fabric):
|
def install_mod_loader(self, version, install_forge, install_fabric):
|
||||||
if not install_forge and not install_fabric:
|
if not install_forge and not install_fabric:
|
||||||
QMessageBox.warning(self, "Select Mod Loader", "Please select at least one mod loader.")
|
QMessageBox.warning(self, self.tr("Select Mod Loader"), self.tr("Please select at least one mod loader."))
|
||||||
return
|
return
|
||||||
|
|
||||||
mod_loader = None
|
mod_loader = None
|
||||||
|
Loading…
Reference in New Issue
Block a user