From 3e8b8efce0ee0b830e134615581e33ae5d9aee86 Mon Sep 17 00:00:00 2001 From: seuyh Date: Sun, 17 Mar 2024 20:37:25 +0700 Subject: [PATCH] 0.97 --- design/languages/en.txt | 5 +- design/languages/installer_en.py | 38 ++- design/languages/installer_ru.py | 479 +++++++++++++++++-------------- design/languages/ru.txt | 5 +- design/resources_rc.py | 2 +- gui/DownloadThread.py | 23 +- gui/cream_api_maker.py | 217 +++++++------- gui/main_window.py | 236 +++++++++++---- libs/server_data.py | 5 +- 9 files changed, 608 insertions(+), 402 deletions(-) diff --git a/design/languages/en.txt b/design/languages/en.txt index 5ca0ad4..ed35e93 100644 --- a/design/languages/en.txt +++ b/design/languages/en.txt @@ -1,5 +1,6 @@ update_found_title: New version -update_found_text: A new version has been detected on the server!\nClick 'OK' to update\nAfter the update, the new version will be automatically opened\n\nYour version: {iversion} Server version: {version} +update_found_text: A new version has been detected on the server!\nClick 'OK' to update\nAfter the update, the new version will be automatically opened\n\nYour version: {iversion} Server version: {version}\n\nIf auto-update does not work, download the latest version using the link:\n{url} +open_link: Open link update_load: Updating... update: Update cancel_title: Exit @@ -12,7 +13,7 @@ dlc_get: Getting DLC info: dlc_get_format: connecting to api done: Done! speed: Speed: {speed} MB/s -download_error: File download error\nMost likely the server is currently unavailable.\nPlease try again later or report the issue to me. +download_error: File download error\nMost likely the server is currently unavailable.\nPlease try again later or report the issue to me.\n\nThe download server is not available in Ukraine, please use VPN. attention: Attention launcher_reinstall_1: The launcher installer will now open, please select 'Remove' if prompted, or simply continue installation. launcher_reinstall_2: The launcher installer will now open, please proceed with the installation. diff --git a/design/languages/installer_en.py b/design/languages/installer_en.py index 75c1e42..61f40b4 100644 --- a/design/languages/installer_en.py +++ b/design/languages/installer_en.py @@ -383,21 +383,29 @@ def setupUi(self, MainWindow): self.label.setGeometry(QtCore.QRect(210, 86, 91, 20)) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(self.page_5) - self.label_2.setGeometry(QtCore.QRect(210, 180, 251, 20)) + self.label_2.setGeometry(QtCore.QRect(210, 260, 121, 20)) self.label_2.setObjectName("label_2") self.creamapi_progressBar_2 = QtWidgets.QProgressBar(self.page_5) - self.creamapi_progressBar_2.setGeometry(QtCore.QRect(210, 204, 281, 21)) + self.creamapi_progressBar_2.setGeometry(QtCore.QRect(340, 260, 171, 21)) self.creamapi_progressBar_2.setProperty("value", 0) self.creamapi_progressBar_2.setObjectName("creamapi_progressBar_2") - self.creamapi_label = QtWidgets.QLabel(self.page_5) - self.creamapi_label.setGeometry(QtCore.QRect(210, 234, 281, 20)) - self.creamapi_label.setObjectName("creamapi_label") - self.label_3 = QtWidgets.QLabel(self.page_5) - self.label_3.setGeometry(QtCore.QRect(210, 260, 281, 20)) - self.label_3.setObjectName("label_3") self.speed_label = QtWidgets.QLabel(self.page_5) self.speed_label.setGeometry(QtCore.QRect(376, 140, 121, 20)) self.speed_label.setObjectName("speed_label") + self.label_3 = QtWidgets.QLabel(self.page_5) + self.label_3.setGeometry(QtCore.QRect(210, 170, 241, 20)) + self.label_3.setObjectName("label_3") + self.download_progressBar_2 = QtWidgets.QProgressBar(self.page_5) + self.download_progressBar_2.setGeometry(QtCore.QRect(210, 200, 281, 21)) + self.download_progressBar_2.setProperty("value", 0) + self.download_progressBar_2.setObjectName("download_progressBar_2") + self.download_text_2 = QtWidgets.QLineEdit(self.page_5) + self.download_text_2.setGeometry(QtCore.QRect(210, 230, 291, 20)) + self.download_text_2.setStyleSheet("background-color: rgb(240, 240, 240);") + self.download_text_2.setText("") + self.download_text_2.setFrame(False) + self.download_text_2.setReadOnly(True) + self.download_text_2.setObjectName("download_text_2") self.stackedWidget.addWidget(self.page_5) self.page_6 = QtWidgets.QWidget() self.page_6.setObjectName("page_6") @@ -505,12 +513,12 @@ def setupUi(self, MainWindow): "}") self.finish_button.setObjectName("finish_button") self.launch_game = QtWidgets.QCheckBox(self.page_7) - self.launch_game.setGeometry(QtCore.QRect(210, 200, 121, 21)) + self.launch_game.setGeometry(QtCore.QRect(210, 200, 231, 21)) self.launch_game.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.launch_game.setObjectName("launch_game") self.checkBox = QtWidgets.QCheckBox(self.page_7) self.checkBox.setEnabled(False) - self.checkBox.setGeometry(QtCore.QRect(210, 250, 141, 21)) + self.checkBox.setGeometry(QtCore.QRect(210, 250, 251, 21)) self.checkBox.setCheckable(True) self.checkBox.setChecked(True) self.checkBox.setObjectName("checkBox") @@ -539,6 +547,12 @@ def setupUi(self, MainWindow): self.textBrowser_15.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.textBrowser_15.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.textBrowser_15.setObjectName("textBrowser_15") + self.dlc_list = QtWidgets.QListWidget(self.centralwidget) + self.dlc_list.setGeometry(QtCore.QRect(510, 11, 201, 311)) + self.dlc_list.setStyleSheet("background-color: rgb(240, 240, 240);\n" +"border: 1px solid #B22222;") + self.dlc_list.setFrameShape(QtWidgets.QFrame.NoFrame) + self.dlc_list.setObjectName("dlc_list") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) @@ -655,9 +669,8 @@ def retranslateUi(self, MainWindow): self.cancel_button_5.setText(_translate("MainWindow", "Cancel")) self.label.setText(_translate("MainWindow", "DLC downloading:")) self.label_2.setText(_translate("MainWindow", "Generating creamapi:")) - self.creamapi_label.setText(_translate("MainWindow", "Getting DLC info: connecting to the API")) - self.label_3.setText(_translate("MainWindow", "The generation speed depends on the server.")) self.speed_label.setText(_translate("MainWindow", "Speed: %nan%")) + self.label_3.setText(_translate("MainWindow", "DLC download progress:")) self.textBrowser_12.setHtml(_translate("MainWindow", "\n" "\n" "

GitHub

")) + diff --git a/design/languages/installer_ru.py b/design/languages/installer_ru.py index 29cb434..a2e2b26 100644 --- a/design/languages/installer_ru.py +++ b/design/languages/installer_ru.py @@ -30,21 +30,21 @@ def setupUi(self, MainWindow): self.next_button.setGeometry(QtCore.QRect(350, 300, 75, 23)) self.next_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.next_button.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.next_button.setObjectName("next_button") self.cancel_button = QtWidgets.QPushButton(self.page_2) self.cancel_button.setGeometry(QtCore.QRect(430, 300, 75, 23)) self.cancel_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.cancel_button.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.cancel_button.setObjectName("cancel_button") self.line = QtWidgets.QFrame(self.page_2) self.line.setGeometry(QtCore.QRect(190, 290, 331, 1)) @@ -90,21 +90,21 @@ def setupUi(self, MainWindow): self.next_button_3.setGeometry(QtCore.QRect(350, 300, 75, 23)) self.next_button_3.setCursor(QtGui.QCursor(QtCore.Qt.ForbiddenCursor)) self.next_button_3.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.next_button_3.setObjectName("next_button_3") self.cancel_button_3 = QtWidgets.QPushButton(self.page_3) self.cancel_button_3.setGeometry(QtCore.QRect(430, 300, 75, 23)) self.cancel_button_3.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.cancel_button_3.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.cancel_button_3.setObjectName("cancel_button_3") self.listWidget_3 = QtWidgets.QListWidget(self.page_3) self.listWidget_3.setGeometry(QtCore.QRect(0, 0, 191, 291)) @@ -115,11 +115,11 @@ def setupUi(self, MainWindow): self.back_button_2.setGeometry(QtCore.QRect(270, 300, 75, 23)) self.back_button_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.back_button_2.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.back_button_2.setObjectName("back_button_2") self.textBrowser = QtWidgets.QTextBrowser(self.page_3) self.textBrowser.setGeometry(QtCore.QRect(210, 10, 281, 31)) @@ -176,11 +176,11 @@ def setupUi(self, MainWindow): self.back_button_3.setGeometry(QtCore.QRect(270, 300, 75, 23)) self.back_button_3.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.back_button_3.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.back_button_3.setObjectName("back_button_3") self.line_5 = QtWidgets.QFrame(self.page_4) self.line_5.setGeometry(QtCore.QRect(190, 80, 331, 1)) @@ -192,11 +192,11 @@ def setupUi(self, MainWindow): self.next_button_4.setGeometry(QtCore.QRect(350, 300, 75, 23)) self.next_button_4.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.next_button_4.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.next_button_4.setObjectName("next_button_4") self.line_6 = QtWidgets.QFrame(self.page_4) self.line_6.setGeometry(QtCore.QRect(190, 290, 331, 1)) @@ -207,9 +207,9 @@ def setupUi(self, MainWindow): self.textBrowser_5 = QtWidgets.QTextBrowser(self.page_4) self.textBrowser_5.setGeometry(QtCore.QRect(210, 90, 281, 191)) self.textBrowser_5.setStyleSheet("background-color: rgb(240, 240, 240);\n" -"\n" -"text-decoration: none;\n" -"") + "\n" + "text-decoration: none;\n" + "") self.textBrowser_5.setFrameShape(QtWidgets.QFrame.Box) self.textBrowser_5.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) self.textBrowser_5.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) @@ -218,11 +218,11 @@ def setupUi(self, MainWindow): self.cancel_button_4.setGeometry(QtCore.QRect(430, 300, 75, 23)) self.cancel_button_4.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.cancel_button_4.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.cancel_button_4.setObjectName("cancel_button_4") self.textBrowser_6 = QtWidgets.QTextBrowser(self.page_4) self.textBrowser_6.setGeometry(QtCore.QRect(210, 40, 281, 35)) @@ -245,21 +245,21 @@ def setupUi(self, MainWindow): self.next_button_2.setGeometry(QtCore.QRect(350, 300, 75, 23)) self.next_button_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.next_button_2.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.next_button_2.setObjectName("next_button_2") self.cancel_button_2 = QtWidgets.QPushButton(self.page) self.cancel_button_2.setGeometry(QtCore.QRect(430, 300, 75, 23)) self.cancel_button_2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.cancel_button_2.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.cancel_button_2.setObjectName("cancel_button_2") self.path_place = QtWidgets.QTextEdit(self.page) self.path_place.setGeometry(QtCore.QRect(210, 150, 281, 25)) @@ -270,21 +270,21 @@ def setupUi(self, MainWindow): self.locate_folder.setGeometry(QtCore.QRect(410, 180, 75, 23)) self.locate_folder.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.locate_folder.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.locate_folder.setObjectName("locate_folder") self.back_button = QtWidgets.QPushButton(self.page) self.back_button.setGeometry(QtCore.QRect(270, 300, 75, 23)) self.back_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.back_button.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.back_button.setObjectName("back_button") self.line_2 = QtWidgets.QFrame(self.page) self.line_2.setGeometry(QtCore.QRect(190, 290, 331, 1)) @@ -362,42 +362,50 @@ def setupUi(self, MainWindow): self.next_button_5.setGeometry(QtCore.QRect(350, 300, 75, 23)) self.next_button_5.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.next_button_5.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.next_button_5.setObjectName("next_button_5") self.cancel_button_5 = QtWidgets.QPushButton(self.page_5) self.cancel_button_5.setEnabled(False) self.cancel_button_5.setGeometry(QtCore.QRect(430, 300, 75, 23)) self.cancel_button_5.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.cancel_button_5.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.cancel_button_5.setObjectName("cancel_button_5") self.label = QtWidgets.QLabel(self.page_5) self.label.setGeometry(QtCore.QRect(210, 86, 91, 20)) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(self.page_5) - self.label_2.setGeometry(QtCore.QRect(210, 180, 251, 20)) + self.label_2.setGeometry(QtCore.QRect(210, 260, 121, 20)) self.label_2.setObjectName("label_2") self.creamapi_progressBar_2 = QtWidgets.QProgressBar(self.page_5) - self.creamapi_progressBar_2.setGeometry(QtCore.QRect(210, 204, 281, 21)) + self.creamapi_progressBar_2.setGeometry(QtCore.QRect(340, 260, 171, 21)) self.creamapi_progressBar_2.setProperty("value", 0) self.creamapi_progressBar_2.setObjectName("creamapi_progressBar_2") - self.creamapi_label = QtWidgets.QLabel(self.page_5) - self.creamapi_label.setGeometry(QtCore.QRect(210, 234, 281, 20)) - self.creamapi_label.setObjectName("creamapi_label") - self.label_3 = QtWidgets.QLabel(self.page_5) - self.label_3.setGeometry(QtCore.QRect(210, 260, 281, 20)) - self.label_3.setObjectName("label_3") self.speed_label = QtWidgets.QLabel(self.page_5) - self.speed_label.setGeometry(QtCore.QRect(376, 140, 121, 20)) + self.speed_label.setGeometry(QtCore.QRect(380, 140, 101, 20)) self.speed_label.setObjectName("speed_label") + self.download_progressBar_2 = QtWidgets.QProgressBar(self.page_5) + self.download_progressBar_2.setGeometry(QtCore.QRect(210, 200, 281, 21)) + self.download_progressBar_2.setProperty("value", 0) + self.download_progressBar_2.setObjectName("download_progressBar_2") + self.label_3 = QtWidgets.QLabel(self.page_5) + self.label_3.setGeometry(QtCore.QRect(210, 170, 241, 20)) + self.label_3.setObjectName("label_3") + self.download_text_2 = QtWidgets.QLineEdit(self.page_5) + self.download_text_2.setGeometry(QtCore.QRect(210, 230, 291, 20)) + self.download_text_2.setStyleSheet("background-color: rgb(240, 240, 240);") + self.download_text_2.setText("") + self.download_text_2.setFrame(False) + self.download_text_2.setReadOnly(True) + self.download_text_2.setObjectName("download_text_2") self.stackedWidget.addWidget(self.page_5) self.page_6 = QtWidgets.QWidget() self.page_6.setObjectName("page_6") @@ -426,21 +434,21 @@ def setupUi(self, MainWindow): self.reinstall_button.setGeometry(QtCore.QRect(350, 300, 75, 23)) self.reinstall_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.reinstall_button.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.reinstall_button.setObjectName("reinstall_button") self.cancel_button_6 = QtWidgets.QPushButton(self.page_6) self.cancel_button_6.setGeometry(QtCore.QRect(430, 300, 75, 23)) self.cancel_button_6.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.cancel_button_6.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.cancel_button_6.setObjectName("cancel_button_6") self.reinstall_low = QtWidgets.QTextBrowser(self.page_6) self.reinstall_low.setGeometry(QtCore.QRect(210, 130, 281, 35)) @@ -498,19 +506,19 @@ def setupUi(self, MainWindow): self.finish_button.setGeometry(QtCore.QRect(430, 300, 75, 23)) self.finish_button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.finish_button.setStyleSheet("QPushButton {border: 1px solid #B22222;\n" -"}\n" -"\n" -"QPushButton:hover {\n" -" background-color: #FFD0D1;\n" -"}") + "}\n" + "\n" + "QPushButton:hover {\n" + " background-color: #FFD0D1;\n" + "}") self.finish_button.setObjectName("finish_button") self.launch_game = QtWidgets.QCheckBox(self.page_7) - self.launch_game.setGeometry(QtCore.QRect(210, 200, 121, 21)) + self.launch_game.setGeometry(QtCore.QRect(210, 200, 221, 21)) self.launch_game.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.launch_game.setObjectName("launch_game") self.checkBox = QtWidgets.QCheckBox(self.page_7) self.checkBox.setEnabled(False) - self.checkBox.setGeometry(QtCore.QRect(210, 250, 141, 21)) + self.checkBox.setGeometry(QtCore.QRect(210, 250, 201, 21)) self.checkBox.setCheckable(True) self.checkBox.setChecked(True) self.checkBox.setObjectName("checkBox") @@ -539,6 +547,12 @@ def setupUi(self, MainWindow): self.textBrowser_15.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.textBrowser_15.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.textBrowser_15.setObjectName("textBrowser_15") + self.dlc_list = QtWidgets.QListWidget(self.centralwidget) + self.dlc_list.setGeometry(QtCore.QRect(510, 11, 201, 311)) + self.dlc_list.setStyleSheet("background-color: rgb(240, 240, 240);\n" + "border: 1px solid #B22222;") + self.dlc_list.setFrameShape(QtWidgets.QFrame.NoFrame) + self.dlc_list.setObjectName("dlc_list") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) @@ -550,155 +564,176 @@ def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.next_button.setText(_translate("MainWindow", "Далее")) self.cancel_button.setText(_translate("MainWindow", "Отмена")) - self.hello_msg.setHtml(_translate("MainWindow", "\n" -"\n" -"

Вас приветствует Stellaris "DLC Unlocker - Разблокировщик дополнений" [unknown]

")) - self.hello2_msg.setHtml(_translate("MainWindow", "\n" -"\n" -"

Программа выполнит разблокировку дополнений для игры Stellaris версии [unknown]

")) - self.textBrowser_3.setHtml(_translate("MainWindow", "\n" -"\n" -"

Нажмите "Далее", чтобы продолжить или "Отмена", чтобы выйти из программы установки.

")) + self.hello_msg.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Вас приветствует Stellaris "DLC Unlocker - Разблокировщик дополнений" [unknown]

")) + self.hello2_msg.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Программа выполнит разблокировку дополнений для игры Stellaris версии [unknown]

")) + self.textBrowser_3.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Нажмите "Далее", чтобы продолжить или "Отмена", чтобы выйти из программы установки.

")) self.next_button_3.setText(_translate("MainWindow", "Далее")) self.cancel_button_3.setText(_translate("MainWindow", "Отмена")) self.back_button_2.setText(_translate("MainWindow", "Назад")) - self.textBrowser.setHtml(_translate("MainWindow", "\n" -"\n" -"

Информация

")) - self.textBrowser_2.setHtml(_translate("MainWindow", "\n" -"\n" -"

Пожалуйста, прочитие следующую важную информацию пред тем, как продолжить.

")) - self.textBrowser_4.setHtml(_translate("MainWindow", "\n" -"\n" -"

1. Данный разблокировщик распространяется абсолютно бесплатно. Любое коммерческое использование данного разблокировщика запрещается.

\n" -"


\n" -"

2. ДАННЫЙ РАЗБЛОКИРОВЩИК ПОСТАВЛЯЕТСЯ ПО ПРИНЦИПУ «AS IS». НИКАКИХ ГАРАНТИЙ НЕ ПРИЛАГАЕТСЯ И НЕ ПРЕДУСМАТРИВАЕТСЯ. ВЫ ИСПОЛЬЗУЕТЕ ЭТУ МОДИФИКАЦИЮ ОРИГИНАЛЬНОЙ ИГРЫ НА СВОЙ СТРАХ И РИСК. АВТОРЫ МОДИФИКАЦИИ НЕ БУДУТ ОТВЕЧАТЬ НИ ЗА КАКИЕ ПОТЕРИ ИЛИ ИСКАЖЕНИЯ ДАННЫХ, ЛЮБУЮ УПУЩЕННУЮ ВЫГОДУ В ПРОЦЕССЕ ИСПОЛЬЗОВАНИЯ ИЛИ НЕПРАВИЛЬНОГО ИСПОЛЬЗОВАНИЯ ДАННОЙ МОДИФИКАЦИИ.

\n" -"


\n" -"

4. Все права, не предоставленные здесь явно, сохраняются за правообладателями.

\n" -"


\n" -"

5. Установка и использование данной модификации означает, что вы ознакомились и понимаете положения настоящего лицензионного соглашения и согласны с ними.

\n" -"


")) + self.textBrowser.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Информация

")) + self.textBrowser_2.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Пожалуйста, прочитие следующую важную информацию пред тем, как продолжить.

")) + self.textBrowser_4.setHtml(_translate("MainWindow", + "\n" + "\n" + "

1. Данный разблокировщик распространяется абсолютно бесплатно. Любое коммерческое использование данного разблокировщика запрещается.

\n" + "


\n" + "

2. ДАННЫЙ РАЗБЛОКИРОВЩИК ПОСТАВЛЯЕТСЯ ПО ПРИНЦИПУ «AS IS». НИКАКИХ ГАРАНТИЙ НЕ ПРИЛАГАЕТСЯ И НЕ ПРЕДУСМАТРИВАЕТСЯ. ВЫ ИСПОЛЬЗУЕТЕ ЭТУ МОДИФИКАЦИЮ ОРИГИНАЛЬНОЙ ИГРЫ НА СВОЙ СТРАХ И РИСК. АВТОРЫ МОДИФИКАЦИИ НЕ БУДУТ ОТВЕЧАТЬ НИ ЗА КАКИЕ ПОТЕРИ ИЛИ ИСКАЖЕНИЯ ДАННЫХ, ЛЮБУЮ УПУЩЕННУЮ ВЫГОДУ В ПРОЦЕССЕ ИСПОЛЬЗОВАНИЯ ИЛИ НЕПРАВИЛЬНОГО ИСПОЛЬЗОВАНИЯ ДАННОЙ МОДИФИКАЦИИ.

\n" + "


\n" + "

4. Все права, не предоставленные здесь явно, сохраняются за правообладателями.

\n" + "


\n" + "

5. Установка и использование данной модификации означает, что вы ознакомились и понимаете положения настоящего лицензионного соглашения и согласны с ними.

\n" + "


")) self.eula_true.setText(_translate("MainWindow", "Я принимаю условия соглашения")) self.eula_false.setText(_translate("MainWindow", "Я не принимаю условия соглашения")) self.eula_true1.setText(_translate("MainWindow", "Я ничего не читал, но со всем согласен")) self.back_button_3.setText(_translate("MainWindow", "Назад")) self.next_button_4.setText(_translate("MainWindow", "Далее")) - self.textBrowser_5.setHtml(_translate("MainWindow", "\n" -"\n" -"

Stellaris DLC Unlocker

\n" -"


\n" -"

Требования:

\n" -"

Лицензия: Steam.

\n" -"


\n" -"

Установка:

\n" -"

Следуйте инструкциям инсталлятора. Установка почти полностью автоматическая.

\n" -"


\n" -"

Удаление:

\n" -"

Переустановите Paradox лаунчер, удалите папку "dlc" в директории игры. Не забудте заново скачать те dlc которые у вас приобретены.

Сделано для всех, с любовью
seuyh

\n" -"

GitHub

\n" -"

Отдельная благодарность человеку, который все это время обновлял анлокер с ручной установкой

\n" -"

He11oThere

\n" -"


playground.ru Stellaris DLC Unlocker

\n" -"


")) + self.textBrowser_5.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Stellaris DLC Unlocker

\n" + "


\n" + "

Требования:

\n" + "

Лицензия: Steam.

\n" + "


\n" + "

Установка:

\n" + "

Следуйте инструкциям инсталлятора. Установка почти полностью автоматическая.

\n" + "


\n" + "

Удаление:

\n" + "

Переустановите Paradox лаунчер, удалите папку "dlc" в директории игры. Не забудте заново скачать те dlc которые у вас приобретены.

Сделано для всех, с любовью
seuyh

\n" + "

GitHub

\n" + "

Отдельная благодарность человеку, который все это время обновлял анлокер с ручной установкой

\n" + "

He11oThere

\n" + "


playground.ru Stellaris DLC Unlocker

\n" + "


")) self.cancel_button_4.setText(_translate("MainWindow", "Отмена")) - self.textBrowser_6.setHtml(_translate("MainWindow", "\n" -"\n" -"

Пожалуйста, прочитие следующую важную информацию пред тем, как продолжить.

")) - self.textBrowser_7.setHtml(_translate("MainWindow", "\n" -"\n" -"

Информация

")) + self.textBrowser_6.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Пожалуйста, прочитие следующую важную информацию пред тем, как продолжить.

")) + self.textBrowser_7.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Информация

")) self.next_button_2.setText(_translate("MainWindow", "Далее")) self.cancel_button_2.setText(_translate("MainWindow", "Отмена")) self.locate_folder.setText(_translate("MainWindow", "Обзор...")) self.back_button.setText(_translate("MainWindow", "Назад")) - self.textBrowser_8.setHtml(_translate("MainWindow", "\n" -"\n" -"

Выбор папки игры

")) - self.textBrowser_9.setHtml(_translate("MainWindow", "\n" -"\n" -"

Пожалуйста, укажите папку с игрой, если мы не смогли найти ее автоматически.

")) + self.textBrowser_8.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Выбор папки игры

")) + self.textBrowser_9.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Пожалуйста, укажите папку с игрой, если мы не смогли найти ее автоматически.

")) self.space_req.setText(_translate("MainWindow", "Требуется дополнительно %nan% места")) - self.textBrowser_10.setHtml(_translate("MainWindow", "\n" -"\n" -"

Пожалуйста, подождите пока мы загрузим все нужные файлы с сервера.

")) - self.textBrowser_11.setHtml(_translate("MainWindow", "\n" -"\n" -"

Загрузка DLC

")) + self.textBrowser_10.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Пожалуйста, подождите пока мы загрузим все нужные файлы с сервера.

")) + self.textBrowser_11.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Загрузка DLC

")) self.download_text.setText(_translate("MainWindow", "Подключение к серверу...")) self.next_button_5.setText(_translate("MainWindow", "Далее")) self.cancel_button_5.setText(_translate("MainWindow", "Отмена")) self.label.setText(_translate("MainWindow", "Загрузка DLC:")) self.label_2.setText(_translate("MainWindow", "Генерация creamapi:")) - self.creamapi_label.setText(_translate("MainWindow", "Получение инфо о dlc: подключение к api")) - self.label_3.setText(_translate("MainWindow", "Скорость генерации зависит от сервера.")) self.speed_label.setText(_translate("MainWindow", "Скорость: %nan%")) - self.textBrowser_12.setHtml(_translate("MainWindow", "\n" -"\n" -"

Переустановка лаунчера

")) - self.textBrowser_13.setHtml(_translate("MainWindow", "\n" -"\n" -"

Необходимо переустановить Paradox лаунчер для корректной работы.

")) + self.label_3.setText(_translate("MainWindow", "Прогресс загрузки теущего DLC:")) + self.textBrowser_12.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Переустановка лаунчера

")) + self.textBrowser_13.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Необходимо переустановить Paradox лаунчер для корректной работы.

")) self.reinstall_button.setText(_translate("MainWindow", "Хорошо")) self.cancel_button_6.setText(_translate("MainWindow", "Отмена")) - self.reinstall_low.setHtml(_translate("MainWindow", "\n" -"\n" -"

Программа почти все сделает автоматически, вам нужно лишь следовать указаниям на экране.

")) + self.reinstall_low.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Программа почти все сделает автоматически, вам нужно лишь следовать указаниям на экране.

")) self.reinstall_up.setText(_translate("MainWindow", "Сейчас нужно будет переустановить Paradox лаунчер")) self.progress_label.setText(_translate("MainWindow", "Прогресс переустановки:")) self.now_reinstalling.setText(_translate("MainWindow", "Ждем")) - self.finish_text.setHtml(_translate("MainWindow", "\n" -"\n" -"

Перезаписываем оставшиеся файлы.

Пожалуйста подождите немного.

")) - self.textBrowser_16.setHtml(_translate("MainWindow", "\n" -"\n" -"

Завершение

")) - self.textBrowser_17.setHtml(_translate("MainWindow", "\n" -"\n" -"

Мы уже почти все сделали, осталось немного подождать.

")) + self.finish_text.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Перезаписываем оставшиеся файлы.

Пожалуйста подождите немного.

")) + self.textBrowser_16.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Завершение

")) + self.textBrowser_17.setHtml(_translate("MainWindow", + "\n" + "\n" + "

Мы уже почти все сделали, осталось немного подождать.

")) self.finish_button.setText(_translate("MainWindow", "Готово")) self.launch_game.setText(_translate("MainWindow", "Запустить игру")) self.checkBox.setText(_translate("MainWindow", "Автор крутой")) self.version.setText(_translate("MainWindow", "version %nan%")) - self.textBrowser_15.setHtml(_translate("MainWindow", "\n" -"\n" -"

GitHub

")) + self.textBrowser_15.setHtml(_translate("MainWindow", + "\n" + "\n" + "

GitHub

")) + + diff --git a/design/languages/ru.txt b/design/languages/ru.txt index a63841a..edb5b9d 100644 --- a/design/languages/ru.txt +++ b/design/languages/ru.txt @@ -1,5 +1,6 @@ update_found_title: Новая версия -update_found_text: На сервере обнаружена новая версия!\nНажмите 'ОК' для обновления\nПосле обновления новая версия будет автоматически открыта\n\nВаша версия: {iversion} Версия на сервере: {version} +update_found_text: На сервере обнаружена новая версия!\nНажмите 'ОК' для обновления\nПосле обновления новая версия будет автоматически открыта\n\nВаша версия: {iversion} Версия на сервере: {version}\n\nЕсли авто-обновление не срабатывает, самостоятельно загрузите последнюю версию по ссылке:\n{url} +open_link: Открыть ссылку update_load: Загрузка обновления... update: Обновление cancel_title: Выход @@ -12,7 +13,7 @@ dlc_get: Получение инфо о dlc: dlc_get_format: подключение к api done: Готово! speed: Скорость: {speed} Мб/с -download_error: Ошибка загрузки файла\nСкорее всего в данный момент сервер не доступен.\nПопробуйте позже, либо сообщите мне о проблеме. +download_error: Ошибка загрузки файла\nСкорее всего в данный момент сервер не доступен.\nПопробуйте позже, либо сообщите мне о проблеме.\n\nСервер для загрузки не доступен в Украине, пожалуйста используйте VPN. attention: Внимание launcher_reinstall_1: Сейчас будет открыт инсталятор лаунчера, пожалуйста выберете 'Remove', если будет предложено, либо просто продолжите установку. launcher_reinstall_2: Сейчас будет открыт инсталятор лаунчера, пожалуйста выполните установку. diff --git a/design/resources_rc.py b/design/resources_rc.py index 584f85f..352912a 100644 --- a/design/resources_rc.py +++ b/design/resources_rc.py @@ -863,7 +863,7 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x8d\xdf\x9b\x77\x5a\ +\x00\x00\x01\x8d\xea\xb0\x01\x86\ \x00\x00\x00\x40\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x65\ \x00\x00\x01\x8d\xe5\x23\x99\x4e\ \x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x30\x86\ diff --git a/gui/DownloadThread.py b/gui/DownloadThread.py index 0f74b77..f01e805 100644 --- a/gui/DownloadThread.py +++ b/gui/DownloadThread.py @@ -1,20 +1,25 @@ import urllib.request -from os import remove +from os import remove, path from PyQt5 import QtCore from time import time class DownloaderThread(QtCore.QThread): - progress_signal = QtCore.pyqtSignal(int) + progress_signal = QtCore.pyqtSignal(int, bool) + progress_signal_2 = QtCore.pyqtSignal(int) + text_signal = QtCore.pyqtSignal(str) error_signal = QtCore.pyqtSignal(Exception) speed_signal = QtCore.pyqtSignal(float) + finished = QtCore.pyqtSignal() - def __init__(self, file_url, save_path): + def __init__(self, file_url, save_path, dlc_downloaded, dlc_count): super().__init__() self.file_url = file_url self.save_path = save_path self.cancelled = False self.downloaded_bytes = 0 + self.dlc_downloaded = dlc_downloaded + self.dlc_count = dlc_count def run(self): request = urllib.request.Request(self.file_url, headers={"User-Agent": "Mozilla/5.0"}) @@ -39,12 +44,20 @@ def run(self): speed = round(self.downloaded_bytes / (1024 * 1024 * elapsed_time), 1) else: speed = 0 - progress_percentage = int((self.downloaded_bytes / total_size) * 100) + progress_percentage_2 = int((self.downloaded_bytes / total_size) * 100) self.speed_signal.emit(speed) - self.progress_signal.emit(progress_percentage) + self.progress_signal_2.emit(progress_percentage_2) + + file.close() + except Exception as e: self.error_signal.emit(e) + finally: + progress_percentage = int((self.dlc_downloaded / self.dlc_count) * 100) + self.progress_signal.emit(progress_percentage, True) + self.text_signal.emit(path.basename(self.save_path)) + self.finished.emit() def cancel(self): self.cancelled = True diff --git a/gui/cream_api_maker.py b/gui/cream_api_maker.py index 83a09c4..8e469dc 100644 --- a/gui/cream_api_maker.py +++ b/gui/cream_api_maker.py @@ -1,13 +1,12 @@ from requests import get from time import sleep -from datetime import datetime from PyQt5 import QtCore import os class CreamAPI(QtCore.QThread): progress_signal = QtCore.pyqtSignal(int) - dlc_signal = QtCore.pyqtSignal(str) + # dlc_signal = QtCore.pyqtSignal(str) def __init__(self): super().__init__() @@ -59,105 +58,121 @@ def get_dlc_list(self, app_id): return self.get_dlc_list(app_id) def run(self): - stellaris_dlc_list = self.get_dlc_list('281990') + # stellaris_dlc_list = self.get_dlc_list('281990') # hoi_dlc_list = self.get_dlc_list('394360') - total_dlcs = len(stellaris_dlc_list) - with open(os.path.join(self.parent_directory, 'creamapi_steam_files', 'cream_api.ini'), 'w', encoding='utf-8') as f: - f.write("; auto created by Stellaris DLC Unlocker\n") - f.write("; Author seuyh\n") - current_datetime = datetime.now().strftime("%d.%m.%Y") - f.write(f"; created {current_datetime}\n") - f.write("; Get DLC Info from api.steamcmd.net\n") - f.write("; Format: CreamAPI v4.5.0.0\n") - f.write(f"; AppID: 281990\n") - f.write(f"; AppID Name: Stellaris\n") - f.write(f"; AppID Total DLCs: {total_dlcs}\n\n") - f.write("[steam]\n") - f.write(f"appid = 281990\n") - f.write("orgapi64 = steam_api64_org_game.dll\n\n") - f.write("[steam_misc]\n") - f.write("; Disables the internal SteamUser interface handler.\n") - f.write("; Does have an effect on the games that are using the license check for the DLC/application.\n") - f.write('; Default is "false".') - f.write("disableuserinterface = false\n\n") - f.write("[dlc]\n") - f.write("; DLC handling.\n") - f.write("; Format: = \n") - f.write("; If the DLC is not specified in this section\n") - f.write("; then it won't be unlocked\n") - current_dlc = 0 - dlcs = [] - for dlc_id in stellaris_dlc_list: - dlc_name = self.get_dlc_name(dlc_id) - dlcs.append(f"{dlc_id} = {dlc_name}\n") - f.write(f"{dlc_id} = {dlc_name}\n") - current_dlc += 1 - progress = int(round(current_dlc / total_dlcs, 2) * 100) - if progress >= 100: - progress = 99 - # self.progress_callback(progress) - self.progress_signal.emit(progress) - # self.dlc_callback(dlc_name) - dlc_str = f'{current_dlc}/{total_dlcs} {dlc_name}' - self.dlc_signal.emit(dlc_str) - # f.write("; HOI IV DlS\n") - # for dlc_id in hoi_dlc_list: - # dlc_name = self.get_dlc_name(dlc_id) - # f.write(f"{dlc_id} = {dlc_name}\n") - # current_dlc += 1 - # progress = int(round(current_dlc / total_dlcs, 2) * 100) - # if progress > 100: - # progress = 100 - # # self.progress_callback(progress) - # self.progress_signal.emit(progress) - # # self.dlc_callback(dlc_name) - # self.dlc_signal.emit(dlc_name) + # total_dlcs = len(stellaris_dlc_list) + # with open(os.path.join(self.parent_directory, 'creamapi_steam_files', 'cream_api.ini'), 'w', + # encoding='utf-8') as f: + # f.write("; auto created by Stellaris DLC Unlocker\n") + # f.write("; Author seuyh\n") + # current_datetime = datetime.now().strftime("%d.%m.%Y") + # f.write(f"; created {current_datetime}\n") + # f.write("; Get DLC Info from api.steamcmd.net\n") + # f.write("; Format: CreamAPI v4.5.0.0\n") + # f.write(f"; AppID: 281990\n") + # f.write(f"; AppID Name: Stellaris\n") + # f.write(f"; AppID Total DLCs: {total_dlcs}\n\n") + # f.write("[steam]\n") + # f.write(f"appid = 281990\n") + # f.write("orgapi64 = steam_api64_org_game.dll\n\n") + # f.write("[steam_misc]\n") + # f.write("; Disables the internal SteamUser interface handler.\n") + # f.write("; Does have an effect on the games that are using the license check for the DLC/application.\n") + # f.write('; Default is "false".') + # f.write("disableuserinterface = false\n\n") + # f.write("[dlc]\n") + # f.write("; DLC handling.\n") + # f.write("; Format: = \n") + # f.write("; If the DLC is not specified in this section\n") + # f.write("; then it won't be unlocked\n") + # current_dlc = 0 + # dlcs = [] + # for dlc_id in stellaris_dlc_list: + # dlc_name = self.get_dlc_name(dlc_id) + # dlcs.append(f"{dlc_id} = {dlc_name}\n") + # f.write(f"{dlc_id} = {dlc_name}\n") + # current_dlc += 1 + # progress = int(round(current_dlc / total_dlcs, 2) * 100) + # if progress >= 100: + # progress = 99 + # # self.progress_callback(progress) + # self.progress_signal.emit(progress) + # # self.dlc_callback(dlc_name) + # dlc_str = f'{current_dlc}/{total_dlcs} {dlc_name}' + # self.dlc_signal.emit(dlc_str) + # f.write("; HOI IV DlS\n") + # for dlc_id in hoi_dlc_list: + # dlc_name = self.get_dlc_name(dlc_id) + # f.write(f"{dlc_id} = {dlc_name}\n") + # current_dlc += 1 + # progress = int(round(current_dlc / total_dlcs, 2) * 100) + # if progress > 100: + # progress = 100 + # # self.progress_callback(progress) + # self.progress_signal.emit(progress) + # # self.dlc_callback(dlc_name) + # self.dlc_signal.emit(dlc_name) + dlc_list = self.get_dlc_list(281990) + self.check_and_update_dlc_list(dlc_list, + os.path.join(self.parent_directory, 'creamapi_steam_files', 'cream_api.ini')) + self.progress_signal.emit(50) + self.check_and_update_dlc_list(dlc_list, + os.path.join(self.parent_directory, 'creamapi_launcher_files', 'cream_api.ini')) + self.progress_signal.emit(100) + # self.launcher_creamapi(dlcs) - self.launcher_creamapi(dlcs) + # def launcher_creamapi(self, dlcs): + # with open(os.path.join(self.parent_directory, 'creamapi_launcher_files', 'cream_api.ini'), 'w', + # encoding='utf-8') as f: + # current_datetime = datetime.now().strftime("%d.%m.%Y") + # f.write(f"; created {current_datetime}\n") + # f.write("[steam]\n") + # f.write("; Application ID (http://store.steampowered.com/app/%appid%/)\n") + # f.write("appid = 281990\n") + # f.write("; Current game language.\n") + # f.write("; Uncomment this option to turn it on.\n") + # f.write("; Default is \"english\".\n") + # f.write(";language = german\n") + # f.write("; Enable/disable automatic DLC unlock. Default option is set to \"false\".\n") + # f.write("; Keep in mind that this option WON'T work properly if the \"[dlc]\" section is NOT empty\n") + # f.write("unlockall = false\n") + # f.write("; Original Valve's steam_api.dll.\n") + # f.write("; Default is \"steam_api_o.dll\".\n") + # f.write("orgapi = steam_api_o.dll\n") + # f.write("; Original Valve's steam_api64.dll.\n") + # f.write("; Default is \"steam_api64_o.dll\".\n") + # f.write("orgapi64 = steam_api64_o.dll\n") + # f.write("; Enable/disable extra protection bypasser.\n") + # f.write("; Default is \"false\".\n") + # f.write("extraprotection = false\n") + # f.write("; The game will think that you're offline (supported by some games).\n") + # f.write("; Default is \"false\".\n") + # f.write("forceoffline = false\n") + # f.write("; Some games are checking for the low violence presence.\n") + # f.write("; Default is \"false\".\n") + # f.write(";lowviolence = true\n") + # f.write("; Purchase timestamp for the DLC (http://www.onlineconversion.com/unix_time.htm).\n") + # f.write("; Default is \"0\" (1970/01/01).\n") + # f.write(";purchasetimestamp = 0\n\n") + # f.write("[steam_misc]\n") + # f.write("; Disables the internal SteamUser interface handler.\n") + # f.write("; Does have an effect on the games that are using the license check for the DLC/application.\n") + # f.write("; Default is \"false\".\n") + # f.write("disableuserinterface = false\n\n") + # f.write("[dlc]\n") + # f.write("; DLC handling.\n") + # f.write("; Format: = \n") + # f.write("; e.g. : 247295 = Saints Row IV - GAT V Pack\n") + # f.write("; If the DLC is not specified in this section\n") + # f.write("; then it won't be unlocked\n\n") + # for dlc in dlcs: + # f.write(dlc) + # self.progress_signal.emit(100) - def launcher_creamapi(self, dlcs): - with open(os.path.join(self.parent_directory, 'creamapi_launcher_files', 'cream_api.ini'), 'w', encoding='utf-8') as f: - current_datetime = datetime.now().strftime("%d.%m.%Y") - f.write(f"; created {current_datetime}\n") - f.write("[steam]\n") - f.write("; Application ID (http://store.steampowered.com/app/%appid%/)\n") - f.write("appid = 281990\n") - f.write("; Current game language.\n") - f.write("; Uncomment this option to turn it on.\n") - f.write("; Default is \"english\".\n") - f.write(";language = german\n") - f.write("; Enable/disable automatic DLC unlock. Default option is set to \"false\".\n") - f.write("; Keep in mind that this option WON'T work properly if the \"[dlc]\" section is NOT empty\n") - f.write("unlockall = false\n") - f.write("; Original Valve's steam_api.dll.\n") - f.write("; Default is \"steam_api_o.dll\".\n") - f.write("orgapi = steam_api_o.dll\n") - f.write("; Original Valve's steam_api64.dll.\n") - f.write("; Default is \"steam_api64_o.dll\".\n") - f.write("orgapi64 = steam_api64_o.dll\n") - f.write("; Enable/disable extra protection bypasser.\n") - f.write("; Default is \"false\".\n") - f.write("extraprotection = false\n") - f.write("; The game will think that you're offline (supported by some games).\n") - f.write("; Default is \"false\".\n") - f.write("forceoffline = false\n") - f.write("; Some games are checking for the low violence presence.\n") - f.write("; Default is \"false\".\n") - f.write(";lowviolence = true\n") - f.write("; Purchase timestamp for the DLC (http://www.onlineconversion.com/unix_time.htm).\n") - f.write("; Default is \"0\" (1970/01/01).\n") - f.write(";purchasetimestamp = 0\n\n") - f.write("[steam_misc]\n") - f.write("; Disables the internal SteamUser interface handler.\n") - f.write("; Does have an effect on the games that are using the license check for the DLC/application.\n") - f.write("; Default is \"false\".\n") - f.write("disableuserinterface = false\n\n") - f.write("[dlc]\n") - f.write("; DLC handling.\n") - f.write("; Format: = \n") - f.write("; e.g. : 247295 = Saints Row IV - GAT V Pack\n") - f.write("; If the DLC is not specified in this section\n") - f.write("; then it won't be unlocked\n\n") - for dlc in dlcs: - f.write(dlc) - self.progress_signal.emit(100) + def check_and_update_dlc_list(self, dlc_list, path): + with open(path, 'r+') as file: + content = file.read() + for dlc_id in dlc_list: + if str(dlc_id) not in content: + dlc_name = self.get_dlc_name(dlc_id) + file.write(f"\n{dlc_id} = {dlc_name}") diff --git a/gui/main_window.py b/gui/main_window.py index 626d9a7..f0adadf 100644 --- a/gui/main_window.py +++ b/gui/main_window.py @@ -1,19 +1,21 @@ +import json import os +import webbrowser from time import sleep from sys import argv, exit -from PyQt5.QtWidgets import QFileDialog, QMessageBox, QMainWindow, QProgressDialog +from PyQt5.QtWidgets import QFileDialog, QMessageBox, QMainWindow, QProgressDialog, QListWidgetItem, QPushButton from gui.cream_api_maker import CreamAPI from PyQt5.QtCore import Qt -from PyQt5.QtGui import QIcon, QDesktopServices +from PyQt5.QtGui import QIcon, QDesktopServices, QColor -from libs.server_data import gameversion, version, get_remote_file_size, url, server_msg +from libs.server_data import gameversion, version, get_remote_file_size, url, server_msg, dlc_data from libs.game_path import stellaris_path, launcher_path from gui.DownloadThread import DownloaderThread from libs.launcher_reinstall import ReinstallThread from libs.encrypt import decrypt from subprocess import Popen, run, CREATE_NO_WINDOW from zipfile import ZipFile -from shutil import rmtree, copytree +from shutil import copytree from requests import get import ctypes @@ -30,7 +32,7 @@ def __init__(self, language): self.next_button_2.clicked.connect(self.download_file) self.next_button_3.clicked.connect(self.switch_to_next) self.next_button_4.clicked.connect(self.switch_to_next) - self.next_button_5.clicked.connect(self.switch_to_next) + self.next_button_5.clicked.connect(self.minimizeWindow) self.cancel_button.clicked.connect(self.cancel) self.cancel_button_2.clicked.connect(self.cancel) self.cancel_button_3.clicked.connect(self.cancel) @@ -59,7 +61,7 @@ def __init__(self, language): self.now_reinstalling.setVisible(False) self.next_button_5.setEnabled(False) - self.iversion = '0.96' + self.iversion = '0.97' # -------------------------------------------- # @@ -96,7 +98,10 @@ def switch_to_back(self): def updateApplication(self, download_url): old_file = argv[0] + print(f'oldfile: {old_file}') + old_dir = os.path.dirname(old_file) + print(f'old_dir: {old_dir}') pid = ctypes.windll.kernel32.GetCurrentProcessId() error = False @@ -118,14 +123,15 @@ def updateApplication(self, download_url): progress_dialog.setValue(progress) with open('unlocker_updater.bat', 'w') as updater_file: + updater_file.write('chcp 1251 > nul\n') updater_file.write('@echo off\n') updater_file.write(f'taskkill /pid {pid} /f\n') - updater_file.write(f'ping 127.0.0.1 -n 1 > nul\n') + updater_file.write(f'ping 127.0.0.1 -n 3 > nul\n') updater_file.write('echo Updating...\n') updater_file.write(f'del "{old_file}"\n') updater_file.write(f'rename "{old_dir}\\Stellaris-DLC-Unlocker.load" "Stellaris-DLC-Unlocker.exe"\n') updater_file.write(f'start "" "{old_dir}\\Stellaris-DLC-Unlocker.exe"\n') - updater_file.write('ping 127.0.0.1 -n 1 > nul\n') + updater_file.write('ping 127.0.0.1 -n 2 > nul\n') updater_file.write('del %0') except Exception: @@ -143,12 +149,15 @@ def updateApplication(self, download_url): def version_check(self): if float(version) > float(self.iversion): + update_url = f'https://github.com/seuyh/stellaris-dlc-unlocker/releases/tag/{str(version)}' if self.ok_dialog(self.translations.get("update_found_title", ""), self.translations.get("update_found_text", "").format(iversion=self.iversion, - version=version), - QMessageBox.Critical): + version=version, url=update_url), + QMessageBox.Critical, link=update_url): self.updateApplication( f'https://github.com/seuyh/stellaris-dlc-unlocker/releases/download/{str(version)}/Stellaris-DLC-Unlocker.exe') + else: + exit(0) def cancel(self): msg_box = QMessageBox() @@ -163,11 +172,11 @@ def cancel(self): cancel_button.setText('Нет') reply = msg_box.exec_() if reply == QMessageBox.Yes: - try: - if os.path.exists(self.save_path): - os.remove(self.save_path) - except: - pass + # try: + # if os.path.exists(self.save_path): + # os.remove(self.save_path) + # except: + # pass self.close() @staticmethod @@ -243,49 +252,103 @@ def browse_folder(self): def download_file(self): self.game_path = self.path_check().replace("/", "\\") + if not os.path.exists(os.path.join(self.game_path, "dlc")): + os.makedirs(os.path.join(self.game_path, "dlc")) if self.game_path: self.is_downloading = True if self.stackedWidget.currentIndex() != 4: self.stackedWidget.setCurrentIndex(self.stackedWidget.currentIndex() + 1) - file_url = decrypt(url, 'LPrVJDjMXGx1ToihooozyFX4-toGjKcCr8pjZFmq62c=') - self.save_path = os.path.join(self.game_path, 'stellaris_unlocker.zip') - try: - if os.path.exists(self.save_path): - os.remove(self.save_path) - except: - pass - - self.download_thread = DownloaderThread(file_url, self.save_path) - self.download_thread.progress_signal.connect(self.update_progress) - self.download_thread.error_signal.connect(self.show_error) - self.download_thread.speed_signal.connect(self.show_download_speed) - + self.expandWindow() + self.loadDLCNames() self.creamapi_maker = CreamAPI() self.creamapi_maker.progress_signal.connect(self.update_creamapi_progress) - self.creamapi_maker.dlc_signal.connect(self.show_dlc_get_message) + # self.creamapi_maker.dlc_signal.connect(self.show_dlc_get_message) - self.download_thread.start() self.creamapi_maker.start() - self.download_text.setText(self.translations.get("loading", "")) - self.creamapi_label.setText( - self.translations.get("dlc_get", "") + " " + self.translations.get("dlc_get_format", "")) + # self.creamapi_label.setText( + # self.translations.get("dlc_get", "") + " " + self.translations.get("dlc_get_format", "")) + + # with open('dlc_data.json', 'r') as f: + # dlc_data = json.load(f) + self.dlc_count = 0 + self.dlc_downloaded = 0 + self.download_queue = [] + + def start_next_download(): + if self.download_queue: + file_url, save_path = self.download_queue.pop(0) + self.download_thread = DownloaderThread(file_url, save_path, self.dlc_downloaded, self.dlc_count) + self.download_thread.progress_signal.connect(self.update_progress) + self.download_thread.progress_signal_2.connect(self.update_progress_2) + self.download_thread.error_signal.connect(self.show_error) + self.download_thread.text_signal.connect(self.download_text_dlc) + self.download_thread.speed_signal.connect(self.show_download_speed) + self.download_thread.finished.connect(start_next_download) + self.download_thread.start() + + for item in dlc_data: + if 'dlc_folder' in item and item['dlc_folder']: + self.dlc_count += 1 + for dlc in dlc_data: + dlc_folder = dlc['dlc_folder'] + if dlc_folder == '': + continue + url = 'gAAAAABl9aNSiYh_5HauLeXsOl1N-mC843aU8oq6NChQdjhxAvJwXgHibACNJ_4p8jGcLhP8wmy0mDmIr11jNKt3-ZjW6LY1cxex5EC6PNGCXIJUSOECECzIeWTT2SkpxdwzkwKhg4I3' + file_url = f"{decrypt(url, 'LPrVJDjMXGx1ToihooozyFX4-toGjKcCr8pjZFmq62c=')}{dlc_folder}.zip" + save_path = os.path.join(self.game_path, 'dlc', f'{dlc_folder}.zip') + dlc_path = os.path.join(self.game_path, 'dlc', dlc_folder) + self.download_text.setText(self.translations.get("loading", "")) + # file_url = decrypt(url, 'LPrVJDjMXGx1ToihooozyFX4-toGjKcCr8pjZFmq62c=') + # self.save_path = os.path.join(self.game_path, 'stellaris_unlocker.zip') + # try: + # if os.path.exists(self.save_path): + # os.remove(self.save_path) + # except: + # pass + + # self.download_thread = DownloaderThread(file_url, self.save_path) + # self.download_thread.progress_signal.connect(self.update_progress) + # self.download_thread.error_signal.connect(self.show_error) + # self.download_thread.speed_signal.connect(self.show_download_speed) + if not os.path.exists(dlc_path) and (not os.path.exists(save_path) or os.path.getsize(save_path) == 0): + if os.path.exists(save_path) and os.path.getsize(save_path) == 0: + os.remove(save_path) + self.download_queue.append((file_url, save_path)) + + else: + self.dlc_downloaded += 1 + self.update_progress(int((self.dlc_downloaded / self.dlc_count) * 100)) + if self.download_queue: + start_next_download() def update_creamapi_progress(self, value): self.creamapi_progressBar_2.setValue(value) if value == 100: - self.creamapi_label.setText(self.translations.get('done', '')) + # self.creamapi_label.setText(self.translations.get('done', '')) self.download_complete() - def show_dlc_get_message(self, dlc_name): - self.creamapi_label.setText(f"{self.translations.get('dlc_get', '')} {dlc_name}") + # def show_dlc_get_message(self, dlc_name): + # self.creamapi_label.setText(f"{self.translations.get('dlc_get', '')} {dlc_name}") - def update_progress(self, value): + def update_progress(self, value, by_download=False): self.download_progressBar.setValue(value) + if by_download: + self.dlc_downloaded += 1 + self.update_progress(int((self.dlc_downloaded / self.dlc_count) * 100)) + self.loadDLCNames() if value == 100: self.download_text.setText(self.translations.get('done', '')) self.speed_label.setText(f"") + self.update_progress_2(100) + self.download_text_dlc(' ') self.download_complete() + def update_progress_2(self, value): + self.download_progressBar_2.setValue(value) + + def download_text_dlc(self, text): + self.download_text_2.setText(text) + def update_reinstall_progress(self, value): self.reinstall_progress.setValue(value) if value == 33: @@ -300,6 +363,7 @@ def show_download_speed(self, speed): def show_error(self, error_message): # QMessageBox.warning(self, self.translations.get('error', ''), self.translations.get('download_error', '')) + print(error_message) if self.ok_dialog(self.translations.get("error", ""), self.translations.get("download_error", ""), QMessageBox.Critical): @@ -359,15 +423,19 @@ def reinstall_2(self, paradox_folder1): # self.replace_files(os.path.join(os.path.join(paradox_folder1, launcher_folders[0]))) try: self.replace_files(os.path.join(os.path.join(paradox_folder1, launcher_folders[1]))) - except Exception: - pass + except Exception as e: + raise e def replace_files(self, launcher_folder): - try: - rmtree(f'{self.game_path}/dlc') - except Exception: - pass - self.unzip_and_replace() + # try: + # rmtree(f'{self.game_path}/dlc') + # except Exception: + # pass + zip_files = [file for file in os.listdir(os.path.join(self.game_path, 'dlc')) if file.endswith('.zip')] + if zip_files: + for zip_file in zip_files: + self.unzip_and_replace(zip_file) + try: os.remove(f'{launcher_folder}/resources/app/dist/main/steam_api64_o.dll') except: @@ -382,14 +450,15 @@ def replace_files(self, launcher_folder): sleep(1) self.finish_button.setEnabled(True) - def unzip_and_replace(self): - zip_path = self.save_path - extract_folder = self.game_path + def unzip_and_replace(self, dlc_path): + zip_path = os.path.join(self.game_path, 'dlc', dlc_path) + extract_folder = os.path.join(self.game_path, 'dlc') if not os.path.exists(extract_folder): os.makedirs(extract_folder) with ZipFile(zip_path, 'r') as zip_ref: zip_ref.extractall(extract_folder) + os.remove(zip_path) return extract_folder def finish(self): @@ -399,14 +468,45 @@ def finish(self): except: pass - try: - if os.path.exists(self.save_path): - os.remove(self.save_path) - except: - pass + # try: + # if os.path.exists(self.save_path): + # os.remove(self.save_path) + # except: + # pass self.close() + def expandWindow(self): + self.setMaximumSize(720, 330) + self.resize(720, 330) + + def minimizeWindow(self): + self.setMaximumSize(510, 330) + self.resize(510, 330) + self.stackedWidget.setCurrentIndex(self.stackedWidget.currentIndex() + 1) + + def loadDLCNames(self): + self.dlc_list.clear() + # with open(os.path.join(self.parent_directory, 'dlc_data.json'), 'r') as f: + # dlc_data = json.load(f) + + for dlc in dlc_data: + item = QListWidgetItem(dlc['dlc_name']) + status_color = self.checkDLCStatus(dlc['dlc_folder']) + if status_color != 'orange': + item.setBackground(QColor(status_color)) + self.dlc_list.addItem(item) + + def checkDLCStatus(self, dlc_folder): + if not dlc_folder: + return "orange" + dlc_path_folder = os.path.join(self.game_path, "dlc", dlc_folder) + dlc_path_zip = os.path.join(self.game_path, "dlc", f'{dlc_folder}.zip') + if os.path.exists(dlc_path_folder) or os.path.exists(dlc_path_zip): + return "green" + else: + return "red" + def server_msg(self): if server_msg: if self.ok_dialog(self.translations.get('server_msg_title', ''), @@ -414,12 +514,36 @@ def server_msg(self): QMessageBox.Information): pass - @staticmethod - def ok_dialog(title, text, msg_type): + # @staticmethod + # def ok_dialog(title, text, msg_type): + # msg_box = QMessageBox() + # msg_box.setIcon(msg_type) + # msg_box.setWindowTitle(title) + # msg_box.setText(text) + # ok_button = msg_box.addButton(QMessageBox.Ok) + # msg_box.exec_() + # return msg_box.clickedButton() == ok_button + + def ok_dialog(self, title, text, msg_type, link=None): msg_box = QMessageBox() msg_box.setIcon(msg_type) msg_box.setWindowTitle(title) msg_box.setText(text) + ok_button = msg_box.addButton(QMessageBox.Ok) - msg_box.exec_() - return msg_box.clickedButton() == ok_button + open_link_button = None + if link: + open_link_button = QPushButton(self.translations.get('open_link', '')) + msg_box.addButton(open_link_button, QMessageBox.ActionRole) + + def open_link(): + if link: + webbrowser.open(link) + msg_box.reject() + + if open_link_button: + open_link_button.clicked.connect(open_link) + + result = msg_box.exec_() + + return result == QMessageBox.Ok diff --git a/libs/server_data.py b/libs/server_data.py index 49d07fa..bec9c06 100644 --- a/libs/server_data.py +++ b/libs/server_data.py @@ -7,10 +7,13 @@ headers = {'Cache-Control': 'no-cache', 'Pragma': 'no-cache'} try: response = requests.get(url, headers=headers).json() + response_dlc_data = requests.get( + 'https://raw.githubusercontent.com/seuyh/stellaris-dlc-unlocker/main/dlc_data.json', headers=headers).json() gameversion = response["gameversion"] version = response["version"] url = response["url"] server_msg = response["server_msg"] + dlc_data = response_dlc_data except Exception: sys.exit(2) @@ -21,7 +24,7 @@ def get_remote_file_size(url): 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' } response = requests.head(url, headers=headers, verify=False) - size_bytes = int(response.headers.get('content-length', 0))*2 + size_bytes = int(response.headers.get('content-length', 0)) * 2 if size_bytes >= 1024 * 1024: size_str = "{:.2f} MB".format(size_bytes / (1024 * 1024)) elif size_bytes >= 1024: