-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8fb9c7a
commit a0cbb60
Showing
65 changed files
with
8,562 additions
and
0 deletions.
There are no files selected for viewing
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pyinstaller -F --windowed gui.py | ||
copy /Y dist\gui.exe "..\Thumper Modding Tool.exe" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
del /s /q __pycache__\*.* | ||
rd /s /q __pycache__ | ||
del /s /q build\*.* | ||
rd /s /q build | ||
del /s /q dist\*.* | ||
rd /s /q dist | ||
del /q gui.spec | ||
del /q "..\Thumper Modding Tool.exe" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import struct | ||
|
||
level_names = ['customlevel1', | ||
'customlevel2', | ||
'customlevel3', | ||
'customlevel4', | ||
'customlevel5', | ||
'customlevel6', | ||
'customlevel7', | ||
'customlevel8', | ||
'testlevel'] | ||
|
||
def hash32(s): | ||
h = 0x811c9dc5 | ||
for c in s: | ||
h = ((h ^ ord(c)) * 0x1000193) & 0xffffffff | ||
h = (h * 0x2001) & 0xffffffff | ||
h = (h ^ (h >> 0x7)) & 0xffffffff | ||
h = (h * 0x9) & 0xffffffff | ||
h = (h ^ (h >> 0x11)) & 0xffffffff | ||
h = (h * 0x21) & 0xffffffff | ||
return h | ||
|
||
def write_int(f, val): | ||
f.write(struct.pack('<i', val)) | ||
|
||
def write_bool(f, val): | ||
f.write(b'\x01' if val else b'\x00') | ||
|
||
def write_float(f, val): | ||
f.write(struct.pack('<f', val)) | ||
|
||
def write_color(f, val): | ||
r, g, b, a = val | ||
write_float(f, r) | ||
write_float(f, g) | ||
write_float(f, b) | ||
write_float(f, a) | ||
|
||
def write_vec3(f, val): | ||
x, y, z = val | ||
write_float(f, x) | ||
write_float(f, y) | ||
write_float(f, z) | ||
|
||
def write_string(f, val): | ||
write_int(f, len(val)) | ||
f.write(val.encode('ascii')) | ||
|
||
def write_hash(f, val): | ||
f.write(struct.pack('<I', hash32(val))) | ||
|
||
def write_hex(f, val): | ||
f.write(bytearray.fromhex(val)) | ||
|
||
def write_hex_reverse(f, val): | ||
f.write(bytearray.fromhex(val)[::-1]) | ||
|
||
def read_int(s, pos): | ||
return struct.unpack('<i', s[pos:pos+4])[0] | ||
|
||
def read_bool(s, pos): | ||
return True if b'\x01' == s[pos] else False | ||
|
||
def read_float(s, pos): | ||
return struct.unpack('<f', s[pos:pos+4])[0] | ||
|
||
def read_color(s, pos): | ||
r = read_float(s, pos) | ||
g = read_float(s, pos+4) | ||
b = read_float(s, pos+8) | ||
a = read_float(s, pos+12) | ||
return (r, g, b, a) | ||
|
||
def read_vec3(s, pos): | ||
x = read_float(s, pos) | ||
y = read_float(s, pos+4) | ||
z = read_float(s, pos+8) | ||
return (x, y, z) | ||
|
||
def read_string(s, pos): | ||
slen = read_int(s, pos) | ||
pos += 4 | ||
return s[pos:pos+slen].decode('ascii') | ||
|
||
def read_hex(s, pos): | ||
return s[pos:pos+4].hex() | ||
|
||
def read_hex_reverse(s, pos): | ||
return s[pos:pos+4][::-1].hex() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import configparser | ||
import psutil | ||
import traceback | ||
from tkinter import * | ||
from tkinter import filedialog | ||
from tkinter import messagebox | ||
from levels import * | ||
from savedata import * | ||
|
||
def read_config(): | ||
global config | ||
config.read('config.ini') | ||
if 'default' not in config: | ||
config['default'] = {} | ||
default = config['default'] | ||
while True: | ||
game_dir = filedialog.askdirectory( | ||
title='Select Thumper folder', | ||
initialdir='C:/Program Files (x86)/Steam/steamapps/common/Thumper') | ||
if len(game_dir) > 7 and game_dir[-7:] == 'Thumper': | ||
break | ||
default['game_dir'] = game_dir | ||
default['mod_mode'] = 'OFF' | ||
write_config() | ||
|
||
def write_config(): | ||
global config | ||
with open('config.ini', 'w') as configfile: | ||
config.write(configfile) | ||
|
||
def get_config(key): | ||
global config | ||
return config['default'][key] | ||
|
||
def set_config(key, value): | ||
global config | ||
config['default'][key] = value | ||
write_config() | ||
|
||
def change_game_dir(): | ||
while True: | ||
game_dir = filedialog.askdirectory( | ||
title='Select Thumper folder', | ||
initialdir=get_config('game_dir')) | ||
if len(game_dir) > 7 and game_dir[-7:] == 'Thumper': | ||
break | ||
set_config('game_dir', game_dir) | ||
|
||
def thumper_running(): | ||
for process in psutil.process_iter(): | ||
try: | ||
process_name = process.name() | ||
except: | ||
continue | ||
if process_name in ('THUMPER_dx9.exe', 'THUMPER_win8.exe', | ||
'THUMPER_win10.exe'): | ||
messagebox.showwarning(title='Warning', | ||
message='Please fully exit Thumper before switching Mod Mode.') | ||
return True | ||
return False | ||
|
||
def update_level(): | ||
global update_level_button | ||
try: | ||
update_level_button.config(text='Please wait...', state=DISABLED) | ||
|
||
make_custom_levels(get_config('game_dir')) | ||
make_custom_savedata(get_config('game_dir')) | ||
except: | ||
messagebox.showerror(title='Error',message=traceback.format_exc()) | ||
finally: | ||
update_level_button.config(text='Update Custom Levels', state=NORMAL) | ||
|
||
def mod_on(): | ||
global mod_mode_label, mod_on_button, mod_off_button, update_level_button | ||
try: | ||
mod_on_button.config(text='Please wait...', state=DISABLED) | ||
|
||
if thumper_running(): | ||
return | ||
backup_savedata(get_config('game_dir')) | ||
make_custom_levels(get_config('game_dir')) | ||
make_custom_savedata(get_config('game_dir')) | ||
|
||
mod_mode_label.config(text='Mod Mode: ON', fg='green') | ||
mod_on_button.grid_forget() | ||
mod_off_button.grid(row=0) | ||
set_config('mod_mode', 'ON') | ||
except: | ||
messagebox.showerror(title='Error',message=traceback.format_exc()) | ||
try: | ||
mod_off(skip_check=True) | ||
except: | ||
pass | ||
finally: | ||
mod_on_button.config(text='Turn ON Mod Mode', state=NORMAL) | ||
if get_config('mod_mode') == 'OFF': | ||
update_level_button.config(state=DISABLED) | ||
else: | ||
update_level_button.config(state=NORMAL) | ||
|
||
def mod_off(skip_check=False): | ||
global mod_mode_label, mod_off_button, mod_on_button, update_level_button | ||
try: | ||
mod_off_button.config(text='Please wait...', state=DISABLED) | ||
update_level_button.config(state=DISABLED) | ||
|
||
if not skip_check and thumper_running(): | ||
return | ||
restore_levels(get_config('game_dir')) | ||
restore_savedata(get_config('game_dir')) | ||
|
||
mod_mode_label.config(text='Mod Mode: OFF', fg='red') | ||
mod_off_button.grid_forget() | ||
mod_on_button.grid(row=0) | ||
set_config('mod_mode', 'OFF') | ||
except: | ||
messagebox.showerror(title='Error',message=traceback.format_exc()) | ||
finally: | ||
mod_off_button.config(text='Turn OFF Mod Mode', state=NORMAL) | ||
if get_config('mod_mode') == 'OFF': | ||
update_level_button.config(state=DISABLED) | ||
else: | ||
update_level_button.config(state=NORMAL) | ||
|
||
root = Tk() | ||
root.title('Thumper Modding Tool v1.0.0') | ||
root.resizable(False, False) | ||
|
||
menubar = Menu(root) | ||
options_menu = Menu(menubar, tearoff=0) | ||
options_menu.add_command(label='Change game folder...', command=change_game_dir) | ||
menubar.add_cascade(label='Options', menu=options_menu) | ||
root.config(menu=menubar) | ||
|
||
left_frame = Frame(root) | ||
left_frame.grid(padx=(10, 10), pady=(10, 10)) | ||
right_frame = Frame(root) | ||
right_frame.grid(row=0, column=1, padx=(10, 10), pady=(10, 10)) | ||
mod_mode_label = Label(left_frame, text='Mod Mode: OFF', fg='red', | ||
font=(None, 20), width=15) | ||
mod_mode_label.grid(row=0) | ||
mod_on_button = Button(right_frame, text='Turn ON Mod Mode', bg='lightgreen', | ||
width=20, command=mod_on) | ||
mod_on_button.grid(row=0) | ||
mod_off_button = Button(right_frame, text='Turn OFF Mod Mode', bg='pink', | ||
width=20, command=mod_off) | ||
update_level_button = Button(right_frame, text='Update Custom Levels', width=20, | ||
command=update_level, state=DISABLED) | ||
update_level_button.grid(row=1) | ||
|
||
config = configparser.ConfigParser() | ||
read_config() | ||
if config['default']['mod_mode'] == 'ON': | ||
mod_mode_label.config(text='Mod Mode: ON', fg='green') | ||
mod_on_button.grid_forget() | ||
mod_off_button.grid(row=0) | ||
update_level_button.config(state=NORMAL) | ||
|
||
root.mainloop() |
Oops, something went wrong.