43 Commits

Author SHA1 Message Date
87174db272 Updated build files
* Removed configs-related stuff

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2025-04-20 22:23:10 +07:00
09530561cf Update setup.py
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2025-04-20 22:14:56 +07:00
0e83537530 Update
* Warning messages have been supplemented

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2025-04-20 22:06:06 +07:00
4601d65909 Update
* Deleted configs-related stuff
* Moved parsing configs to another repository

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2025-04-20 21:57:58 +07:00
8db3700be1 Update requirements
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2025-04-09 21:49:07 +07:00
756e7d823e Optimize interaction with ADR
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2025-04-09 21:41:27 +07:00
13e3e0e1b8 Update
* Improved game checking mechanism
* Some code refactor
* Updated .gitignore

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-12-28 21:31:42 +07:00
2a20b50943 Update requirements.txt (lower lief version)
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-12-06 19:01:40 +07:00
f19a76d95d Fix config editor script
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-12-06 19:00:34 +07:00
dependabot[bot]
f6428d1142 Bump lief from 0.14.0 to 0.15.0 (#5)
Bumps [lief](https://github.com/lief-project/LIEF) from 0.14.0 to 0.15.0.
- [Release notes](https://github.com/lief-project/LIEF/releases)
- [Commits](https://github.com/lief-project/LIEF/compare/0.14.0...0.15.0)

---
updated-dependencies:
- dependency-name: lief
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-30 00:10:40 +07:00
307c6a76e9 Update setup.py
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-09-18 22:59:35 +07:00
dependabot[bot]
b68331d683 Bump certifi from 2023.11.17 to 2024.7.4 (#4)
Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.11.17 to 2024.7.4.
- [Commits](https://github.com/certifi/python-certifi/compare/2023.11.17...2024.07.04)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-06 11:41:17 +07:00
dependabot[bot]
1ad1f536de Bump urllib3 from 2.1.0 to 2.2.2 (#3)
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.1.0 to 2.2.2.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.1.0...2.2.2)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-19 01:35:25 +07:00
89f56be8b2 Proper variable names
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-06-19 01:30:33 +07:00
2b14be3832 Update README.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-06-17 19:14:03 +07:00
6330a0dfa8 Update
* Implemented show_progress_bar and update_progress_bar to interact with progress bars
* Added 3 progress bars to second window
* Imports little optimization

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-06-17 08:26:19 +07:00
e9eef9f785 Fix research all dealers and agencies
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-05-24 20:30:08 +07:00
dependabot[bot]
f989c54664 --- (#2)
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-21 17:36:44 +07:00
2d40c51f9c Update statics.py
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-05-13 19:29:21 +07:00
dependabot[bot]
9223095fe7 Bump idna from 3.6 to 3.7 (#1)
Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst)
- [Commits](https://github.com/kjd/idna/compare/v3.6...v3.7)

---
updated-dependencies:
- dependency-name: idna
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-13 19:23:06 +07:00
b9607db785 Update
* moved call check_remote_hashes into module_parsing

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-05-12 18:00:36 +07:00
bafcb26fbe Update
* added progress dialog when download configs
* updated requirements (again)
* updated .gitignore
* updated second window flags
* warning fixes

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-05-08 23:01:38 +07:00
b8cc20a184 Update
* small README update
* change exec() to exec_()
* added config parsing when app starting up
* setup.py fixes (for cx_Freeze build)
* updated requirements

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-05-08 08:46:59 +07:00
dd238a0ae1 Update DLC_TABLE.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-02-08 16:07:30 +07:00
1afd4b6079 Update README.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-01-13 23:53:36 +07:00
dbcec7a6ed Update module_main/script.py
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2024-01-13 23:53:08 +07:00
70fceee6a2 Update requirements.txt
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-12-29 13:45:54 +07:00
242de815da Update DLC_TABLE.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-12-22 22:11:46 +07:00
c4cf9491d6 Update configs
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-12-01 21:44:59 +07:00
944c79dac0 Update DLC_TABLE.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-12-01 21:33:54 +07:00
33c21c4043 Update build.spec
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-11-12 13:40:30 +07:00
54331abf5a Use CDLL instead of WinDLL to load decrypt library
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-11-12 13:13:46 +07:00
aa071c7ea5 Update DLC_TABLE.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-11-02 18:18:12 +07:00
375e66e989 Update README.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-27 21:09:46 +07:00
59d4f89a96 Update README.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-27 21:08:50 +07:00
d2d814c870 Update README.md
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-27 21:07:11 +07:00
befed61b0c Added table with DLC info
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-27 20:59:28 +07:00
ef36387e05 Update requirements.txt
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-25 23:08:21 +07:00
da25c7bbc4 Update setup.py
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-25 23:05:33 +07:00
e21266970e Remove unused module_choice
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-23 15:20:13 +07:00
a2d4f84877 Automatically check configurations instead of user selection
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-23 14:58:39 +07:00
e7e4939882 Remove unused dlls
Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-23 00:06:12 +07:00
66a571309d Particular revert "Update module_parsing"
This reverts commit 78141ae9aa.

Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com>
2023-10-22 22:38:22 +07:00
38 changed files with 471 additions and 1065 deletions

5
.gitignore vendored
View File

@@ -14,7 +14,7 @@
/upx
## Ignore build from cx_Freeze
/prog_build
/app_build
## Ignore build files from PyInstaller
/build
@@ -22,3 +22,6 @@
## Ignore .bak files
*.bak
## Ignore created 'update.cfg' file
update.cfg

View File

@@ -8,21 +8,20 @@
Features:
1. Decrypt file, if save file crypted
2. Check for DLC to the save file
2. Check for DLC to the save file (available DLC listed at [DLC_TABLE.md](https://github.com/JDM170/SaveWizard_configs/blob/main/DLC_TABLE.md))
3. Edit money, experience and loan limit
4. Edit skills
5. Unlock garages, visit cities, unlock dealers and agencies
**This functionality of the program isn't final!**
5. Visit cities, unlock garages, dealers and agencies
***
Requirments to build project:
* Python >=3.5.4
* PyQt5 >=5.6.0
* requests >=2.24.0
* cx_Freeze >=6.0 (or PyInstaller >=3.6)
To build project You need Python 3.10.7 and installed requirements from [requirements.txt](https://github.com/JDM170/SaveWizard/blob/dev/requirements.txt)
Command to convert .ui to .py: ```pyuic5 -x input.ui -o output.py```
Commands to build project:
- cx_Freeze: ```python setup.py build```
- PyInstaller: ```pyinstaller build.spec --clean```
***
#### Since the program is in development, I won't give up help and guidance on my errors in the code.
#### If you've found a bug - please open an issue

View File

@@ -4,8 +4,7 @@ app = Analysis(
['init_main_program.py'],
pathex=['.'],
datas=[
('configs/ats', 'configs/ats'),
('configs/ets2', 'configs/ets2')
('SII_Decrypt.dll', '.')
]
)
cfg = Analysis(
@@ -32,15 +31,6 @@ app_exe = EXE(
strip=False,
console=False
)
app_coll = COLLECT(
app_exe,
app.binaries,
app.zipfiles,
app.datas,
strip=False,
name='app_build'
)
cfg_exe = EXE(
cfg_pyz,
cfg.scripts,
@@ -52,11 +42,16 @@ cfg_exe = EXE(
strip=False,
console=False
)
cfg_coll = COLLECT(
coll = COLLECT(
app_exe,
app.binaries,
app.zipfiles,
app.datas,
cfg_exe,
cfg.binaries,
cfg.zipfiles,
cfg.datas,
strip=False,
name='cfg_build'
name='app_build'
)

View File

@@ -1,77 +0,0 @@
{
"base" : [
"bakersfield",
"carson_city",
"fresno",
"las_vegas",
"los_angeles",
"oxnard",
"redding",
"san_diego",
"san_rafael",
"santa_cruz",
"stockton"
],
"arizona" : [
"phoenix",
"sierra_vista",
"tucson"
],
"new_mexico" : [
"carlsbad_nm",
"farmington",
"roswell",
"santa_fe"
],
"oregon" : [
"bend",
"eugene",
"ontario",
"salem"
],
"washington" : [
"bellingham",
"olympia",
"seattle",
"wenatchee",
"yakima"
],
"utah" : [
"moab",
"price",
"salt_lake",
"st_george"
],
"idaho" : [
"boise",
"coeur_dalene",
"idaho_falls",
"twin_falls"
],
"colorado" : [
"alamosa",
"denver",
"fort_collins"
],
"wyoming" : [
"casper",
"cheyenne",
"rock_springs",
"sheridan"
],
"montana" : [
"great_falls",
"havre",
"helena",
"kalispell"
],
"texas" : [
"corpus_christi",
"dallas",
"el_paso",
"houston",
"huntsville",
"laredo",
"san_antonio"
]
}

View File

@@ -1,96 +0,0 @@
{
"base" : [
"bakersfield",
"elko",
"las_vegas",
"los_angeles",
"oxnard",
"reno",
"sacramento",
"san_diego",
"san_francisc",
"santa_cruz",
"stockton"
],
"arizona" : [
"flagstaff",
"phoenix",
"tucson",
"yuma"
],
"new_mexico" : [
"alamogordo",
"albuquerque",
"farmington",
"hobbs"
],
"oregon" : [
"eugene",
"medford",
"pendleton",
"portland",
"salem"
],
"washington" : [
"bellingham",
"seattle",
"spokane",
"tacoma",
"yakima"
],
"utah" : [
"ogden",
"price",
"provo",
"salina",
"salt_lake",
"st_george",
"vernal"
],
"idaho" : [
"boise",
"idaho_falls",
"lewiston",
"twin_falls"
],
"colorado" : [
"alamosa",
"colorado_spr",
"denver",
"fort_collins",
"grand_juncti",
"montrose",
"pueblo"
],
"wyoming" : [
"casper",
"cheyenne",
"gillette",
"rock_springs"
],
"montana" : [
"billings",
"great_falls",
"helena",
"kalispell",
"missoula"
],
"texas" : [
"abilene",
"amarillo",
"austin",
"corpus_christi",
"dallas",
"el_paso",
"fort_worth",
"houston",
"laredo",
"longview_tx",
"lubbock",
"mcallen",
"odessa",
"san_angelo",
"san_antonio",
"waco"
]
}

View File

@@ -1,12 +0,0 @@
{
"arizona" : "company.volatile.aport_phx.phoenix",
"new_mexico" : "company.volatile.aport_abq.albuquerque",
"oregon" : "company.volatile.aport_pcc.portland",
"washington" : "company.volatile.port_sea.seattle",
"utah" : "company.volatile.gal_oil_sit.price",
"idaho" : "company.volatile.du_farm.nampa",
"colorado" : "company.volatile.aport_den.denver",
"wyoming" : "company.volatile.aml_rail_str.cheyenne",
"montana" : "company.volatile.aport_gtf.great_falls",
"texas" : "company.volatile.ali_car_dlr.austin"
}

View File

@@ -1,130 +0,0 @@
{
"base" : [
"aberdeen",
"berlin",
"bialystok",
"birmingham",
"bremen",
"brno",
"brussel",
"calais",
"debrecen",
"dortmund",
"dover",
"dresden",
"edinburgh",
"frankfurt",
"glasgow",
"graz",
"groningen",
"hamburg",
"hannover",
"innsbruck",
"kassel",
"klagenfurt",
"koln",
"kosice",
"leipzig",
"liege",
"linz",
"liverpool",
"lodz",
"london",
"luxembourg",
"manchester",
"mannheim",
"munchen",
"newcastle",
"nurnberg",
"ostrava",
"pecs",
"plymouth",
"poznan",
"prague",
"sheffield",
"southampton",
"stuttgart",
"swansea",
"szczecin",
"wien",
"zurich"
],
"east" : [
"budapest",
"gdansk",
"krakow",
"szeged",
"warszawa"
],
"scandinavia" : [
"aalborg",
"bergen",
"helsingborg",
"kobenhavn",
"malmo",
"odense",
"oslo",
"stavanger",
"stockholm"
],
"france" : [
"ajaccio",
"bordeaux",
"clermont",
"geneve",
"larochelle",
"lyon",
"marseille",
"metz",
"paris",
"reims",
"rennes",
"toulouse"
],
"italy" : [
"bologna",
"cagliari",
"catania",
"milano",
"napoli",
"pescara",
"roma",
"taranto",
"venezia"
],
"baltic_sea" : [
"daugavpils",
"helsinki",
"kaliningrad",
"kaunas",
"klaipeda",
"kouvola",
"lahti",
"parnu",
"pori",
"pskov",
"riga",
"tallinn",
"turku",
"vilnius"
],
"black_sea" : [
"bucuresti",
"cluj_napoca",
"iasi",
"istanbul",
"plovdiv",
"sofia"
],
"iberia" : [
"bilbao",
"leon",
"lisboa",
"madrid",
"malaga",
"murcia",
"porto",
"valencia",
"zaragoza"
]
}

View File

@@ -1,135 +0,0 @@
{
"base" : [
"aberdeen",
"amsterdam",
"berlin",
"bern",
"birmingham",
"bratislava",
"bremen",
"brussel",
"calais",
"cardiff",
"dortmund",
"dortmund",
"dresden",
"dusseldorf",
"edinburgh",
"felixstowe",
"frankfurt",
"glasgow",
"graz",
"grimsby",
"hamburg",
"hannover",
"leipzig",
"lille",
"london",
"luxembourg",
"manchester",
"munchen",
"newcastle",
"nurnberg",
"osnabruck",
"plymouth",
"prague",
"rostock",
"rotterdam",
"salzburg",
"strasbourg",
"stuttgart",
"szczecin",
"wien",
"wroclaw",
"zurich"
],
"east" : [
"budapest",
"gdansk",
"krakow",
"szeged",
"warszawa"
],
"scandinavia" : [
"bergen",
"goteborg",
"kalmar",
"kobenhavn",
"linkoping",
"oslo",
"stockholm"
],
"france" : [
"ajaccio",
"bayonne",
"bordeaux",
"bourges",
"brest",
"geneve",
"lemans",
"limoges",
"lyon",
"marseille",
"nantes",
"paris",
"toulouse"
],
"italy" : [
"bologna",
"cagliari",
"catania",
"firenze",
"milano",
"napoli",
"palermo",
"roma",
"sassari",
"taranto",
"torino",
"verona"
],
"baltic_sea" : [
"helsinki",
"kaliningrad",
"kaunas",
"klaipeda",
"lahti",
"petersburg",
"riga",
"tallinn",
"tartu",
"turku",
"vilnius"
],
"black_sea" : [
"brasov",
"bucuresti",
"cluj_napoca",
"constanta",
"edirne",
"galati",
"iasi",
"istanbul",
"pitesti",
"plovdiv",
"sofia",
"veliko_tarnovo"
],
"iberia" : [
"albacete",
"almeria",
"badajoz",
"barcelona",
"burgos",
"cordoba",
"gijon",
"leon",
"lisboa",
"madrid",
"malaga",
"porto",
"sevilla",
"valladolid",
"zaragoza"
]
}

View File

@@ -1,9 +0,0 @@
{
"east" : "company.volatile.quarry.katowice",
"scandinavia" : "company.volatile.sag_tre.oslo",
"france" : "company.volatile.lisette_log.roscoff",
"italy" : "company.volatile.marina_it.ancona",
"baltic_sea" : "company.volatile.polarislines.tallinn",
"black_sea" : "company.volatile.bhv.galati",
"iberia" : "company.volatile.tdc_auto.vigo"
}

View File

@@ -1,8 +0,0 @@
{
"ats_dlc": "b8329b3b104e76398a0466a8996d0ec1",
"ats_agencies": "3c4e60c8177ed917bc15fdb7199b0b8a",
"ats_dealers": "a9bd15fc4db8bc1ec64c938192b97252",
"ets2_dlc": "d3634f683550d9f9d87ad3c1ff579561",
"ets2_agencies": "cd71f9d0a0b53bbc5c1ae127936455c8",
"ets2_dealers": "c045068fa3fe4eaf3a2cae7b8ec05066"
}

View File

@@ -1,12 +0,0 @@
{
"ats": {
"dlc": "c5f4adb336a6c2a7f1987f00c61c8d48",
"agencies": "7b6eb8747a5b51d5d03869884e4b6e80",
"dealers": "4e3b0d639a6bc85b2e25af2f73656d21"
},
"ets2": {
"dlc": "d3634f683550d9f9d87ad3c1ff579561",
"agencies": "cd71f9d0a0b53bbc5c1ae127936455c8",
"dealers": "c045068fa3fe4eaf3a2cae7b8ec05066"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -9,4 +9,4 @@ if __name__ == '__main__':
app = QApplication(argv)
win = EditorWindow()
win.show()
exit(app.exec())
exit(app.exec_())

View File

@@ -3,10 +3,10 @@
from sys import argv, exit
from PyQt5.QtWidgets import QApplication
from module_choice.script import ChoiceWindow
from module_main.script import MainWindow
if __name__ == '__main__':
app = QApplication(argv)
win = ChoiceWindow()
win = MainWindow()
win.show()
exit(app.exec())
exit(app.exec_())

View File

@@ -1 +0,0 @@
# initialize module 'choice'

View File

@@ -1,107 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>JDM170</author>
<class>Choice</class>
<widget class="QDialog" name="Choice">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>490</width>
<height>130</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>490</width>
<height>130</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>490</width>
<height>130</height>
</size>
</property>
<property name="windowTitle">
<string>Select game</string>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>471</width>
<height>111</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QPushButton" name="ets2_button">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>ETS2</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="ats_button">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>ATS</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>Select the configs you want to use:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>DON'T USE CONFIGS FROM ANOTHER GAME INTENTIONALLY,
YOU CAN DAMAGE THE GAME'S SAVE.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<tabstops>
<tabstop>ats_button</tabstop>
<tabstop>ets2_button</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -1,54 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog, QMessageBox
from ast import literal_eval
from os.path import isfile
from .form import Ui_Choice
from module_main.script import MainWindow
from module_parsing.script import check_remote_hashes, update_configs
from statics import update_config_name
class ChoiceWindow(QDialog, Ui_Choice):
def __init__(self, parent=None):
# Setup UI
QDialog.__init__(self, parent, flags=Qt.Window)
Ui_Choice.__init__(self)
self.ui = Ui_Choice()
self.ui.setupUi(self)
self.ui.ats_button.clicked.connect(self.button_clicked)
self.ui.ets2_button.clicked.connect(self.button_clicked)
remember_data = {"answer_updates": True, "update_on_start": False}
if isfile(update_config_name):
with open(update_config_name, "r") as f:
remember_data = literal_eval(f.read())
upd_list = check_remote_hashes()
if upd_list and len(upd_list) > 0:
if remember_data.get("update_on_start"):
update_configs(upd_list)
return
if remember_data.get("answer_updates"):
box = QMessageBox(QMessageBox.Information, "Info",
"Some configs have been updated. Do you want to update the local configs?")
box.addButton("Yes", QMessageBox.YesRole) # 0
box.addButton("Yes, remember that", QMessageBox.YesRole) # 1
box.addButton("No", QMessageBox.NoRole) # 2
box.addButton("No, remember that", QMessageBox.NoRole) # 3
update_configs(upd_list, box.exec())
def button_clicked(self):
sender = self.sender()
if sender == self.ui.ats_button:
selected = "ats"
elif sender == self.ui.ets2_button:
selected = "ets2"
else:
return
self.close()
win = MainWindow(selected)
win.exec()

View File

@@ -8,19 +8,19 @@
<x>0</x>
<y>0</y>
<width>360</width>
<height>350</height>
<height>400</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>360</width>
<height>350</height>
<height>400</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>360</width>
<height>350</height>
<height>400</height>
</size>
</property>
<property name="font">
@@ -38,21 +38,11 @@
<x>10</x>
<y>50</y>
<width>341</width>
<height>81</height>
<height>104</height>
</rect>
</property>
<layout class="QGridLayout" name="basic_inf_layout">
<item row="0" column="1">
<widget class="QLineEdit" name="money_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="0" column="2">
<item row="1" column="2">
<widget class="QCheckBox" name="money_dont_change">
<property name="font">
<font>
@@ -65,7 +55,7 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="xp_label">
<property name="font">
<font>
@@ -78,7 +68,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QLineEdit" name="xp_edit">
<property name="font">
<font>
@@ -88,7 +78,17 @@
</property>
</widget>
</item>
<item row="1" column="2">
<item row="1" column="1">
<widget class="QLineEdit" name="money_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="xp_dont_change">
<property name="font">
<font>
@@ -101,20 +101,7 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="loan_limit_label">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Loan limit:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QLineEdit" name="loan_limit_edit">
<property name="font">
<font>
@@ -124,7 +111,7 @@
</property>
</widget>
</item>
<item row="2" column="2">
<item row="3" column="2">
<widget class="QCheckBox" name="loan_limit_dont_change">
<property name="font">
<font>
@@ -137,7 +124,7 @@
</property>
</widget>
</item>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="money_label">
<property name="font">
<font>
@@ -150,6 +137,34 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="loan_limit_label">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Loan limit:</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="basic_inf_label">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Basic info</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QPushButton" name="path_button">
@@ -177,16 +192,16 @@
</property>
<property name="geometry">
<rect>
<x>10</x>
<y>310</y>
<width>141</width>
<x>130</x>
<y>360</y>
<width>111</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>12</pointsize>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
@@ -194,12 +209,15 @@
</property>
</widget>
<widget class="QCheckBox" name="dont_change_all_inf">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>80</x>
<y>350</y>
<y>400</y>
<width>211</width>
<height>31</height>
<height>21</height>
</rect>
</property>
<property name="font">
@@ -211,97 +229,21 @@
<property name="text">
<string>Don't save all changes in this form</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
<widget class="QWidget" name="gridLayoutWidget_3">
<property name="geometry">
<rect>
<x>10</x>
<y>140</y>
<y>160</y>
<width>341</width>
<height>161</height>
<height>191</height>
</rect>
</property>
<layout class="QGridLayout" name="skills_layout">
<item row="1" column="1">
<widget class="QLineEdit" name="long_distance_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="urgent_delivery_label">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Urgent delivery:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QCheckBox" name="ecodriving_dont_change">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Don't change</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="adr_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="urgent_delivery_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="fragile_cargo_dont_change">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Don't change</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="ecodriving_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="high_value_cargo_dont_change">
<property name="font">
<font>
@@ -314,30 +256,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="fragile_cargo_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="adr_dont_change">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Don't change</string>
</property>
</widget>
</item>
<item row="1" column="2">
<item row="2" column="2">
<widget class="QCheckBox" name="long_distance_dont_change">
<property name="font">
<font>
@@ -350,8 +269,8 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="high_value_cargo_edit">
<item row="6" column="1">
<widget class="QLineEdit" name="ecodriving_edit">
<property name="font">
<font>
<family>Times New Roman</family>
@@ -360,33 +279,30 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="high_value_cargo_label">
<item row="1" column="2">
<widget class="QCheckBox" name="adr_dont_change">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>13</pointsize>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>High value cargo:</string>
<string>Don't change</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="fragile_cargo_label">
<item row="4" column="1">
<widget class="QLineEdit" name="fragile_cargo_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>13</pointsize>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Fragile cargo:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="ecodriving_label">
<property name="font">
<font>
@@ -399,7 +315,30 @@
</property>
</widget>
</item>
<item row="4" column="2">
<item row="3" column="0">
<widget class="QLabel" name="high_value_cargo_label">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>High value cargo:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="high_value_cargo_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QCheckBox" name="urgent_delivery_dont_change">
<property name="font">
<font>
@@ -412,7 +351,20 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="4" column="0">
<widget class="QLabel" name="fragile_cargo_label">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Fragile cargo:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="long_distance_label">
<property name="font">
<font>
@@ -425,7 +377,7 @@
</property>
</widget>
</item>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="adr_label">
<property name="font">
<font>
@@ -438,6 +390,90 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="urgent_delivery_label">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Urgent delivery:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="long_distance_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="urgent_delivery_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QCheckBox" name="fragile_cargo_dont_change">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Don't change</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QCheckBox" name="ecodriving_dont_change">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Don't change</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="adr_edit">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="skills_label">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Skills</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QPushButton" name="apply">
@@ -446,16 +482,16 @@
</property>
<property name="geometry">
<rect>
<x>210</x>
<y>310</y>
<width>141</width>
<x>250</x>
<y>360</y>
<width>101</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>12</pointsize>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
@@ -468,49 +504,37 @@
</property>
<property name="geometry">
<rect>
<x>160</x>
<y>320</y>
<width>41</width>
<height>21</height>
<x>10</x>
<y>360</y>
<width>111</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>...</string>
<string>Unlock garages</string>
</property>
</widget>
<widget class="QLabel" name="chosen_cfgs">
<widget class="QCheckBox" name="updates_checkbox">
<property name="geometry">
<rect>
<x>210</x>
<x>180</x>
<y>10</y>
<width>141</width>
<width>181</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Chosen configs:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QPushButton" name="cfg_button">
<property name="geometry">
<rect>
<x>180</x>
<y>20</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>...</string>
<string>Check updates on startup</string>
</property>
</widget>
</widget>
<tabstops>
<tabstop>path_button</tabstop>
<tabstop>cfg_button</tabstop>
<tabstop>money_edit</tabstop>
<tabstop>money_dont_change</tabstop>
<tabstop>xp_edit</tabstop>
@@ -529,8 +553,8 @@
<tabstop>urgent_delivery_dont_change</tabstop>
<tabstop>ecodriving_edit</tabstop>
<tabstop>ecodriving_dont_change</tabstop>
<tabstop>backup</tabstop>
<tabstop>second_window</tabstop>
<tabstop>backup</tabstop>
<tabstop>apply</tabstop>
<tabstop>dont_change_all_inf</tabstop>
</tabstops>

View File

@@ -1,37 +1,49 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from ast import literal_eval
from ctypes import CDLL
from os import getcwd, remove
from os.path import isfile
from ctypes import WinDLL
from PyQt5.QtCore import Qt, QRegExp
from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QRegExpValidator
from PyQt5.QtWidgets import QDialog, QFileDialog
from .form import Ui_MainWindow
from util import *
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, selected_game, parent=None):
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 = selected_game
self.selected_game = ""
self.owns = {}
self.dlc = {}
# Editing label to show what configs chosen
self.chosen_cfg_text = self.ui.chosen_cfgs.text()
self.ui.chosen_cfgs.setText("{} {}".format(self.chosen_cfg_text, selected_game.upper()))
# Storing edits with his checkboxes and file-lines
self.basic_edits = {
self.ui.money_edit: [self.ui.money_dont_change, "money_account:"],
@@ -64,12 +76,11 @@ class MainWindow(QDialog, Ui_MainWindow):
# Connecting buttons
self.ui.path_button.clicked.connect(self.open_file_dialog)
self.ui.cfg_button.clicked.connect(self.change_configs)
self.ui.backup.clicked.connect(self.recover_backup)
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.check_config()
self.clear_form_data()
def text_edited(self):
@@ -90,19 +101,16 @@ class MainWindow(QDialog, Ui_MainWindow):
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))
"functionality has been limited.\n"
"Updating configs may solve problem.".format(self.selected_game))
else:
self.owns = {}
self.dlc = dataIO.load_json(cfg_path)
@@ -112,8 +120,9 @@ class MainWindow(QDialog, Ui_MainWindow):
self.old_file = ""
util.set_lines([])
if self.owns is not False:
self.owns = {}
self.selected_game = ""
self.owns = {}
self.dlc = {}
for key, value in self.basic_edits.items():
key.setText("")
@@ -130,10 +139,9 @@ class MainWindow(QDialog, Ui_MainWindow):
self.ui.second_window.setEnabled(False)
def get_file_data(self, file_path):
sii_lib = WinDLL("{}\SII_Decrypt.dll".format(getcwd()))
bytes_file_path = file_path.replace("/", "\\").encode("utf-8")
if sii_lib.GetFileFormat(bytes_file_path) == 2:
if sii_lib.DecryptAndDecodeFile(bytes_file_path, bytes_file_path) != 0:
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
@@ -141,6 +149,14 @@ class MainWindow(QDialog, Ui_MainWindow):
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:"))
@@ -151,12 +167,7 @@ class MainWindow(QDialog, Ui_MainWindow):
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)
self.ui.adr_edit.setText(",".join(self.get_adr(util.get_value(util.search_line("adr:")))))
for key, value in self.skill_edits.items():
key.setText(util.get_value(util.search_line(value[1])))
@@ -169,22 +180,18 @@ class MainWindow(QDialog, Ui_MainWindow):
caption=self.tr("Choose your save file..."),
filter=self.tr("game.sii"))
self.clear_form_data()
if file_path != "":
self.file_path = file_path
self.get_file_data(file_path)
else:
if file_path == "":
return
self.file_path = file_path
self.get_file_data(file_path)
def change_configs(self):
box = QMessageBox(QMessageBox.Warning, "Warning", "Do you really want to load other configs?\n"
"Your current changes won't be saved.")
box.addButton("Yes", QMessageBox.YesRole)
box.addButton("No", QMessageBox.NoRole)
if box.exec() == 0:
self.clear_form_data()
self.selected_game = "ets2" if self.selected_game == "ats" else "ats"
self.ui.chosen_cfgs.setText("{} {}".format(self.chosen_cfg_text, self.selected_game.upper()))
self.check_config()
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"
@@ -198,29 +205,26 @@ class MainWindow(QDialog, Ui_MainWindow):
QMessageBox.information(self, "Success", "Backup successfully recovered.")
self.get_file_data(self.file_path)
def open_second_win(self):
second_win = SecondWindow(self.selected_game, self.owns, self)
second_win.exec()
def apply_changes(self):
if not self.ui.dont_change_all_inf.isChecked():
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)
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 = [i for i in list(self.ui.adr_edit.text()) if i not in (' ', ',', '.')]
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)

View File

@@ -1,18 +1,20 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from requests import get
from ast import literal_eval
import os
from statics import github_link, update_config_name
from ast import literal_eval
from requests import get
from dataIO import dataIO
from statics import github_link
from util import util
def get_response_result(url):
"""
Getting the result from a given url
:param url: url where we get data
:param url: place where we get data
:return: status code (True or False), response body
"""
response = get(url)
@@ -26,7 +28,7 @@ def check_path(path):
"""
current_path = os.getcwd()
for item in path.split("/"):
current_path = os.path.join(current_path, item)
current_path = os.path.join(str(current_path), item)
if not os.path.exists(current_path):
if item.find(".json") > 0:
open(current_path, "w").close()
@@ -35,33 +37,30 @@ def check_path(path):
def check_remote_hashes():
# response_status, response = get_response_result(github_link + "configs/version.cfg")
response_status, response = get_response_result(github_link + "configs/version_new.cfg")
response_status, response = get_response_result(github_link + "version.cfg")
if response_status:
remote_cfg = literal_eval(response.text)
need_update = []
for game, cfg in remote_cfg.items():
for f_name, f_hash in cfg.items():
path = "configs/{}/{}.json".format(game, f_name)
if util.generate_md5(path) != f_hash:
need_update.append(path)
for key, value in remote_cfg.items():
path = key.split("_")
path = "configs/{}/{}.json".format(path[0], path[1])
if util.generate_md5(path) != value:
need_update.append(path)
return need_update
return False
def update_configs(cfg_list, ans_upd=0):
"""
:param cfg_list: config list to update
:param ans_upd: ask user to update configs, update or not, remember answer or not
"""
if ans_upd in (0, 1):
for cfg in cfg_list:
check_path(cfg)
response_status, response = get_response_result(github_link + cfg)
if response_status:
remote_cfg = literal_eval(response.text)
if dataIO.is_valid_json(cfg) or os.path.exists(cfg):
dataIO.save_json(cfg, remote_cfg)
if ans_upd in (1, 3):
with open(update_config_name, "w") as f:
f.write(str({"answer_updates": ans_upd == 3, "update_on_start": ans_upd == 1}))
def update_configs():
update_list = check_remote_hashes()
if not update_list or len(update_list) == 0:
return
progress_bar = util.show_progress_bar("Download progress", "Downloading configs", len(update_list))
for cfg in update_list:
check_path(cfg)
response_status, response = get_response_result(github_link + cfg.replace("configs/", ""))
if response_status:
remote_cfg = literal_eval(response.text)
if dataIO.is_valid_json(cfg) or os.path.exists(cfg):
dataIO.save_json(cfg, remote_cfg)
util.update_progress_bar(progress_bar)
util.update_progress_bar(progress_bar, len(update_list))

View File

@@ -1,7 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog
from .form import Ui_SecondWindow
from util import *
@@ -17,73 +16,77 @@ garages_stat = {
class SecondWindow(QDialog, Ui_SecondWindow):
def __init__(self, selected_game, owns_list, parent=None):
# Setup UI
QDialog.__init__(self, parent, flags=Qt.Window)
QDialog.__init__(self, parent, flags=(Qt.Window | Qt.WindowTitleHint | Qt.WindowCloseButtonHint))
Ui_SecondWindow.__init__(self)
self.ui = Ui_SecondWindow()
self.ui.setupUi(self)
self.owns = owns_list # From main window
# Checking config files
if selected_game is not None:
cfg_path = "configs/{}".format(selected_game)
dealers_path = "{}/dealers.json".format(cfg_path)
if dataIO.is_valid_json(dealers_path) is False:
self.dealers = False
self.ui.dealer_edit.setEnabled(False)
self.ui.dealer_add.setEnabled(False)
self.ui.dealer_add_all.setEnabled(False)
QMessageBox.warning(self, "Warning", "'dealers.json' from '{}' have errors or not found.\n"
"Dealers editing has been disabled.\n"
"Updating configs may solve problem.".format(selected_game))
else:
self.dealers = []
self.dealers_file = dataIO.load_json(dealers_path)
# Checking files
cfg_path = "configs/{}".format(selected_game)
dealers_path = "{}/dealers.json".format(cfg_path)
agencies_path = "{}/agencies.json".format(cfg_path)
if dataIO.is_valid_json(dealers_path) is False:
self.dealers = False
self.ui.dealer_edit.setEnabled(False)
self.ui.dealer_add.setEnabled(False)
self.ui.dealer_add_all.setEnabled(False)
QMessageBox.warning(self, "Warning", "'dealers.json' from '{}' have errors or not found.\n"
"Dealers editing has been disabled".format(selected_game))
else:
self.dealers = []
self.dealers_file = dataIO.load_json(dealers_path)
if dataIO.is_valid_json(agencies_path) is False:
self.agencies = False
self.ui.agency_edit.setEnabled(False)
self.ui.agency_add.setEnabled(False)
self.ui.agency_add_all.setEnabled(False)
QMessageBox.warning(self, "Warning", "'agencies.json' from '{}' have errors or not found.\n"
"Agencies editing has been disabled".format(selected_game))
else:
self.agencies = []
self.agencies_file = dataIO.load_json(agencies_path)
agencies_path = "{}/agencies.json".format(cfg_path)
if dataIO.is_valid_json(agencies_path) is False:
self.agencies = False
self.ui.agency_edit.setEnabled(False)
self.ui.agency_add.setEnabled(False)
self.ui.agency_add_all.setEnabled(False)
QMessageBox.warning(self, "Warning", "'agencies.json' from '{}' have errors or not found.\n"
"Agencies editing has been disabled.\n"
"Updating configs may solve problem.".format(selected_game))
else:
self.agencies = []
self.agencies_file = dataIO.load_json(agencies_path)
self.ui.garage_size.addItem("Small")
self.ui.garage_size.addItem("Medium")
self.ui.garage_size.addItem("Big")
# Dealers and agencies properties for 'ADD' button
self.add_da_dict = {
self.ui.dealer_add: [
self.ui.dealer_edit,
"unlocked_dealers:",
self.dealers,
"Dealership",
self.check_dealers
self.da_statics = {
"dealer": [
self.dealers, # city_list
"unlocked_dealers:", # line_to_search
self.check_dealers, # check_func
],
self.ui.agency_add: [
self.ui.agency_edit,
"unlocked_recruitments:",
self.agencies,
"Recruitment agency",
self.check_agencies
"agency": [
self.agencies, # city_list
"unlocked_recruitments:", # line_to_search
self.check_agencies, # check_func
],
}
# Dealers and agencies properties for 'ADD ALL' button
self.add_all_da_dict = {
self.add_da_handlers = {
self.ui.dealer_add: [
"dealer",
self.ui.dealer_edit, # city_to_add
"Dealership", # message_variable
],
self.ui.dealer_add_all: [
self.dealers,
"unlocked_dealers:",
"All dealerships unlocked.",
self.check_dealers
"dealer",
"All dealerships unlocked.", # success_message
"Visiting dealers", # progress_message
],
self.ui.agency_add: [
"agency",
self.ui.agency_edit, # city_to_add
"Recruitment agency", # message_variable
],
self.ui.agency_add_all: [
self.agencies,
"unlocked_recruitments:",
"All recruitment agencies unlocked.",
self.check_agencies
"agency",
"All recruitment agencies unlocked.", # success_message
"Visiting agencies", # progress_message
],
}
@@ -96,14 +99,13 @@ class SecondWindow(QDialog, Ui_SecondWindow):
self.ui.city_add_all.clicked.connect(self.add_all_cities)
self.ui.dealer_add.clicked.connect(self.add_da_clicked)
self.ui.agency_add.clicked.connect(self.add_da_clicked)
# self.ui.dealer_add_all.clicked.connect(self.add_all_dealers)
# self.ui.agency_add_all.clicked.connect(self.add_all_agencies)
self.ui.dealer_add_all.clicked.connect(self.add_all_da_clicked)
self.ui.agency_add_all.clicked.connect(self.add_all_da_clicked)
if self.owns:
self.fill_list(self.owns, self.dealers, self.dealers_file)
self.fill_list(self.owns, self.agencies, self.agencies_file)
if isinstance(owns_list, dict):
self.fill_list(owns_list, self.dealers, self.dealers_file)
self.fill_list(owns_list, self.agencies, self.agencies_file)
# Checking save-file
self.check_cities()
self.check_dealers()
@@ -146,8 +148,8 @@ class SecondWindow(QDialog, Ui_SecondWindow):
array.append(value)
def check_garage_size(self):
stat = garages_stat[self.ui.garage_size.currentText()]
return str(stat[0]), stat[1]
status_id, size = garages_stat[self.ui.garage_size.currentText()]
return str(status_id), size
def check_garages(self):
self.ui.garages_text.clear()
@@ -225,11 +227,14 @@ class SecondWindow(QDialog, Ui_SecondWindow):
QMessageBox.critical(self, "Error", "You've already visited \"{}\".".format(city))
def add_all_cities(self):
all_cities = self.all_cities()
visited_cities = util.get_array_items(util.search_line("visited_cities:"))
for city in self.all_cities():
progress = util.show_progress_bar("Visiting cities", "Visiting cities", len(all_cities)-len(visited_cities))
for city in all_cities:
if city not in visited_cities:
util.add_array_value(util.search_line("visited_cities:"), city)
util.add_array_value(util.search_line("visited_cities_count:"), "1")
util.update_progress_bar(progress)
QMessageBox.information(self, "Success", "All cities successfully visited.")
self.check_cities()
@@ -243,15 +248,6 @@ class SecondWindow(QDialog, Ui_SecondWindow):
self.ui.dealerships_text.append(dealer)
self.ui.dealerships_text.scrollToAnchor(visited_dealers[0])
# def add_all_dealers(self):
# all_cities = self.all_cities()
# visited_dealers = util.get_array_items(util.search_line("unlocked_dealers:"))
# for dealer in self.dealers:
# if dealer in all_cities and dealer not in visited_dealers:
# util.add_array_value(util.search_line("unlocked_dealers:"), dealer)
# QMessageBox.information(self, "Success", "All dealerships unlocked.")
# self.check_dealers()
def check_agencies(self):
self.ui.agencies_text.clear()
visited_agencies = util.get_array_items(util.search_line("unlocked_recruitments:"))
@@ -262,25 +258,17 @@ class SecondWindow(QDialog, Ui_SecondWindow):
self.ui.agencies_text.append(agency)
self.ui.agencies_text.scrollToAnchor(visited_agencies[0])
# def add_all_agencies(self):
# all_cities = self.all_cities()
# visited_agencies = util.get_array_items(util.search_line("unlocked_recruitments:"))
# for agency in self.agencies:
# if agency in all_cities and agency not in visited_agencies:
# util.add_array_value(util.search_line("unlocked_recruitments:"), agency)
# QMessageBox.information(self, "Success", "All recruitment agencies unlocked.")
# self.check_agencies()
def add_da_clicked(self):
da_arr = self.add_da_dict.get(self.sender())
da_arr = self.add_da_handlers.get(self.sender())
if da_arr is None:
return
edit, line_to_search, city_list, message_variable, check_func = da_arr
city_element = edit.text().lower()
static_key, city_to_add, message_variable = da_arr
city_list, line_to_search, check_func = self.da_statics.get(static_key)
city_element = city_to_add.text().lower()
if not city_element:
QMessageBox.critical(self, "Error", "Enter city name!")
return
edit.setText("")
city_to_add.setText("")
if city_element not in city_list:
QMessageBox.critical(self, "Error", "There is no {} in that city.".format(message_variable.lower()))
elif city_element in util.get_array_items(util.search_line(line_to_search)):
@@ -293,15 +281,18 @@ class SecondWindow(QDialog, Ui_SecondWindow):
check_func()
def add_all_da_clicked(self):
da_arr = self.add_all_da_dict.get(self.sender())
da_arr = self.add_da_handlers.get(self.sender())
if da_arr is None:
return
city_list, line_to_search, success_message, check_func = da_arr
static_key, success_message, progress_message = da_arr
cities_to_unlock, line_to_search, check_func = self.da_statics.get(static_key)
all_cities = self.all_cities()
array_line = util.search_line(line_to_search)
visited = util.get_array_items(array_line)
for element in city_list:
if element in all_cities and not element not in visited:
unlocked_cities = util.get_array_items(array_line)
progress = util.show_progress_bar(progress_message, progress_message, len(all_cities)-len(unlocked_cities))
for element in cities_to_unlock:
if (element not in unlocked_cities) and (element in all_cities):
util.add_array_value(array_line, element)
util.update_progress_bar(progress)
QMessageBox.information(self, "Success", success_message)
check_func()

View File

@@ -1,4 +1,21 @@
PyQt5>=5.4.0
requests>=2.24.0
cx-Freeze>=6.0
pyinstaller>=3.6
altgraph==0.17.4
cabarchive==0.2.4
certifi==2024.7.4
charset-normalizer==3.3.2
cx-Logging==3.1.0
cx_Freeze==8.0.0
filelock==3.18.0
idna==3.7
lief==0.15.0
packaging==24.2
pefile==2023.2.7
pyinstaller==6.3.0
pyinstaller-hooks-contrib==2023.11
PyQt5==5.15.10
PyQt5-Qt5==5.15.2
PyQt5-sip==12.13.0
pywin32-ctypes==0.2.2
requests==2.32.0
striprtf==0.0.29
tomli==2.2.1
urllib3==2.2.2

View File

@@ -13,8 +13,8 @@ executables = [
Executable('init_config_editor.py', target_name='SaveWizard_Config_Editor.exe', base=base)
]
excludes = ['html', 'pydoc_data', 'unittest', 'xml', 'pwd', 'shlex', 'platform', 'webbrowser', 'pydoc', 'tty',
'inspect', 'doctest', 'plistlib', 'subprocess', 'bz2', '_strptime', 'dummy_threading']
excludes = ['html', 'pydoc_data', 'unittest', 'xml', 'pwd', 'shlex', 'platform', 'webbrowser', 'pydoc',
'tty', 'doctest', 'plistlib', 'subprocess', 'bz2', '_strptime', 'dummy_threading']
includes = ['pkgutil', 'enum', 'queue']
@@ -24,19 +24,14 @@ zip_include_packages = [
'calendar', 'urllib', 'posixpath', 'tempfile', 'shutil', 'copy', 'stringprep', 'socket', 'ast', 'ssl', 'ctypes',
# PyQt5
'PyQt5',
# Modules for parsing cfg's
'requests', 'logging', 'certifi', 'chardet', 'idna', 'urllib3',
# Modules for parsing configs
'requests', 'logging', 'certifi', 'chardet', 'idna', 'urllib3', 'inspect',
# Self-written modules
'module_parsing', 'module_choice', 'module_main', 'module_second', 'module_config_editor'
'module_parsing', 'module_main', 'module_second', 'module_config_editor'
]
include_files = [
# 'dlls/imageformats',
# 'dlls/platforms',
# 'dlls/styles',
'SII_Decrypt.dll',
('configs/ats', 'configs/ats'),
('configs/ets2', 'configs/ets2')
'SII_Decrypt.dll'
]
options = {
@@ -44,7 +39,7 @@ options = {
'excludes': excludes,
'includes': includes,
'include_msvcr': True,
'build_exe': 'prog_build',
'build_exe': 'app_build',
'include_files': include_files,
'zip_include_packages': zip_include_packages,
}
@@ -52,8 +47,8 @@ options = {
setup(
name='SaveWizard',
version='1.4',
description='For editing ETS2 sii files',
version='1.5',
description='Tool for edit ATS and ETS2 save files',
executables=executables,
options=options,
requires=['PyQt5', 'requests'],

View File

@@ -2,5 +2,5 @@
# -*- coding: utf-8 -*-
update_config_name = "update.cfg"
github_link = "https://raw.githubusercontent.com/JDM170/SaveWizard/master/"
github_link = "https://raw.githubusercontent.com/JDM170/SaveWizard_configs/main/"
hash_chunk_size = 4096

22
util.py
View File

@@ -4,7 +4,10 @@
from os.path import isfile
from re import search, match
# from re import search, match, sub
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QMessageBox, QProgressDialog, QApplication
)
from hashlib import md5
from statics import hash_chunk_size
@@ -32,6 +35,23 @@ class CustomFuncs:
hash_md5.update(chunk)
return hash_md5.hexdigest()
@staticmethod
def show_progress_bar(title, text, length):
if (not title) or (not text) or (not length) or (length <= 0):
return
progress_bar = QProgressDialog(text + "...", None, 0, length, flags=Qt.Window | Qt.WindowTitleHint)
progress_bar.setWindowTitle(title)
progress_bar.setWindowModality(Qt.WindowModal)
progress_bar.show()
return progress_bar
@staticmethod
def update_progress_bar(progress_bar, value=1):
if not progress_bar:
return
progress_bar.setValue(progress_bar.value() + value)
QApplication.processEvents()
# Stock functions
def search_line(self, term, start=0, cancel=r"this_string_must_not_exist"):
if search(term, self.lines[start]):