Files
HOI4LauncherQT/main.py
2026-01-24 17:12:42 +03:00

165 lines
5.7 KiB
Python

import json
import os
import re
import sys
import zipfile
from functools import partial
from json import JSONDecodeError
from PySide6 import QtWidgets
from PySide6.QtCore import QProcess
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import QMainWindow, QWidget
from Layout.ui_card import Ui_MainCard
from Layout.ui_main import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.setFixedSize(800, 600)
class MainCard(QWidget):
def __init__(self):
super(MainCard, self).__init__()
self.ui = Ui_MainCard()
self.ui.setupUi(self)
self.setFixedSize(762, 144)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
mainWindow = MainWindow()
def update_apply_button_state():
old_mods = enabled_mods
old_mods.sort()
new_mods = new_enabled_mods
new_mods.sort()
old_dlcs = disabled_dlcs
old_dlcs.sort()
new_dlcs = new_disabled_dlcs
new_dlcs.sort()
if new_mods == old_mods and old_dlcs == new_dlcs:
mainWindow.ui.apply_button.setEnabled(False)
else:
mainWindow.ui.apply_button.setEnabled(True)
def add_remove_mods(modf: str):
if modf in new_enabled_mods:
new_enabled_mods.remove(modf)
else:
new_enabled_mods.append(modf)
update_apply_button_state()
def add_remove_dlcs(dlcf: str):
if dlcf in new_disabled_dlcs:
new_disabled_dlcs.remove(dlcf)
else:
new_disabled_dlcs.append(dlcf)
update_apply_button_state()
def on_process_finished():
app.quit()
def play_game():
if mainWindow.ui.apply_button.isEnabled():
apply_mods_and_dlcs()
mainWindow.hide()
process = QProcess(mainWindow)
process.finished.connect(on_process_finished)
process.start("/bin/bash", ["-c", f"xdg-open steam://rungameid/394360"])
dlc_mod_file = f"{os.getenv('HOME')}/.local/share/Paradox Interactive/Hearts of Iron IV/dlc_load.json"
with open(dlc_mod_file, "r") as dlc_f:
dlc_obj = json.load(dlc_f)
enabled_mods = [i.replace("mod/ugc_", "").replace(".mod", "") for i in dlc_obj["enabled_mods"]]
disabled_dlcs = [i.split("/")[1] for i in dlc_obj["disabled_dlcs"]]
new_enabled_mods = enabled_mods.copy()
new_disabled_dlcs = disabled_dlcs.copy()
def apply_mods_and_dlcs():
global enabled_mods
enabled_mods = new_enabled_mods.copy()
global disabled_dlcs
disabled_dlcs = new_disabled_dlcs.copy()
new_dlc_obj = dlc_obj.copy()
new_dlc_obj["enabled_mods"] = [f"mod/ugc_{mod}.mod" for mod in new_enabled_mods]
new_dlc_obj["disabled_dlcs"] = [f"dlc/{dlc}/{dlc.split("_")[0]}.dlc" for dlc in new_disabled_dlcs]
with open(dlc_mod_file, "w") as mf:
mf.write(json.dumps(new_dlc_obj))
update_apply_button_state()
mainWindow.ui.apply_button.clicked.connect(apply_mods_and_dlcs)
mainWindow.ui.play_button.clicked.connect(play_game)
mod_dir = f"{os.getenv('HOME')}/.local/share/Steam/steamapps/workshop/content/394360"
dlc_dir = f"{os.getenv('HOME')}/.local/share/Steam/steamapps/common/Hearts of Iron IV/dlc"
temp_thumb = "placeholder_unknown.jpg"
for f in os.listdir(mod_dir):
try:
with open(f"{mod_dir}/{f}/descriptor.mod", "r", encoding="utf-8") as fl:
text = fl.read()
except FileNotFoundError:
files = os.listdir(f"{mod_dir}/{f}")
if ".zip" == [a[-4:] for a in files][0]:
with zipfile.ZipFile(f"{mod_dir}/{f}/{files[0]}") as zf:
with zf.open("descriptor.mod") as flz:
text = flz.read().decode("utf-8")
mod_name = re.findall('name="(.*)"', text)[0]
thumb_name = re.findall('picture="(.*)"', text)
if len(thumb_name) != 0:
mod_thumbnail = f"{mod_dir}/{f}/{thumb_name[0]}"
elif "thumbnail.png" in os.listdir(f"{mod_dir}/{f}"):
mod_thumbnail = f"{mod_dir}/{f}/thumbnail.png"
else:
mod_thumbnail = temp_thumb
item = MainCard()
item.ui.card_thumbnail.setFixedSize(128, 128)
pixmap = QPixmap(mod_thumbnail).scaled(item.ui.card_thumbnail.size())
item.ui.card_thumbnail.setPixmap(pixmap)
item.ui.card_title_check.setText(mod_name)
item.ui.card_descr.setText(f"{mod_dir}/{f}")
if f in enabled_mods:
item.ui.card_title_check.setChecked(True)
item.ui.card_title_check.clicked.connect(partial(add_remove_mods, f))
mainWindow.ui.mods_container.layout().addWidget(item)
for d in os.listdir(dlc_dir):
dlc_p = f"{dlc_dir}/{d}"
dlc_info = f"{dlc_p}/{d.split("_")[0]}.dlc"
dlc_name = ""
dlc_thumbnail = ""
try:
with open(dlc_info, "r") as df:
text = df.read()
dlc_name = re.findall('^name = "(.*)"', text)[0]
dlc_thumbnail = f"{dlc_p}/thumbnail.png"
except FileNotFoundError:
dlc_name = d
dlc_thumbnail = temp_thumb
item = MainCard()
item.ui.card_thumbnail.setFixedSize(224, 128)
pixmap = QPixmap(dlc_thumbnail).scaled(item.ui.card_thumbnail.size())
item.ui.card_thumbnail.setPixmap(pixmap)
item.ui.card_title_check.setText(dlc_name)
if d not in disabled_dlcs:
item.ui.card_title_check.setChecked(True)
item.ui.card_title_check.clicked.connect(partial(add_remove_dlcs, d))
mainWindow.ui.dlcs_container.layout().addWidget(item)
mainWindow.show()
sys.exit(app.exec())