v0.2.4 preview
This commit is contained in:
parent
10ac2564ea
commit
2af9cd8ddb
495
boiiiwd.py
495
boiiiwd.py
@ -20,28 +20,13 @@ import io
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
VERSION = "v0.2.3"
|
VERSION = "v0.2.4"
|
||||||
GITHUB_REPO = "faroukbmiled/BOIIIWD"
|
GITHUB_REPO = "faroukbmiled/BOIIIWD"
|
||||||
LATEST_RELEASE_URL = "https://github.com/faroukbmiled/BOIIIWD/releases/latest/download/Release.zip"
|
LATEST_RELEASE_URL = "https://github.com/faroukbmiled/BOIIIWD/releases/latest/download/Release.zip"
|
||||||
UPDATER_FOLDER = "update"
|
UPDATER_FOLDER = "update"
|
||||||
CONFIG_FILE_PATH = "config.ini"
|
CONFIG_FILE_PATH = "config.ini"
|
||||||
RESOURCES_DIR = os.path.join(os.path.dirname(__file__), 'resources')
|
RESOURCES_DIR = os.path.join(os.path.dirname(__file__), 'resources')
|
||||||
|
|
||||||
# fuck it we ball, ill get rid of globals when i finish everything cant be bothered rn
|
|
||||||
global stopped, steampid, console, clean_on_finish, continuous, estimated_progress, steam_fail_counter, \
|
|
||||||
steam_fail_counter_toggle, steam_fail_number, steamcmd_reset, show_fails
|
|
||||||
steampid = None
|
|
||||||
stopped = False
|
|
||||||
console = False
|
|
||||||
clean_on_finish = True
|
|
||||||
continuous = True
|
|
||||||
estimated_progress = True
|
|
||||||
steam_fail_counter_toggle = False
|
|
||||||
steam_fail_counter = 0
|
|
||||||
steam_fail_number = 10
|
|
||||||
steamcmd_reset = False
|
|
||||||
show_fails = True
|
|
||||||
|
|
||||||
# Start Helper Functions
|
# Start Helper Functions
|
||||||
def cwd():
|
def cwd():
|
||||||
if getattr(sys, 'frozen', False):
|
if getattr(sys, 'frozen', False):
|
||||||
@ -73,6 +58,7 @@ def check_custom_theme(theme_name):
|
|||||||
except:
|
except:
|
||||||
return os.path.join(RESOURCES_DIR, "boiiiwd_theme.json")
|
return os.path.join(RESOURCES_DIR, "boiiiwd_theme.json")
|
||||||
|
|
||||||
|
# theme initialization
|
||||||
ctk.set_appearance_mode(check_config("appearance", "Dark")) # Modes: "System" (standard), "Dark", "Light"
|
ctk.set_appearance_mode(check_config("appearance", "Dark")) # Modes: "System" (standard), "Dark", "Light"
|
||||||
try:
|
try:
|
||||||
ctk.set_default_color_theme(check_custom_theme(check_config("theme", fallback="boiiiwd_theme.json")))
|
ctk.set_default_color_theme(check_custom_theme(check_config("theme", fallback="boiiiwd_theme.json")))
|
||||||
@ -218,84 +204,6 @@ def create_default_config():
|
|||||||
with open(CONFIG_FILE_PATH, "w") as config_file:
|
with open(CONFIG_FILE_PATH, "w") as config_file:
|
||||||
config.write(config_file)
|
config.write(config_file)
|
||||||
|
|
||||||
def run_steamcmd_command(command, self, map_folder, queue=None):
|
|
||||||
global steampid, stopped, steam_fail_counter, steam_fail_number, steamcmd_reset
|
|
||||||
steamcmd_path = get_steamcmd_path()
|
|
||||||
show_console = subprocess.CREATE_NO_WINDOW
|
|
||||||
if console:
|
|
||||||
show_console = subprocess.CREATE_NEW_CONSOLE
|
|
||||||
|
|
||||||
if os.path.exists(map_folder):
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
os.remove(map_folder)
|
|
||||||
except:
|
|
||||||
timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
|
||||||
os.rename(map_folder, os.path.join(map_folder, os.path.join(get_steamcmd_path(), "steamapps", "workshop", "content", "311210", f"couldntremove_{timestamp}")))
|
|
||||||
except Exception as e:
|
|
||||||
stopped = True
|
|
||||||
self.queue_stop_button = True
|
|
||||||
show_message("Error", f"Couldn't remove {map_folder}, please do so manually\n{e}", icon="cancel")
|
|
||||||
return
|
|
||||||
|
|
||||||
if continuous:
|
|
||||||
while not os.path.exists(map_folder) and not stopped:
|
|
||||||
process = subprocess.Popen(
|
|
||||||
[steamcmd_path + "\steamcmd.exe"] + command.split(),
|
|
||||||
stdout=None if console else subprocess.PIPE,
|
|
||||||
stderr=None if console else subprocess.PIPE,
|
|
||||||
text=True,
|
|
||||||
bufsize=1,
|
|
||||||
universal_newlines=True,
|
|
||||||
creationflags=show_console
|
|
||||||
)
|
|
||||||
|
|
||||||
steampid = process.pid
|
|
||||||
|
|
||||||
if process.poll() is not None:
|
|
||||||
return process.returncode
|
|
||||||
|
|
||||||
process.communicate()
|
|
||||||
steam_fail_counter = steam_fail_counter + 1
|
|
||||||
if steam_fail_counter_toggle:
|
|
||||||
# print(steam_fail_counter)
|
|
||||||
try:
|
|
||||||
if steam_fail_counter >= int(steam_fail_number):
|
|
||||||
reset_steamcmd(no_warn=True)
|
|
||||||
steamcmd_reset = True
|
|
||||||
steam_fail_counter = 0
|
|
||||||
except:
|
|
||||||
if steam_fail_counter >= 10:
|
|
||||||
reset_steamcmd(no_warn=True)
|
|
||||||
steam_fail_counter = 0
|
|
||||||
else:
|
|
||||||
process = subprocess.Popen(
|
|
||||||
[steamcmd_path + "\steamcmd.exe"] + command.split(),
|
|
||||||
stdout=None if console else subprocess.PIPE,
|
|
||||||
stderr=None if console else subprocess.PIPE,
|
|
||||||
text=True,
|
|
||||||
bufsize=1,
|
|
||||||
universal_newlines=True,
|
|
||||||
creationflags=show_console
|
|
||||||
)
|
|
||||||
|
|
||||||
steampid = process.pid
|
|
||||||
|
|
||||||
if process.poll() is not None:
|
|
||||||
return process.returncode
|
|
||||||
|
|
||||||
process.communicate()
|
|
||||||
|
|
||||||
if not os.path.exists(map_folder):
|
|
||||||
show_message("SteamCMD has terminated", "SteamCMD has been terminated\nAnd failed to download the map/mod, try again or enable continuous download in settings")
|
|
||||||
|
|
||||||
stopped = True
|
|
||||||
if not queue:
|
|
||||||
self.button_download.configure(state="normal")
|
|
||||||
self.button_stop.configure(state="disabled")
|
|
||||||
|
|
||||||
return process.returncode
|
|
||||||
|
|
||||||
def get_steamcmd_path():
|
def get_steamcmd_path():
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(CONFIG_FILE_PATH)
|
config.read(CONFIG_FILE_PATH)
|
||||||
@ -353,9 +261,15 @@ def show_message(title, message, icon="warning", exit_on_close=False):
|
|||||||
msg = CTkMessagebox(title=title, message=message, icon=icon)
|
msg = CTkMessagebox(title=title, message=message, icon=icon)
|
||||||
|
|
||||||
def launch_boiii_func(path):
|
def launch_boiii_func(path):
|
||||||
|
procname = "boiii.exe"
|
||||||
try:
|
try:
|
||||||
boiii_path = os.path.join(path, "boiii.exe")
|
if procname in (p.name() for p in psutil.process_iter()):
|
||||||
subprocess.Popen([boiii_path], cwd=path)
|
for proc in psutil.process_iter():
|
||||||
|
if proc.name() == procname:
|
||||||
|
proc.kill()
|
||||||
|
boiii_path = os.path.join(path, procname)
|
||||||
|
subprocess.Popen([boiii_path ,"-launch"] , cwd=path)
|
||||||
|
show_message("Please wait!", "The game has launched in the background it will open up in a sec!", icon="info")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
show_message("Error: Failed to launch BOIII", f"Failed to launch boiii.exe\nMake sure to put in your correct boiii path\n{e}")
|
show_message("Error: Failed to launch BOIII", f"Failed to launch boiii.exe\nMake sure to put in your correct boiii path\n{e}")
|
||||||
|
|
||||||
@ -639,6 +553,7 @@ class LibraryTab(ctk.CTkScrollableFrame):
|
|||||||
button_view_list.destroy()
|
button_view_list.destroy()
|
||||||
self.label_list.remove(label)
|
self.label_list.remove(label)
|
||||||
self.button_list.remove(button)
|
self.button_list.remove(button)
|
||||||
|
self.added_items.remove(label.cget("text"))
|
||||||
self.button_view_list.remove(button_view_list)
|
self.button_view_list.remove(button_view_list)
|
||||||
|
|
||||||
def refresh_items(self):
|
def refresh_items(self):
|
||||||
@ -829,6 +744,18 @@ class LibraryTab(ctk.CTkScrollableFrame):
|
|||||||
class SettingsTab(ctk.CTkFrame):
|
class SettingsTab(ctk.CTkFrame):
|
||||||
def __init__(self, master=None):
|
def __init__(self, master=None):
|
||||||
super().__init__(master)
|
super().__init__(master)
|
||||||
|
# settings default bools
|
||||||
|
self.skip_already_installed = True
|
||||||
|
self.stopped = False
|
||||||
|
self.console = False
|
||||||
|
self.clean_on_finish = True
|
||||||
|
self.continuous = True
|
||||||
|
self.estimated_progress = True
|
||||||
|
self.steam_fail_counter_toggle = False
|
||||||
|
self.steam_fail_counter = 0
|
||||||
|
self.steam_fail_number = 10
|
||||||
|
self.steamcmd_reset = False
|
||||||
|
self.show_fails = True
|
||||||
|
|
||||||
# Left and right frames, use fg_color="transparent"
|
# Left and right frames, use fg_color="transparent"
|
||||||
self.grid_rowconfigure(0, weight=1)
|
self.grid_rowconfigure(0, weight=1)
|
||||||
@ -876,27 +803,35 @@ class SettingsTab(ctk.CTkFrame):
|
|||||||
# Show estimated_progress checkbox
|
# Show estimated_progress checkbox
|
||||||
self.estimated_progress_var = ctk.BooleanVar()
|
self.estimated_progress_var = ctk.BooleanVar()
|
||||||
self.estimated_progress_var.trace_add("write", self.enable_save_button)
|
self.estimated_progress_var.trace_add("write", self.enable_save_button)
|
||||||
self.estimated_progress = ctk.CTkSwitch(left_frame, text="Estimated Progress Bar", variable=self.estimated_progress_var)
|
self.estimated_progress_cb = ctk.CTkSwitch(left_frame, text="Estimated Progress Bar", variable=self.estimated_progress_var)
|
||||||
self.estimated_progress.grid(row=4, column=1, padx=20, pady=(20, 0), sticky="nw")
|
self.estimated_progress_cb.grid(row=4, column=1, padx=20, pady=(20, 0), sticky="nw")
|
||||||
self.estimated_progress_var_tooltip = CTkToolTip(self.estimated_progress, message="This will change how to progress bar works by estimating how long the download will take\
|
self.estimated_progress_var_tooltip = CTkToolTip(self.estimated_progress_cb, message="This will change how to progress bar works by estimating how long the download will take\
|
||||||
\nThis is not accurate ,it's better than with it off which is calculating the downloaded folder size which steamcmd dumps the full size rigth mostly")
|
\nThis is not accurate ,it's better than with it off which is calculating the downloaded folder size which steamcmd dumps the full size rigth mostly")
|
||||||
self.estimated_progress_var.set(self.load_settings("estimated_progress", "on"))
|
self.estimated_progress_var.set(self.load_settings("estimated_progress", "on"))
|
||||||
|
|
||||||
# Show estimated_progress checkbox
|
# Show show fails checkbox
|
||||||
self.show_fails_var = ctk.BooleanVar()
|
self.show_fails_var = ctk.BooleanVar()
|
||||||
self.show_fails_var.trace_add("write", self.enable_save_button)
|
self.show_fails_var.trace_add("write", self.enable_save_button)
|
||||||
self.show_fails = ctk.CTkSwitch(left_frame, text="Show fails (on top of progress bar):", variable=self.show_fails_var)
|
self.show_fails_cb = ctk.CTkSwitch(left_frame, text="Show fails (on top of progress bar):", variable=self.show_fails_var)
|
||||||
self.show_fails.grid(row=5, column=1, padx=20, pady=(20, 0), sticky="nw")
|
self.show_fails_cb.grid(row=5, column=1, padx=20, pady=(20, 0), sticky="nw")
|
||||||
self.show_fails_tooltip = CTkToolTip(self.show_fails, message="Display how many times steamcmd has failed/crashed\nIf the number is getting high quickly then try pressing Reset SteamCMD and try again, otherwise its fine")
|
self.show_fails_tooltip = CTkToolTip(self.show_fails_cb, message="Display how many times steamcmd has failed/crashed\nIf the number is getting high quickly then try pressing Reset SteamCMD and try again, otherwise its fine")
|
||||||
self.estimated_progress_var.set(self.load_settings("show_fails", "on"))
|
self.estimated_progress_var.set(self.load_settings("show_fails", "on"))
|
||||||
|
|
||||||
|
# Show skip_already_installed maps checkbox
|
||||||
|
self.skip_already_installed_var = ctk.BooleanVar()
|
||||||
|
self.skip_already_installed_var.trace_add("write", self.enable_save_button)
|
||||||
|
self.skip_already_installed_ch = ctk.CTkSwitch(left_frame, text="Skip already installed maps:", variable=self.skip_already_installed_var)
|
||||||
|
self.skip_already_installed_ch.grid(row=6, column=1, padx=20, pady=(20, 0), sticky="nw")
|
||||||
|
self.skip_already_installed_ch_tooltip = CTkToolTip(self.skip_already_installed_ch, message="If on it will not download installed maps,\nthis can miss sometimes if you remove maps manually and not from library tab while the app is running")
|
||||||
|
self.skip_already_installed_var.set(self.load_settings("skip_already_installed", "on"))
|
||||||
|
|
||||||
# Resetr steam on many fails
|
# Resetr steam on many fails
|
||||||
self.reset_steamcmd_on_fail_var = ctk.IntVar()
|
self.reset_steamcmd_on_fail_var = ctk.IntVar()
|
||||||
self.reset_steamcmd_on_fail_var.trace_add("write", self.enable_save_button)
|
self.reset_steamcmd_on_fail_var.trace_add("write", self.enable_save_button)
|
||||||
self.reset_steamcmd_on_fail_text = ctk.CTkLabel(left_frame, text=f"Reset steamcmd on % fails: (n of fails)", anchor="w")
|
self.reset_steamcmd_on_fail_text = ctk.CTkLabel(left_frame, text=f"Reset steamcmd on % fails: (n of fails)", anchor="w")
|
||||||
self.reset_steamcmd_on_fail_text.grid(row=6, column=1, padx=20, pady=(10, 0), sticky="nw")
|
self.reset_steamcmd_on_fail_text.grid(row=7, column=1, padx=20, pady=(10, 0), sticky="nw")
|
||||||
self.reset_steamcmd_on_fail = ctk.CTkOptionMenu(left_frame, values=["20", "30", "40", "Custom", "Disable"], variable=self.reset_steamcmd_on_fail_var, command=self.reset_steamcmd_on_fail_func)
|
self.reset_steamcmd_on_fail = ctk.CTkOptionMenu(left_frame, values=["20", "30", "40", "Custom", "Disable"], variable=self.reset_steamcmd_on_fail_var, command=self.reset_steamcmd_on_fail_func)
|
||||||
self.reset_steamcmd_on_fail.grid(row=7, column=1, padx=20, pady=(0, 0), sticky="nw")
|
self.reset_steamcmd_on_fail.grid(row=8, column=1, padx=20, pady=(0, 0), sticky="nw")
|
||||||
self.reset_steamcmd_on_fail_tooltip = CTkToolTip(self.reset_steamcmd_on_fail, message="This actually fixes steamcmd when its crashing way too much")
|
self.reset_steamcmd_on_fail_tooltip = CTkToolTip(self.reset_steamcmd_on_fail, message="This actually fixes steamcmd when its crashing way too much")
|
||||||
self.reset_steamcmd_on_fail.set(value=self.load_settings("reset_on_fail", "Disable"))
|
self.reset_steamcmd_on_fail.set(value=self.load_settings("reset_on_fail", "Disable"))
|
||||||
|
|
||||||
@ -976,7 +911,6 @@ class SettingsTab(ctk.CTkFrame):
|
|||||||
|
|
||||||
def save_settings(self):
|
def save_settings(self):
|
||||||
self.save_button.configure(state='disabled')
|
self.save_button.configure(state='disabled')
|
||||||
global console, clean_on_finish, continuous, estimated_progress, steam_fail_number, steam_fail_counter_toggle, show_fails
|
|
||||||
if self.check_updates_checkbox.get():
|
if self.check_updates_checkbox.get():
|
||||||
save_config("checkforupdtes", "on")
|
save_config("checkforupdtes", "on")
|
||||||
else:
|
else:
|
||||||
@ -984,104 +918,118 @@ class SettingsTab(ctk.CTkFrame):
|
|||||||
|
|
||||||
if self.checkbox_show_console.get():
|
if self.checkbox_show_console.get():
|
||||||
save_config("console", "on")
|
save_config("console", "on")
|
||||||
console = True
|
self.console = True
|
||||||
else:
|
else:
|
||||||
save_config("console", "off")
|
save_config("console", "off")
|
||||||
console = False
|
self.console = False
|
||||||
|
|
||||||
|
if self.skip_already_installed_ch.get():
|
||||||
|
save_config("skip_already_installed", "on")
|
||||||
|
self.skip_already_installed = True
|
||||||
|
else:
|
||||||
|
save_config("skip_already_installed", "off")
|
||||||
|
self.skip_already_installed = False
|
||||||
|
|
||||||
if self.clean_checkbox.get():
|
if self.clean_checkbox.get():
|
||||||
save_config("clean_on_finish", "on")
|
save_config("clean_on_finish", "on")
|
||||||
clean_on_finish = True
|
self.clean_on_finish = True
|
||||||
else:
|
else:
|
||||||
save_config("clean_on_finish", "off")
|
save_config("clean_on_finish", "off")
|
||||||
clean_on_finish = False
|
self.clean_on_finish = False
|
||||||
|
|
||||||
if self.checkbox_continuous.get():
|
if self.checkbox_continuous.get():
|
||||||
save_config("continuous_download", "on")
|
save_config("continuous_download", "on")
|
||||||
continuous = True
|
self.continuous = True
|
||||||
else:
|
else:
|
||||||
save_config("continuous_download", "off")
|
save_config("continuous_download", "off")
|
||||||
continuous = False
|
self.continuous = False
|
||||||
|
|
||||||
if self.estimated_progress.get():
|
if self.estimated_progress_cb.get():
|
||||||
save_config("estimated_progress", "on")
|
save_config("estimated_progress", "on")
|
||||||
estimated_progress = True
|
self.estimated_progress = True
|
||||||
else:
|
else:
|
||||||
save_config("estimated_progress", "off")
|
save_config("estimated_progress", "off")
|
||||||
estimated_progress = False
|
self.estimated_progress = False
|
||||||
|
|
||||||
if self.show_fails.get():
|
if self.show_fails_cb.get():
|
||||||
save_config("show_fails", "on")
|
save_config("show_fails", "on")
|
||||||
show_fails = True
|
self.show_fails = True
|
||||||
else:
|
else:
|
||||||
save_config("show_fails", "off")
|
save_config("show_fails", "off")
|
||||||
show_fails = False
|
self.show_fails = False
|
||||||
|
|
||||||
if self.reset_steamcmd_on_fail.get():
|
if self.reset_steamcmd_on_fail.get():
|
||||||
value = self.reset_steamcmd_on_fail.get()
|
value = self.reset_steamcmd_on_fail.get()
|
||||||
if value == "Disable":
|
if value == "Disable":
|
||||||
steam_fail_counter_toggle = False
|
self.steam_fail_counter_toggle = False
|
||||||
else:
|
else:
|
||||||
steam_fail_counter_toggle = True
|
self.steam_fail_counter_toggle = True
|
||||||
steam_fail_number = int(value)
|
self.steam_fail_number = int(value)
|
||||||
save_config("reset_on_fail", value)
|
save_config("reset_on_fail", value)
|
||||||
|
|
||||||
def load_settings(self, setting, fallback=None):
|
def load_settings(self, setting, fallback=None):
|
||||||
global console, clean_on_finish, continuous, estimated_progress, steam_fail_counter_toggle, steam_fail_number, show_fails
|
|
||||||
if setting == "console":
|
if setting == "console":
|
||||||
if check_config(setting, fallback) == "on":
|
if check_config(setting, fallback) == "on":
|
||||||
console = True
|
self.console = True
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
console = False
|
self.console = False
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if setting == "continuous_download":
|
if setting == "continuous_download":
|
||||||
if check_config(setting, "on") == "on":
|
if check_config(setting, "on") == "on":
|
||||||
continuous = True
|
self.continuous = True
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
continuous = False
|
self.continuous = False
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if setting == "clean_on_finish":
|
if setting == "clean_on_finish":
|
||||||
if check_config(setting, fallback) == "on":
|
if check_config(setting, fallback) == "on":
|
||||||
clean_on_finish = True
|
self.clean_on_finish = True
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
clean_on_finish = False
|
self.clean_on_finish = False
|
||||||
return 0
|
return 0
|
||||||
if setting == "estimated_progress":
|
if setting == "estimated_progress":
|
||||||
if check_config(setting, fallback) == "on":
|
if check_config(setting, fallback) == "on":
|
||||||
estimated_progress = True
|
self.estimated_progress = True
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
estimated_progress = False
|
self.estimated_progress = False
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if setting == "reset_on_fail":
|
if setting == "reset_on_fail":
|
||||||
option = check_config(setting, fallback)
|
option = check_config(setting, fallback)
|
||||||
if option == "Disable" or option == "Custom":
|
if option == "Disable" or option == "Custom":
|
||||||
steam_fail_counter_toggle = False
|
self.steam_fail_counter_toggle = False
|
||||||
return "Disable"
|
return "Disable"
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
steam_fail_number = int(option)
|
self.steam_fail_number = int(option)
|
||||||
return option
|
return option
|
||||||
except:
|
except:
|
||||||
if steam_fail_counter_toggle:
|
if self.steam_fail_counter_toggle:
|
||||||
steam_fail_number = 10
|
self.steam_fail_number = 10
|
||||||
return "10"
|
return "10"
|
||||||
else:
|
else:
|
||||||
steam_fail_number = 10
|
self.steam_fail_number = 10
|
||||||
return "Disable"
|
return "Disable"
|
||||||
|
|
||||||
if setting == "show_fails":
|
if setting == "show_fails":
|
||||||
if check_config(setting, fallback) == "on":
|
if check_config(setting, fallback) == "on":
|
||||||
show_fails = True
|
self.show_fails = True
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
show_fails = False
|
self.show_fails = False
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if setting == "skip_already_installed":
|
||||||
|
if check_config(setting, fallback) == "on":
|
||||||
|
self.skip_already_installed = True
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
self.skip_already_installed = False
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if setting == "theme":
|
if setting == "theme":
|
||||||
@ -1099,6 +1047,8 @@ class SettingsTab(ctk.CTkFrame):
|
|||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def boiiiwd_custom_theme(self, disable_only=None):
|
def boiiiwd_custom_theme(self, disable_only=None):
|
||||||
file_to_rename = os.path.join(cwd(), "boiiiwd_theme.json")
|
file_to_rename = os.path.join(cwd(), "boiiiwd_theme.json")
|
||||||
if os.path.exists(file_to_rename):
|
if os.path.exists(file_to_rename):
|
||||||
@ -1128,6 +1078,7 @@ class SettingsTab(ctk.CTkFrame):
|
|||||||
self.clean_checkbox_var.set(self.load_settings("clean_on_finish", "on"))
|
self.clean_checkbox_var.set(self.load_settings("clean_on_finish", "on"))
|
||||||
self.continuous_var.set(self.load_settings("continuous_download"))
|
self.continuous_var.set(self.load_settings("continuous_download"))
|
||||||
self.show_fails_var.set(self.load_settings("show_fails", "on"))
|
self.show_fails_var.set(self.load_settings("show_fails", "on"))
|
||||||
|
self.skip_already_installed_var.set(self.load_settings("skip_already_installed", "on"))
|
||||||
|
|
||||||
# keep last cuz of trace_add()
|
# keep last cuz of trace_add()
|
||||||
self.save_button.configure(state='disabled')
|
self.save_button.configure(state='disabled')
|
||||||
@ -1309,6 +1260,7 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.is_pressed = False
|
self.is_pressed = False
|
||||||
self.queue_enabled = False
|
self.queue_enabled = False
|
||||||
self.queue_stop_button = False
|
self.queue_stop_button = False
|
||||||
|
self.is_downloading = False
|
||||||
|
|
||||||
# sidebar windows bouttons
|
# sidebar windows bouttons
|
||||||
self.sidebar_main.configure(command=self.main_button_event, text="Main ⬇️", fg_color=(self.active_color), state="active")
|
self.sidebar_main.configure(command=self.main_button_event, text="Main ⬇️", fg_color=(self.active_color), state="active")
|
||||||
@ -1337,6 +1289,7 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.settings_tab.load_settings("estimated_progress", "on")
|
self.settings_tab.load_settings("estimated_progress", "on")
|
||||||
self.settings_tab.load_settings("reset_on_fail", "Disable")
|
self.settings_tab.load_settings("reset_on_fail", "Disable")
|
||||||
self.settings_tab.load_settings("show_fails", "on")
|
self.settings_tab.load_settings("show_fails", "on")
|
||||||
|
self.settings_tab.load_settings("skip_already_installed", "on")
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -1473,7 +1426,7 @@ class BOIIIWD(ctk.CTk):
|
|||||||
create_default_config()
|
create_default_config()
|
||||||
|
|
||||||
def help_queue_text_func(self):
|
def help_queue_text_func(self):
|
||||||
if any(char.isalpha() for char in self.queuetextarea.get("1.0", "end")):
|
if any(char.strip() for char in self.queuetextarea.get("1.0", "end")):
|
||||||
self.workshop_queue_label.configure(text="Workshop IDs/Links => press help to see examples:")
|
self.workshop_queue_label.configure(text="Workshop IDs/Links => press help to see examples:")
|
||||||
self.queuetextarea.configure(state="normal")
|
self.queuetextarea.configure(state="normal")
|
||||||
self.queuetextarea.delete(1.0, "end")
|
self.queuetextarea.delete(1.0, "end")
|
||||||
@ -1702,9 +1655,148 @@ class BOIIIWD(ctk.CTk):
|
|||||||
top.grid_columnconfigure(0, weight=1)
|
top.grid_columnconfigure(0, weight=1)
|
||||||
top.grid_columnconfigure(1, weight=1)
|
top.grid_columnconfigure(1, weight=1)
|
||||||
|
|
||||||
|
def check_steamcmd_stdout(self, log_file_path, target_item_id):
|
||||||
|
temp_file_path = log_file_path + '.temp'
|
||||||
|
shutil.copy2(log_file_path, temp_file_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(temp_file_path, 'r') as log_file:
|
||||||
|
log_file.seek(0, os.SEEK_END)
|
||||||
|
file_size = log_file.tell()
|
||||||
|
|
||||||
|
position = file_size
|
||||||
|
lines_found = 0
|
||||||
|
|
||||||
|
while lines_found < 7 and position > 0:
|
||||||
|
position -= 1
|
||||||
|
log_file.seek(position, os.SEEK_SET)
|
||||||
|
|
||||||
|
char = log_file.read(1)
|
||||||
|
|
||||||
|
if char == '\n':
|
||||||
|
lines_found += 1
|
||||||
|
|
||||||
|
lines = log_file.readlines()[-7:]
|
||||||
|
|
||||||
|
for line in reversed(lines):
|
||||||
|
line = line.lower().strip()
|
||||||
|
if f"download item {target_item_id.strip()}" in line:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
os.remove(temp_file_path)
|
||||||
|
|
||||||
|
# the real deal
|
||||||
|
def run_steamcmd_command(self, command, map_folder, wsid, queue=None):
|
||||||
|
steamcmd_path = get_steamcmd_path()
|
||||||
|
stdout = os.path.join(steamcmd_path, "logs", "workshop_log.txt")
|
||||||
|
timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
||||||
|
try:
|
||||||
|
with open(stdout, 'w') as file:
|
||||||
|
file.write('')
|
||||||
|
except:
|
||||||
|
os.rename(stdout, os.path.join(map_folder, os.path.join(stdout, f"workshop_log_couldntremove_{timestamp}.txt")))
|
||||||
|
|
||||||
|
show_console = subprocess.CREATE_NO_WINDOW
|
||||||
|
if self.settings_tab.console:
|
||||||
|
show_console = subprocess.CREATE_NEW_CONSOLE
|
||||||
|
|
||||||
|
if os.path.exists(map_folder):
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
os.remove(map_folder)
|
||||||
|
except:
|
||||||
|
os.rename(map_folder, os.path.join(map_folder, os.path.join(get_steamcmd_path(), "steamapps", "workshop", "content", "311210", f"couldntremove_{timestamp}")))
|
||||||
|
except Exception as e:
|
||||||
|
self.settings_tab.stopped = True
|
||||||
|
self.queue_stop_button = True
|
||||||
|
show_message("Error", f"Couldn't remove {map_folder}, please do so manually\n{e}", icon="cancel")
|
||||||
|
self.stop_download
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.settings_tab.continuous:
|
||||||
|
while not os.path.exists(map_folder) and not self.settings_tab.stopped:
|
||||||
|
process = subprocess.Popen(
|
||||||
|
[steamcmd_path + "\steamcmd.exe"] + command.split(),
|
||||||
|
stdout=None if self.settings_tab.console else subprocess.PIPE,
|
||||||
|
stderr=None if self.settings_tab.console else subprocess.PIPE,
|
||||||
|
text=True,
|
||||||
|
bufsize=1,
|
||||||
|
universal_newlines=True,
|
||||||
|
creationflags=show_console
|
||||||
|
)
|
||||||
|
|
||||||
|
#wait for process
|
||||||
|
while True:
|
||||||
|
if not self.is_downloading:
|
||||||
|
if self.check_steamcmd_stdout(stdout, wsid):
|
||||||
|
self.is_downloading = True
|
||||||
|
if process.poll() != None:
|
||||||
|
break
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# print("Broken freeeee!")
|
||||||
|
self.is_downloading = False
|
||||||
|
try:
|
||||||
|
with open(stdout, 'w') as file:
|
||||||
|
file.write('')
|
||||||
|
except:
|
||||||
|
os.rename(stdout, os.path.join(map_folder, os.path.join(stdout, f"workshop_log_couldntremove_{timestamp}.txt")))
|
||||||
|
|
||||||
|
self.settings_tab.steam_fail_counter = self.settings_tab.steam_fail_counter + 1
|
||||||
|
if self.settings_tab.steam_fail_counter_toggle:
|
||||||
|
try:
|
||||||
|
if self.settings_tab.steam_fail_counter >= int(self.settings_tab.steam_fail_number):
|
||||||
|
reset_steamcmd(no_warn=True)
|
||||||
|
self.settings_tab.steamcmd_reset = True
|
||||||
|
self.settings_tab.steam_fail_counter = 0
|
||||||
|
except:
|
||||||
|
if self.settings_tab.steam_fail_counter >= 10:
|
||||||
|
reset_steamcmd(no_warn=True)
|
||||||
|
self.settings_tab.steam_fail_counter = 0
|
||||||
|
else:
|
||||||
|
process = subprocess.Popen(
|
||||||
|
[steamcmd_path + "\steamcmd.exe"] + command.split(),
|
||||||
|
stdout=None if self.settings_tab.console else subprocess.PIPE,
|
||||||
|
stderr=None if self.settings_tab.console else subprocess.PIPE,
|
||||||
|
text=True,
|
||||||
|
bufsize=1,
|
||||||
|
universal_newlines=True,
|
||||||
|
creationflags=show_console
|
||||||
|
)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
if not self.is_downloading:
|
||||||
|
if self.find_download_event(stdout, wsid):
|
||||||
|
self.is_downloading = True
|
||||||
|
if process.poll() != None:
|
||||||
|
break
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# print("Broken freeeee!")
|
||||||
|
self.is_downloading = False
|
||||||
|
try:
|
||||||
|
with open(stdout, 'w') as file:
|
||||||
|
file.write('')
|
||||||
|
except:
|
||||||
|
os.rename(stdout, os.path.join(map_folder, os.path.join(stdout, f"workshop_log_couldntremove_{timestamp}.txt")))
|
||||||
|
|
||||||
|
if not os.path.exists(map_folder):
|
||||||
|
show_message("SteamCMD has terminated", "SteamCMD has been terminated\nAnd failed to download the map/mod, try again or enable continuous download in settings")
|
||||||
|
|
||||||
|
self.settings_tab.stopped = True
|
||||||
|
if not queue:
|
||||||
|
self.button_download.configure(state="normal")
|
||||||
|
self.button_stop.configure(state="disabled")
|
||||||
|
|
||||||
|
return process.returncode
|
||||||
|
|
||||||
def download_map(self):
|
def download_map(self):
|
||||||
|
self.is_downloading = False
|
||||||
if not self.is_pressed:
|
if not self.is_pressed:
|
||||||
self.is_pressed = True
|
self.is_pressed = True
|
||||||
|
self.library_tab.load_items(self.edit_destination_folder.get())
|
||||||
if self.queue_enabled:
|
if self.queue_enabled:
|
||||||
start_down_thread = threading.Thread(target=self.queue_download_thread)
|
start_down_thread = threading.Thread(target=self.queue_download_thread)
|
||||||
start_down_thread.start()
|
start_down_thread.start()
|
||||||
@ -1715,8 +1807,7 @@ class BOIIIWD(ctk.CTk):
|
|||||||
show_message("Warning", "Already pressed, Please wait.")
|
show_message("Warning", "Already pressed, Please wait.")
|
||||||
|
|
||||||
def queue_download_thread(self):
|
def queue_download_thread(self):
|
||||||
global stopped
|
self.stopped = False
|
||||||
stopped = False
|
|
||||||
self.queue_stop_button = False
|
self.queue_stop_button = False
|
||||||
try:
|
try:
|
||||||
save_config("DestinationFolder" ,self.edit_destination_folder.get())
|
save_config("DestinationFolder" ,self.edit_destination_folder.get())
|
||||||
@ -1762,6 +1853,7 @@ class BOIIIWD(ctk.CTk):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.total_queue_size = 0
|
self.total_queue_size = 0
|
||||||
|
self.already_installed = []
|
||||||
for item in items:
|
for item in items:
|
||||||
item.strip()
|
item.strip()
|
||||||
workshop_id = item
|
workshop_id = item
|
||||||
@ -1791,16 +1883,32 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.stop_download
|
self.stop_download
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if any(workshop_id in item for item in self.library_tab.added_items):
|
||||||
|
self.already_installed.append(workshop_id)
|
||||||
|
|
||||||
|
if self.already_installed:
|
||||||
|
item_ids = ", ".join(self.already_installed)
|
||||||
|
if self.settings_tab.skip_already_installed:
|
||||||
|
for item in self.already_installed:
|
||||||
|
if item in items:
|
||||||
|
items.remove(item)
|
||||||
|
show_message("Heads up!, map/s skipped => skip is on in settings", f"These item IDs may already be installed and are skipped:\n{item_ids}", icon="info")
|
||||||
|
if not any(isinstance(item, int) for item in items):
|
||||||
|
self.stop_download
|
||||||
|
return
|
||||||
|
show_message("Heads up! map/s not skipped => skip is off in settings", f"These item IDs may already be installed:\n{item_ids}", icon="info")
|
||||||
|
|
||||||
self.after(1, self.status_text.configure(text=f"Status: Total size: ~{convert_bytes_to_readable(self.total_queue_size)}"))
|
self.after(1, self.status_text.configure(text=f"Status: Total size: ~{convert_bytes_to_readable(self.total_queue_size)}"))
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
for index, item in enumerate(items):
|
for index, item in enumerate(items):
|
||||||
|
self.settings_tab.steam_fail_counter = 0
|
||||||
current_number = index + 1
|
current_number = index + 1
|
||||||
total_items = len(items)
|
total_items = len(items)
|
||||||
if self.queue_stop_button:
|
if self.queue_stop_button:
|
||||||
self.stop_download
|
self.stop_download
|
||||||
break
|
break
|
||||||
item.strip()
|
item.strip()
|
||||||
stopped = False
|
self.settings_tab.stopped = False
|
||||||
workshop_id = item
|
workshop_id = item
|
||||||
if not workshop_id.isdigit():
|
if not workshop_id.isdigit():
|
||||||
try:
|
try:
|
||||||
@ -1823,17 +1931,14 @@ class BOIIIWD(ctk.CTk):
|
|||||||
os.makedirs(download_folder)
|
os.makedirs(download_folder)
|
||||||
|
|
||||||
def check_and_update_progress():
|
def check_and_update_progress():
|
||||||
# delay untill steam boots up and starts downloading (ive a better idea ill implement it later)
|
|
||||||
time.sleep(8)
|
|
||||||
global stopped, steamcmd_reset
|
|
||||||
previous_net_speed = 0
|
previous_net_speed = 0
|
||||||
est_downloaded_bytes = 0
|
est_downloaded_bytes = 0
|
||||||
file_size = ws_file_size
|
file_size = ws_file_size
|
||||||
item_name = get_item_name(workshop_id) if get_item_name(workshop_id) else "Error getting name"
|
item_name = get_item_name(workshop_id) if get_item_name(workshop_id) else "Error getting name"
|
||||||
|
|
||||||
while not stopped:
|
while not self.settings_tab.stopped:
|
||||||
if steamcmd_reset:
|
if self.settings_tab.steamcmd_reset:
|
||||||
steamcmd_reset = False
|
self.settings_tab.steamcmd_reset = False
|
||||||
previous_net_speed = 0
|
previous_net_speed = 0
|
||||||
est_downloaded_bytes = 0
|
est_downloaded_bytes = 0
|
||||||
|
|
||||||
@ -1856,7 +1961,19 @@ class BOIIIWD(ctk.CTk):
|
|||||||
text=f"Status: Total size: ~{convert_bytes_to_readable(self.total_queue_size)} | ID: {workshop_id} | {item_name} | Downloading {current_number}/{total_items}"))
|
text=f"Status: Total size: ~{convert_bytes_to_readable(self.total_queue_size)} | ID: {workshop_id} | {item_name} | Downloading {current_number}/{total_items}"))
|
||||||
self.after(1, lambda p=progress: self.label_file_size.configure(text=f"Wrong size reported\nFile size: ~{convert_bytes_to_readable(current_size)}"))
|
self.after(1, lambda p=progress: self.label_file_size.configure(text=f"Wrong size reported\nFile size: ~{convert_bytes_to_readable(current_size)}"))
|
||||||
|
|
||||||
if estimated_progress:
|
while not self.is_downloading:
|
||||||
|
self.after(1, self.label_speed.configure(text=f"Network Speed: 0 KB/s"))
|
||||||
|
time_elapsed = time.time() - start_time
|
||||||
|
elapsed_hours, elapsed_minutes, elapsed_seconds = convert_seconds(time_elapsed)
|
||||||
|
if self.settings_tab.show_fails:
|
||||||
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {self.settings_tab.steam_fail_counter}"))
|
||||||
|
else:
|
||||||
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
||||||
|
time.sleep(1)
|
||||||
|
if self.is_downloading:
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.settings_tab.estimated_progress:
|
||||||
time_elapsed = time.time() - start_time
|
time_elapsed = time.time() - start_time
|
||||||
raw_net_speed = psutil.net_io_counters().bytes_recv
|
raw_net_speed = psutil.net_io_counters().bytes_recv
|
||||||
|
|
||||||
@ -1885,8 +2002,8 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.after(1, self.progress_bar.set(progress))
|
self.after(1, self.progress_bar.set(progress))
|
||||||
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
||||||
self.after(1, lambda p=min(percentage_complete ,99): self.progress_text.configure(text=f"{p:.2f}%"))
|
self.after(1, lambda p=min(percentage_complete ,99): self.progress_text.configure(text=f"{p:.2f}%"))
|
||||||
if show_fails:
|
if self.settings_tab.show_fails:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {steam_fail_counter}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {self.settings_tab.steam_fail_counter}"))
|
||||||
else:
|
else:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
||||||
|
|
||||||
@ -1908,14 +2025,14 @@ class BOIIIWD(ctk.CTk):
|
|||||||
text=f"Status: Total size: ~{convert_bytes_to_readable(self.total_queue_size)} | ID: {workshop_id} | {item_name} | Downloading {current_number}/{total_items}"))
|
text=f"Status: Total size: ~{convert_bytes_to_readable(self.total_queue_size)} | ID: {workshop_id} | {item_name} | Downloading {current_number}/{total_items}"))
|
||||||
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
||||||
self.after(1, lambda p=progress: self.progress_text.configure(text=f"{p}%"))
|
self.after(1, lambda p=progress: self.progress_text.configure(text=f"{p}%"))
|
||||||
if show_fails:
|
if self.settings_tab.show_fails:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {steam_fail_counter}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {self.settings_tab.steam_fail_counter}"))
|
||||||
else:
|
else:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
command = f"+login anonymous +@sSteamCmdForcePlatformBitness 64 +app_info_update 1 +app_info_print 311210 app_update 311210 +workshop_download_item 311210 {workshop_id} validate +quit"
|
command = f"+login anonymous app_update 311210 +workshop_download_item 311210 {workshop_id} validate +quit"
|
||||||
steamcmd_thread = threading.Thread(target=lambda: run_steamcmd_command(command, self, map_folder, queue=True))
|
steamcmd_thread = threading.Thread(target=lambda: self.run_steamcmd_command(command, map_folder, workshop_id, queue=True))
|
||||||
steamcmd_thread.start()
|
steamcmd_thread.start()
|
||||||
|
|
||||||
def wait_for_threads():
|
def wait_for_threads():
|
||||||
@ -1954,12 +2071,12 @@ class BOIIIWD(ctk.CTk):
|
|||||||
except Exception as E:
|
except Exception as E:
|
||||||
show_message("Error", f"Error copying files: {E}", icon="cancel")
|
show_message("Error", f"Error copying files: {E}", icon="cancel")
|
||||||
|
|
||||||
if clean_on_finish:
|
if self.settings_tab.clean_on_finish:
|
||||||
remove_tree(map_folder)
|
remove_tree(map_folder)
|
||||||
remove_tree(download_folder)
|
remove_tree(download_folder)
|
||||||
|
|
||||||
if index == len(items) - 1:
|
if index == len(items) - 1:
|
||||||
msg = CTkMessagebox(title="Downloads Complete", message=f"All files were downloaded\nYou can run the game now!", icon="info", option_1="Launch", option_2="Ok")
|
msg = CTkMessagebox(title="Downloads Complete", message=f"All files were downloaded\nYou can run the game now!\nPS: You have to restart the game \n(pressing launch will launch/restarts)", icon="info", option_1="Launch", option_2="Ok")
|
||||||
response = msg.get()
|
response = msg.get()
|
||||||
if response=="Launch":
|
if response=="Launch":
|
||||||
launch_boiii_func(self.edit_destination_folder.get().strip())
|
launch_boiii_func(self.edit_destination_folder.get().strip())
|
||||||
@ -1978,20 +2095,18 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.button_stop.configure(state="disabled")
|
self.button_stop.configure(state="disabled")
|
||||||
self.after(1, self.status_text.configure(text=f"Status: Done"))
|
self.after(1, self.status_text.configure(text=f"Status: Done"))
|
||||||
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
||||||
stopped = True
|
self.settings_tab.stopped = True
|
||||||
self.stop_download
|
self.stop_download
|
||||||
return
|
return
|
||||||
finally:
|
finally:
|
||||||
global steam_fail_counter
|
self.settings_tab.steam_fail_counter = 0
|
||||||
steam_fail_counter = 0
|
|
||||||
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
||||||
self.stop_download
|
self.stop_download
|
||||||
self.is_pressed = False
|
self.is_pressed = False
|
||||||
|
|
||||||
def download_thread(self):
|
def download_thread(self):
|
||||||
try:
|
try:
|
||||||
global stopped
|
self.settings_tab.stopped = False
|
||||||
stopped = False
|
|
||||||
|
|
||||||
save_config("DestinationFolder" ,self.edit_destination_folder.get())
|
save_config("DestinationFolder" ,self.edit_destination_folder.get())
|
||||||
save_config("SteamCMDPath" ,self.edit_steamcmd_path.get())
|
save_config("SteamCMDPath" ,self.edit_steamcmd_path.get())
|
||||||
@ -2051,6 +2166,13 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.stop_download
|
self.stop_download
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if any(workshop_id in item for item in self.library_tab.added_items):
|
||||||
|
if self.settings_tab.skip_already_installed:
|
||||||
|
show_message("Heads up!, map skipped => Skip is on in settings", f"This item may already be installed, Stopping: {workshop_id}", icon="info")
|
||||||
|
self.stop_download
|
||||||
|
return
|
||||||
|
show_message("Heads up! map not skipped => Skip is off in settings", f"This item may already be installed: {workshop_id}", icon="info")
|
||||||
|
|
||||||
self.after(1, lambda mid=workshop_id: self.label_file_size.configure(text=f"File size: {get_workshop_file_size(mid ,raw=True)}"))
|
self.after(1, lambda mid=workshop_id: self.label_file_size.configure(text=f"File size: {get_workshop_file_size(mid ,raw=True)}"))
|
||||||
download_folder = os.path.join(get_steamcmd_path(), "steamapps", "workshop", "downloads", "311210", workshop_id)
|
download_folder = os.path.join(get_steamcmd_path(), "steamapps", "workshop", "downloads", "311210", workshop_id)
|
||||||
map_folder = os.path.join(get_steamcmd_path(), "steamapps", "workshop", "content", "311210", workshop_id)
|
map_folder = os.path.join(get_steamcmd_path(), "steamapps", "workshop", "content", "311210", workshop_id)
|
||||||
@ -2058,17 +2180,14 @@ class BOIIIWD(ctk.CTk):
|
|||||||
os.makedirs(download_folder)
|
os.makedirs(download_folder)
|
||||||
|
|
||||||
def check_and_update_progress():
|
def check_and_update_progress():
|
||||||
# delay untill steam boots up and starts downloading (ive a better idea ill implement it later)
|
|
||||||
time.sleep(8)
|
|
||||||
global stopped, steamcmd_reset
|
|
||||||
previous_net_speed = 0
|
previous_net_speed = 0
|
||||||
est_downloaded_bytes = 0
|
est_downloaded_bytes = 0
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
file_size = ws_file_size
|
file_size = ws_file_size
|
||||||
|
|
||||||
while not stopped:
|
while not self.settings_tab.stopped:
|
||||||
if steamcmd_reset:
|
if self.settings_tab.steamcmd_reset:
|
||||||
steamcmd_reset = False
|
self.settings_tab.steamcmd_reset = False
|
||||||
previous_net_speed = 0
|
previous_net_speed = 0
|
||||||
est_downloaded_bytes = 0
|
est_downloaded_bytes = 0
|
||||||
|
|
||||||
@ -2087,7 +2206,19 @@ class BOIIIWD(ctk.CTk):
|
|||||||
file_size = current_size
|
file_size = current_size
|
||||||
self.after(1, lambda p=progress: self.label_file_size.configure(text=f"Wrong size reported\nActual size: ~{convert_bytes_to_readable(current_size)}"))
|
self.after(1, lambda p=progress: self.label_file_size.configure(text=f"Wrong size reported\nActual size: ~{convert_bytes_to_readable(current_size)}"))
|
||||||
|
|
||||||
if estimated_progress:
|
while not self.is_downloading:
|
||||||
|
self.after(1, self.label_speed.configure(text=f"Network Speed: 0 KB/s"))
|
||||||
|
time_elapsed = time.time() - start_time
|
||||||
|
elapsed_hours, elapsed_minutes, elapsed_seconds = convert_seconds(time_elapsed)
|
||||||
|
if self.settings_tab.show_fails:
|
||||||
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {self.settings_tab.steam_fail_counter}"))
|
||||||
|
else:
|
||||||
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
||||||
|
time.sleep(1)
|
||||||
|
if self.is_downloading:
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.settings_tab.estimated_progress:
|
||||||
time_elapsed = time.time() - start_time
|
time_elapsed = time.time() - start_time
|
||||||
raw_net_speed = psutil.net_io_counters().bytes_recv
|
raw_net_speed = psutil.net_io_counters().bytes_recv
|
||||||
|
|
||||||
@ -2115,8 +2246,8 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.after(1, self.progress_bar.set(progress))
|
self.after(1, self.progress_bar.set(progress))
|
||||||
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
||||||
self.after(1, lambda p=min(percentage_complete ,99): self.progress_text.configure(text=f"{p:.2f}%"))
|
self.after(1, lambda p=min(percentage_complete ,99): self.progress_text.configure(text=f"{p:.2f}%"))
|
||||||
if show_fails:
|
if self.settings_tab.show_fails:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {steam_fail_counter}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {self.settings_tab.steam_fail_counter}"))
|
||||||
else:
|
else:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
||||||
|
|
||||||
@ -2136,14 +2267,14 @@ class BOIIIWD(ctk.CTk):
|
|||||||
|
|
||||||
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
self.after(1, lambda v=net_speed: self.label_speed.configure(text=f"Network Speed: {v:.2f} {speed_unit}"))
|
||||||
self.after(1, lambda p=progress: self.progress_text.configure(text=f"{p}%"))
|
self.after(1, lambda p=progress: self.progress_text.configure(text=f"{p}%"))
|
||||||
if show_fails:
|
if self.settings_tab.show_fails:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {steam_fail_counter}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d} - Fails: {self.settings_tab.steam_fail_counter}"))
|
||||||
else:
|
else:
|
||||||
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
self.after(1, lambda h=elapsed_hours, m=elapsed_minutes, s=elapsed_seconds: self.elapsed_time.configure(text=f"Elapsed Time: {int(h):02d}:{int(m):02d}:{int(s):02d}"))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
command = f"+login anonymous +@sSteamCmdForcePlatformBitness 64 +app_info_update 1 +app_info_print 311210 app_update 311210 +workshop_download_item 311210 {workshop_id} validate +quit"
|
command = f"+login anonymous app_update 311210 +workshop_download_item 311210 {workshop_id} validate +quit"
|
||||||
steamcmd_thread = threading.Thread(target=lambda: run_steamcmd_command(command, self, map_folder))
|
steamcmd_thread = threading.Thread(target=lambda: self.run_steamcmd_command(command, map_folder, workshop_id))
|
||||||
steamcmd_thread.start()
|
steamcmd_thread.start()
|
||||||
|
|
||||||
def wait_for_threads():
|
def wait_for_threads():
|
||||||
@ -2152,8 +2283,7 @@ class BOIIIWD(ctk.CTk):
|
|||||||
update_ui_thread.start()
|
update_ui_thread.start()
|
||||||
update_ui_thread.join()
|
update_ui_thread.join()
|
||||||
|
|
||||||
global stopped
|
self.settings_tab.stopped = True
|
||||||
stopped = True
|
|
||||||
|
|
||||||
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
||||||
self.progress_text.configure(text="0%")
|
self.progress_text.configure(text="0%")
|
||||||
@ -2185,11 +2315,11 @@ class BOIIIWD(ctk.CTk):
|
|||||||
except Exception as E:
|
except Exception as E:
|
||||||
show_message("Error", f"Error copying files: {E}", icon="cancel")
|
show_message("Error", f"Error copying files: {E}", icon="cancel")
|
||||||
|
|
||||||
if clean_on_finish:
|
if self.settings_tab.clean_on_finish:
|
||||||
remove_tree(map_folder)
|
remove_tree(map_folder)
|
||||||
remove_tree(download_folder)
|
remove_tree(download_folder)
|
||||||
|
|
||||||
msg = CTkMessagebox(title="Download Complete", message=f"{mod_type.capitalize()} files were downloaded\nYou can run the game now!", icon="info", option_1="Launch", option_2="Ok")
|
msg = CTkMessagebox(title="Download Complete", message=f"{mod_type.capitalize()} files were downloaded\nYou can run the game now!\nPS: You have to restart the game \n(pressing launch will launch/restarts)", icon="info", option_1="Launch", option_2="Ok")
|
||||||
response = msg.get()
|
response = msg.get()
|
||||||
if response=="Launch":
|
if response=="Launch":
|
||||||
launch_boiii_func(self.edit_destination_folder.get().strip())
|
launch_boiii_func(self.edit_destination_folder.get().strip())
|
||||||
@ -2206,17 +2336,16 @@ class BOIIIWD(ctk.CTk):
|
|||||||
self.button_stop.configure(state="normal")
|
self.button_stop.configure(state="normal")
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
global steam_fail_counter
|
self.settings_tab.steam_fail_counter = 0
|
||||||
steam_fail_counter = 0
|
|
||||||
self.stop_download
|
self.stop_download
|
||||||
self.is_pressed = False
|
self.is_pressed = False
|
||||||
|
|
||||||
def stop_download(self, on_close=None):
|
def stop_download(self, on_close=None):
|
||||||
global stopped, steam_fail_counter
|
self.settings_tab.stopped = True
|
||||||
stopped = True
|
|
||||||
self.queue_stop_button = True
|
self.queue_stop_button = True
|
||||||
steam_fail_counter = 0
|
self.settings_tab.steam_fail_counter = 0
|
||||||
self.is_pressed = False
|
self.is_pressed = False
|
||||||
|
self.is_downloading = False
|
||||||
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
||||||
|
|
||||||
if on_close:
|
if on_close:
|
||||||
|
BIN
dist/BOIIIWD.exe
vendored
BIN
dist/BOIIIWD.exe
vendored
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user