Compare commits

..

No commits in common. "master" and "1.0.0" have entirely different histories.

8 changed files with 37 additions and 64 deletions

View File

@ -1,2 +0,0 @@
kind: template
load: python-gui.starlark

View File

@ -1,22 +0,0 @@
# Giants Wdefs Importer
This tool was created to simplify the process of importing custom Wdefs for Giants 1.502.1.
![Image](readme-img/screenshot.png)
## What it does
This tool:
1. Creates a backup of your game.
2. Downloads the requested wdefs file.
3. Modifies GiantsMain.exe to overwrite the expected CRC value (the game won't load if there is a CRC mismatch).
4. Starts modded Giants.
5. Reverts everything to original state after Giants is closed.
## Where to find modded wdefs?
[Check our Discord server](https://discord.gg/Avj4azU)
## What about cheaters?
Starting 1.497, Giants features a built-in anti-cheat. It works by automatically detecting mismatching clients and kicking them if they don't use the same environment as the server.

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
for ui in *.ui; do for ui in *.ui; do
pyside2-uic $ui > ${ui%.*}.py pyside6-uic $ui > ${ui%.*}.py
done done

30
main.py
View File

@ -1,13 +1,17 @@
import os import os
import struct import struct
import subprocess
import sys import sys
import traceback import traceback
from pathlib import Path from pathlib import Path
import shutil import shutil
import zlib import zlib
import requests import requests
from PySide2.QtCore import QProcess import threading
from PySide2.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox, QPushButton
from PySide6.QtCore import QProcess
from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox, QTreeWidgetItem, QLayout, QLabel, \
QLineEdit, QPushButton
from mainwindow import Ui_MainWindow from mainwindow import Ui_MainWindow
@ -17,10 +21,11 @@ class MainWindow(QMainWindow):
self.ui = Ui_MainWindow() self.ui = Ui_MainWindow()
self.ui.setupUi(self) self.ui.setupUi(self)
self.giants_path = locate_giants_folder() self.giants_path = locate_giants_folder()
if not self.giants_path:
raise Exception()
self.wdefs_path = self.giants_path / "Bin" / "wdefs.bin" self.wdefs_path = self.giants_path / "Bin" / "wdefs.bin"
self.giantsmain_path = self.giants_path / "GiantsMain.exe" self.giantsmain_path = self.giants_path / "GiantsMain.exe"
if not self.giants_path:
self.close()
self.ui.lineEdit.textEdited.connect(self.on_textedit_changed) self.ui.lineEdit.textEdited.connect(self.on_textedit_changed)
self.ui.pushButton.clicked.connect(self.on_button_clicked) self.ui.pushButton.clicked.connect(self.on_button_clicked)
@ -82,13 +87,11 @@ def start_giants_with_wdefs_bytes(wdefs_bytes: bytes, wdefs_path: Path, giantsma
process = QProcess(app) process = QProcess(app)
process.finished.connect(giants_finished) process.finished.connect(giants_finished)
process.setWorkingDirectory(str(giantsmain_path.parent))
btn.setText("Game started") btn.setText("Game started")
if sys.platform == "win32": if sys.platform == "win32":
process.start(str(giantsmain_path), ["-launcher"]) process.start(str(giantsmain_path), ["-launcher"])
else: else:
# Linux only works for me because of this hardcoded value process.setWorkingDirectory(str(giantsmain_path.parent))
# if you want to use my tool, feel free to create a PR to make these values parameterized
process.start("/home/tasty/.local/share/lutris/runners/wine/lutris-6.0-x86_64/bin/wine", ["/home/tasty/Jeux/Giants Citizen Kabuto1.498/GiantsMain.exe", "-window", "-launcher"]) process.start("/home/tasty/.local/share/lutris/runners/wine/lutris-6.0-x86_64/bin/wine", ["/home/tasty/Jeux/Giants Citizen Kabuto1.498/GiantsMain.exe", "-window", "-launcher"])
@ -102,6 +105,7 @@ def backup_file(file_path: Path) -> None:
# copy and append _original to filename # copy and append _original to filename
# if file already exists, skip # if file already exists, skip
dst = str(file_path.parent / file_path.stem) + "_original" + file_path.suffix dst = str(file_path.parent / file_path.stem) + "_original" + file_path.suffix
print(dst)
if os.path.exists(dst): if os.path.exists(dst):
return return
shutil.copy(file_path, dst) shutil.copy(file_path, dst)
@ -138,9 +142,7 @@ def ask_giants_directory() -> Path:
QMessageBox.information(None, "Wdefs", QMessageBox.information(None, "Wdefs",
"Could not locate your Giants installation automatically.\nPlease browse to your Giants folder and select GiantsMain.exe") "Could not locate your Giants installation automatically.\nPlease browse to your Giants folder and select GiantsMain.exe")
giantsmain_path, _filename = QFileDialog.getOpenFileName(None, caption="Wdefs", filter="GiantsMain.exe") giantsmain_path, _filename = QFileDialog.getOpenFileName(None, caption="Wdefs", filter="GiantsMain.exe")
if giantsmain_path:
return Path(giantsmain_path).parent return Path(giantsmain_path).parent
return None
def crc(inp_bytes: bytes) -> int: def crc(inp_bytes: bytes) -> int:
@ -156,7 +158,7 @@ def new_exe_bytes(wdefs_bytes: bytes, giantsmain_path: Path) -> bytes:
index = content.find(CHECKSUM_1_502_0_1) index = content.find(CHECKSUM_1_502_0_1)
if index < 0: if index < 0:
raise Exception("Could not find wdefs checksum in embedded GiantsMain.exe. If you are 100% sure this is unmodded Giants 1.502.1 please report this to Amazed#0001 on Discord or create an issue on the Git project.") raise Exception("Could not find wdefs checksum in embedded GiantsMain.exe. Report this to Amazed#0001")
else: else:
content = bytearray(content) content = bytearray(content)
wdefs_crc = struct.pack("<L", crc(wdefs_bytes)) wdefs_crc = struct.pack("<L", crc(wdefs_bytes))
@ -167,12 +169,6 @@ def new_exe_bytes(wdefs_bytes: bytes, giantsmain_path: Path) -> bytes:
if __name__ == "__main__": if __name__ == "__main__":
app = QApplication(sys.argv) app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(True) app.setQuitOnLastWindowClosed(True)
try:
window = MainWindow() window = MainWindow()
window.show() window.show()
sys.exit(app.exec_()) sys.exit(app.exec())
except SystemExit:
sys.exit(0)
except:
traceback.print_exc()
sys.exit(1)

View File

@ -12,7 +12,7 @@ a = Analysis(['main.py'],
hookspath=[], hookspath=[],
hooksconfig={}, hooksconfig={},
runtime_hooks=[], runtime_hooks=[],
excludes=[], excludes=['PySide6.QtQml'],
win_no_prefer_redirects=False, win_no_prefer_redirects=False,
win_private_assemblies=False, win_private_assemblies=False,
cipher=block_cipher, cipher=block_cipher,
@ -22,23 +22,19 @@ pyz = PYZ(a.pure, a.zipped_data,
exe = EXE(pyz, exe = EXE(pyz,
a.scripts, a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[], [],
exclude_binaries=True,
name='main', name='main',
debug=False, debug=False,
bootloader_ignore_signals=False, bootloader_ignore_signals=False,
strip=False, strip=False,
upx=True, upx=True,
console=True, upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False, disable_windowed_traceback=False,
target_arch=None, target_arch=None,
codesign_identity=None, codesign_identity=None,
entitlements_file=None , icon='icon.ico') entitlements_file=None , icon='icon.ico')
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main')

View File

@ -3,15 +3,21 @@
################################################################################ ################################################################################
## Form generated from reading UI file 'mainwindow.ui' ## Form generated from reading UI file 'mainwindow.ui'
## ##
## Created by: Qt User Interface Compiler version 5.15.2 ## Created by: Qt User Interface Compiler version 6.2.2
## ##
## WARNING! All changes made in this file will be lost when recompiling UI file! ## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################ ################################################################################
from PySide2.QtCore import * from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
from PySide2.QtGui import * QMetaObject, QObject, QPoint, QRect,
from PySide2.QtWidgets import * QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QGridLayout, QLabel, QLineEdit,
QMainWindow, QMenuBar, QPushButton, QSizePolicy,
QWidget)
class Ui_MainWindow(object): class Ui_MainWindow(object):
def setupUi(self, MainWindow): def setupUi(self, MainWindow):
@ -33,7 +39,6 @@ class Ui_MainWindow(object):
self.pushButton = QPushButton(self.gridLayoutWidget) self.pushButton = QPushButton(self.gridLayoutWidget)
self.pushButton.setObjectName(u"pushButton") self.pushButton.setObjectName(u"pushButton")
self.pushButton.setEnabled(False)
self.gridLayout.addWidget(self.pushButton, 0, 2, 1, 1) self.gridLayout.addWidget(self.pushButton, 0, 2, 1, 1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -1,3 +1,3 @@
PySide2 PySide6
pyinstaller pyinstaller
requests requests