mirror of
https://github.com/JDM170/SaveWizard
synced 2025-04-20 22:30:42 +07:00
* Improved game checking mechanism * Some code refactor * Updated .gitignore Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
246 lines
9.3 KiB
Python
246 lines
9.3 KiB
Python
#!/usr/bin/python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from ast import literal_eval
|
|
from ctypes import CDLL
|
|
from os import getcwd, remove
|
|
|
|
from PyQt5.QtCore import QRegExp
|
|
from PyQt5.QtGui import QRegExpValidator
|
|
from PyQt5.QtWidgets import QDialog, QFileDialog
|
|
|
|
from dataIO import dataIO
|
|
from module_parsing.script import update_configs
|
|
from module_second.script import SecondWindow
|
|
from statics import update_config_name
|
|
from util import *
|
|
from .form import Ui_MainWindow
|
|
|
|
libDecrypt = CDLL("{}\\SII_Decrypt.dll".format(getcwd()))
|
|
|
|
|
|
class MainWindow(QDialog, Ui_MainWindow):
|
|
def __init__(self, parent=None):
|
|
# Setup UI
|
|
QDialog.__init__(self, parent, flags=Qt.Window)
|
|
Ui_MainWindow.__init__(self)
|
|
self.ui = Ui_MainWindow()
|
|
self.ui.setupUi(self)
|
|
|
|
update_cfg = {"update_on_start": False}
|
|
if isfile(update_config_name):
|
|
with open(update_config_name, "r") as f:
|
|
update_cfg = literal_eval(f.read())
|
|
|
|
update_bool = update_cfg.get("update_on_start")
|
|
if update_bool:
|
|
self.ui.updates_checkbox.setChecked(update_bool)
|
|
update_configs()
|
|
|
|
self.file_path = ""
|
|
self.old_file = ""
|
|
|
|
self.selected_game = ""
|
|
self.owns = {}
|
|
self.dlc = {}
|
|
|
|
# Storing edits with his checkboxes and file-lines
|
|
self.basic_edits = {
|
|
self.ui.money_edit: [self.ui.money_dont_change, "money_account:"],
|
|
self.ui.xp_edit: [self.ui.xp_dont_change, "experience_points:"],
|
|
self.ui.loan_limit_edit: [self.ui.loan_limit_dont_change, "loan_limit:"],
|
|
}
|
|
self.skill_edits = {
|
|
self.ui.long_distance_edit: [self.ui.long_distance_dont_change, "long_dist:"],
|
|
self.ui.high_value_cargo_edit: [self.ui.high_value_cargo_dont_change, "heavy:"],
|
|
self.ui.fragile_cargo_edit: [self.ui.fragile_cargo_dont_change, "fragile:"],
|
|
self.ui.urgent_delivery_edit: [self.ui.urgent_delivery_dont_change, "urgent:"],
|
|
self.ui.ecodriving_edit: [self.ui.ecodriving_dont_change, "mechanical:"],
|
|
}
|
|
|
|
# Setting up validators for edits
|
|
basic_validator = QRegExpValidator(QRegExp("[0-9]{,9}"))
|
|
for key in self.basic_edits.keys():
|
|
key.setValidator(basic_validator)
|
|
key.textEdited.connect(self.text_edited)
|
|
|
|
adr_validator_text = ""
|
|
for i in range(6):
|
|
adr_validator_text += r"\d[., ]?" if i != 5 else r"\d"
|
|
self.ui.adr_edit.textEdited.connect(self.text_edited)
|
|
self.ui.adr_edit.setValidator(QRegExpValidator(QRegExp(adr_validator_text)))
|
|
skills_validator = QRegExpValidator(QRegExp("[0-6]{,1}"))
|
|
for key in self.skill_edits.keys():
|
|
key.setValidator(skills_validator)
|
|
key.textEdited.connect(self.text_edited)
|
|
|
|
# Connecting buttons
|
|
self.ui.path_button.clicked.connect(self.open_file_dialog)
|
|
self.ui.updates_checkbox.clicked.connect(self.update_on_startup)
|
|
self.ui.second_window.clicked.connect(self.open_second_win)
|
|
self.ui.backup.clicked.connect(self.recover_backup)
|
|
self.ui.apply.clicked.connect(self.apply_changes)
|
|
|
|
self.clear_form_data()
|
|
|
|
def text_edited(self):
|
|
sender = self.sender()
|
|
if sender in self.basic_edits:
|
|
self.basic_edits[sender][0].setChecked(False)
|
|
if sender == self.ui.adr_edit:
|
|
self.ui.adr_dont_change.setChecked(False)
|
|
if sender in self.skill_edits:
|
|
self.skill_edits[sender][0].setChecked(False)
|
|
|
|
@staticmethod
|
|
def get_adr(value):
|
|
bin_code = bin(int(value))[2:]
|
|
bin_code = "0" * (6 - len(bin_code)) + bin_code
|
|
r = []
|
|
for i in bin_code:
|
|
r.append(i)
|
|
return r
|
|
|
|
def get_adr_from_line(self):
|
|
adr_list = list(self.ui.adr_edit.text())
|
|
for i in adr_list:
|
|
if (i == " ") or (i == ",") or (i == "."):
|
|
adr_list.remove(i)
|
|
return adr_list
|
|
|
|
def check_config(self):
|
|
if self.selected_game is None:
|
|
self.owns = False
|
|
return
|
|
cfg_path = "configs/{}/dlc.json".format(self.selected_game)
|
|
if dataIO.is_valid_json(cfg_path) is False:
|
|
self.owns = False
|
|
QMessageBox.warning(self, "Warning", "'dlc.json' from '{}' have errors or not found, "
|
|
"functionality has been limited".format(self.selected_game))
|
|
else:
|
|
self.owns = {}
|
|
self.dlc = dataIO.load_json(cfg_path)
|
|
|
|
def clear_form_data(self):
|
|
self.file_path = ""
|
|
self.old_file = ""
|
|
util.set_lines([])
|
|
|
|
self.selected_game = ""
|
|
self.owns = {}
|
|
self.dlc = {}
|
|
|
|
for key, value in self.basic_edits.items():
|
|
key.setText("")
|
|
value[0].setChecked(True)
|
|
|
|
self.ui.adr_edit.setText("")
|
|
self.ui.adr_dont_change.setChecked(True)
|
|
for key, value in self.skill_edits.items():
|
|
key.setText("")
|
|
value[0].setChecked(True)
|
|
|
|
self.ui.apply.setEnabled(False)
|
|
self.ui.backup.setEnabled(False)
|
|
self.ui.second_window.setEnabled(False)
|
|
|
|
def get_file_data(self, file_path):
|
|
bytes_file_path = file_path.replace("/", "\\").encode("utf-8")
|
|
if libDecrypt.GetFileFormat(bytes_file_path) == 2:
|
|
if libDecrypt.DecryptAndDecodeFile(bytes_file_path, bytes_file_path) != 0:
|
|
QMessageBox.critical(self, "Error", "Something went wrong with decrypting file. Try again.")
|
|
return
|
|
|
|
with open(file_path) as f:
|
|
self.old_file = f.read()
|
|
util.set_lines(self.old_file.split("\n"))
|
|
|
|
if util.search_line("company.volatile.eurogoodies.dortmund"):
|
|
self.selected_game = "ets2"
|
|
elif util.search_line("company.volatile.ed_mkt.elko"):
|
|
self.selected_game = "ats"
|
|
else:
|
|
self.selected_game = None
|
|
self.check_config()
|
|
|
|
if self.owns is not False:
|
|
self.owns["base"] = True
|
|
companies = util.get_array_items(util.search_line("companies:"))
|
|
for key, value in self.dlc.items():
|
|
if value in companies:
|
|
self.owns[key] = True
|
|
|
|
for key, value in self.basic_edits.items():
|
|
key.setText(util.get_value(util.search_line(value[1])))
|
|
|
|
adr = self.get_adr(util.get_value(util.search_line("adr:")))
|
|
adr_list = ""
|
|
for i in range(6):
|
|
adr_list += adr[i] + "," if i != 5 else adr[i]
|
|
self.ui.adr_edit.setText(adr_list)
|
|
|
|
for key, value in self.skill_edits.items():
|
|
key.setText(util.get_value(util.search_line(value[1])))
|
|
|
|
self.ui.apply.setEnabled(True)
|
|
self.ui.backup.setEnabled(True)
|
|
self.ui.second_window.setEnabled(True)
|
|
|
|
def open_file_dialog(self):
|
|
file_path, file_name = QFileDialog.getOpenFileName(parent=self,
|
|
caption=self.tr("Choose your save file..."),
|
|
filter=self.tr("game.sii"))
|
|
self.clear_form_data()
|
|
if file_path == "":
|
|
return
|
|
self.file_path = file_path
|
|
self.get_file_data(file_path)
|
|
|
|
def update_on_startup(self):
|
|
with open(update_config_name, "w") as f:
|
|
f.write(str({"update_on_start": self.ui.updates_checkbox.isChecked()}))
|
|
|
|
def open_second_win(self):
|
|
second_win = SecondWindow(self.selected_game, self.owns, self)
|
|
second_win.exec_()
|
|
|
|
def recover_backup(self):
|
|
backup_path = self.file_path + ".swbak"
|
|
if not isfile(backup_path):
|
|
QMessageBox.critical(self, "Error", "Backup not found.")
|
|
return
|
|
with open(self.file_path, "w") as current:
|
|
with open(backup_path) as backup:
|
|
current.write(backup.read())
|
|
remove(backup_path)
|
|
QMessageBox.information(self, "Success", "Backup successfully recovered.")
|
|
self.get_file_data(self.file_path)
|
|
|
|
def apply_changes(self):
|
|
if self.ui.dont_change_all_inf.isChecked():
|
|
return
|
|
for key, value in self.basic_edits.items():
|
|
if value[0].isChecked() is False:
|
|
util.set_value(util.search_line(value[1]), key.text())
|
|
value[0].setChecked(True)
|
|
if self.ui.adr_dont_change.isChecked() is False:
|
|
adr_set = self.get_adr_from_line()
|
|
if len(adr_set) < 6:
|
|
QMessageBox.critical(self, "Error", "ADR can't have less than 6 elements.")
|
|
elif len(adr_set) > 6:
|
|
QMessageBox.critical(self, "Error", "ADR can't have more than 6 elements.")
|
|
else:
|
|
adr_new = int("".join(adr_set), 2)
|
|
util.set_value(util.search_line("adr:"), str(adr_new))
|
|
for key, value in self.skill_edits.items():
|
|
if value[0].isChecked() is False:
|
|
util.set_value(util.search_line(value[1]), key.text())
|
|
value[0].setChecked(True)
|
|
backup = self.file_path + ".swbak"
|
|
with open(backup, "w") as f:
|
|
f.write(self.old_file)
|
|
with open(self.file_path, "w") as f:
|
|
f.write("\n".join(util.get_lines()))
|
|
QMessageBox.information(self, "Success", "Changes successfully applied!")
|
|
self.get_file_data(self.file_path)
|