2023-09-20 14:35:02 +01:00
from src . update_window import check_for_updates_func
2023-08-31 22:07:52 +01:00
from src . imports import *
2023-09-20 02:28:20 -02:30
from src . helpers import *
2023-09-20 17:59:00 +01:00
import src . shared_vars as main_app
2023-08-31 22:07:52 +01:00
class SettingsTab ( ctk . CTkFrame ) :
def __init__ ( self , master = None ) :
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 = True
self . steam_fail_counter = 0
self . steam_fail_number = 10
self . steamcmd_reset = False
self . show_fails = True
2023-09-20 02:28:20 -02:30
self . check_items_on_launch = False
2023-08-31 22:07:52 +01:00
# Left and right frames, use fg_color="transparent"
self . grid_rowconfigure ( 0 , weight = 1 )
self . grid_columnconfigure ( 1 , weight = 1 )
self . grid_columnconfigure ( 0 , weight = 1 )
left_frame = ctk . CTkFrame ( self )
left_frame . grid ( row = 0 , column = 0 , padx = ( 20 , 20 ) , pady = ( 20 , 0 ) , sticky = " nsew " )
left_frame . grid_columnconfigure ( 1 , weight = 1 )
right_frame = ctk . CTkFrame ( self )
right_frame . grid ( row = 0 , column = 1 , padx = ( 20 , 20 ) , pady = ( 20 , 0 ) , sticky = " nsew " )
right_frame . grid_columnconfigure ( 1 , weight = 1 )
self . update_idletasks ( )
# Check for updates checkbox
self . check_updates_var = ctk . BooleanVar ( )
self . check_updates_var . trace_add ( " write " , self . enable_save_button )
self . check_updates_checkbox = ctk . CTkSwitch ( left_frame , text = " Check for updates on launch " , variable = self . check_updates_var )
self . check_updates_checkbox . grid ( row = 0 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
self . check_updates_var . set ( self . load_settings ( " checkforupdates " ) )
# Show console checkbox
self . console_var = ctk . BooleanVar ( )
self . console_var . trace_add ( " write " , self . enable_save_button )
self . checkbox_show_console = ctk . CTkSwitch ( left_frame , text = " Console (On Download) " , variable = self . console_var )
self . checkbox_show_console . grid ( row = 1 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
self . checkbox_show_console_tooltip = CTkToolTip ( self . checkbox_show_console , message = " Toggle SteamCMD console \n Please don ' t close the Console If you want to stop press the Stop button " )
2023-08-31 22:07:52 +01:00
self . console_var . set ( self . load_settings ( " console " ) )
# Show continuous checkbox
self . continuous_var = ctk . BooleanVar ( )
self . continuous_var . trace_add ( " write " , self . enable_save_button )
self . checkbox_continuous = ctk . CTkSwitch ( left_frame , text = " Continuous Download " , variable = self . continuous_var )
self . checkbox_continuous . grid ( row = 2 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
self . checkbox_continuous_tooltip = CTkToolTip ( self . checkbox_continuous , message = " This will make sure that the download restarts and resumes! until it finishes if steamcmd crashes randomly (it will not redownload from the start) " )
2023-08-31 22:07:52 +01:00
self . continuous_var . set ( self . load_settings ( " continuous_download " ) )
# clean on finish checkbox
self . clean_checkbox_var = ctk . BooleanVar ( )
self . clean_checkbox_var . trace_add ( " write " , self . enable_save_button )
self . clean_checkbox = ctk . CTkSwitch ( left_frame , text = " Clean on finish " , variable = self . clean_checkbox_var )
self . clean_checkbox . grid ( row = 3 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
self . clean_checkbox_tooltip = CTkToolTip ( self . clean_checkbox , message = " Cleans the map that have been downloaded and installed from steamcmd ' s steamapps folder ,to save space " )
2023-08-31 22:07:52 +01:00
self . clean_checkbox_var . set ( self . load_settings ( " clean_on_finish " , " on " ) )
# Show estimated_progress checkbox
self . estimated_progress_var = ctk . BooleanVar ( )
self . estimated_progress_var . trace_add ( " write " , self . enable_save_button )
self . estimated_progress_cb = ctk . CTkSwitch ( left_frame , text = " Estimated Progress Bar " , variable = self . estimated_progress_var )
self . estimated_progress_cb . grid ( row = 4 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
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 \
2023-08-31 22:07:52 +01:00
\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 " ) )
# Show show fails checkbox
self . show_fails_var = ctk . BooleanVar ( )
self . show_fails_var . trace_add ( " write " , self . enable_save_button )
2023-09-20 02:28:20 -02:30
self . show_fails_cb = ctk . CTkSwitch ( left_frame , text = " Show fails (on top of progress bar) " , variable = self . show_fails_var )
2023-08-31 22:07:52 +01:00
self . show_fails_cb . grid ( row = 5 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
self . show_fails_tooltip = CTkToolTip ( self . show_fails_cb , message = " Display how many times steamcmd has failed/crashed \n If the number is getting high quickly then try pressing Reset SteamCMD and try again, otherwise its fine " )
2023-08-31 22:07:52 +01:00
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 )
2023-09-20 02:28:20 -02:30
self . skip_already_installed_ch = ctk . CTkSwitch ( left_frame , text = " Skip already installed maps " , variable = self . skip_already_installed_var )
2023-08-31 22:07:52 +01:00
self . skip_already_installed_ch . grid ( row = 6 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
self . skip_already_installed_ch_tooltip = CTkToolTip ( self . skip_already_installed_ch , message = " If on it will not download installed maps, \n this can miss sometimes if you remove maps manually and not from library tab while the app is running " )
2023-08-31 22:07:52 +01:00
self . skip_already_installed_var . set ( self . load_settings ( " skip_already_installed " , " on " ) )
2023-09-20 02:28:20 -02:30
# check items for update on launch
self . check_items_var = ctk . BooleanVar ( )
self . check_items_var . trace_add ( " write " , self . enable_save_button )
self . check_items_ch = ctk . CTkSwitch ( left_frame , text = " Check Library items on launch " , variable = self . check_items_var )
self . check_items_ch . grid ( row = 7 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
self . check_items_tooltip = CTkToolTip ( self . check_items_ch , message = " This will show a window on launch of items that have pending updates -> you can open it manually from library tab " )
2023-09-20 02:28:20 -02:30
self . check_items_var . set ( self . load_settings ( " check_items " , " off " ) )
2023-08-31 22:07:52 +01:00
# Resetr steam on many fails
self . reset_steamcmd_on_fail_var = ctk . IntVar ( )
self . reset_steamcmd_on_fail_var . trace_add ( " write " , self . enable_save_button )
2023-09-20 02:28:20 -02:30
self . reset_steamcmd_on_fail_text = ctk . CTkLabel ( left_frame , text = f " Reset steamcmd: (n of fails): " , anchor = " w " )
self . reset_steamcmd_on_fail_text . grid ( row = 8 , column = 1 , padx = 20 , pady = ( 10 , 0 ) , sticky = " nw " )
2023-08-31 22:07:52 +01:00
self . reset_steamcmd_on_fail = ctk . CTkOptionMenu ( left_frame , values = [ " 5 " , " 10 " , " 20 " , " 30 " , " 40 " , " Custom " , " Disable " ] , variable = self . reset_steamcmd_on_fail_var , command = self . reset_steamcmd_on_fail_func )
2023-09-20 02:28:20 -02:30
self . reset_steamcmd_on_fail . grid ( row = 8 , column = 1 , padx = ( 190 , 0 ) , pady = ( 10 , 0 ) , sticky = " nw " )
2023-09-20 16:18:57 +01:00
self . reset_steamcmd_on_fail_tooltip = CTkToolTip ( self . reset_steamcmd_on_fail , message = " This actually fixes steamcmd when its crashing way too much " )
2023-08-31 22:07:52 +01:00
self . reset_steamcmd_on_fail . set ( value = self . load_settings ( " reset_on_fail " , " 10 " ) )
2023-09-20 02:28:20 -02:30
# item folder naming
self . folder_options_label_var = ctk . IntVar ( )
self . folder_options_label_var . trace_add ( " write " , self . enable_save_button )
self . folder_options_label = ctk . CTkLabel ( left_frame , text = " Items Folder Naming: " , anchor = " nw " )
self . folder_options_label . grid ( row = 10 , column = 1 , padx = 20 , pady = ( 10 , 0 ) , sticky = " nw " )
self . folder_options = ctk . CTkOptionMenu ( left_frame , values = [ " PublisherID " , " FolderName " ] , variable = self . folder_options_label_var )
self . folder_options . grid ( row = 10 , column = 1 , padx = ( 150 , 0 ) , pady = ( 3 , 0 ) , sticky = " nw " )
self . folder_options . set ( value = self . load_settings ( " folder_naming " , " PublisherID " ) )
2023-08-31 22:07:52 +01:00
# Check for updates button n Launch boiii
self . check_for_updates = ctk . CTkButton ( right_frame , text = " Check for updates " , command = self . settings_check_for_updates )
self . check_for_updates . grid ( row = 1 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " n " )
self . launch_boiii = ctk . CTkButton ( right_frame , text = " Launch boiii " , command = self . settings_launch_boiii )
self . launch_boiii . grid ( row = 2 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " n " )
self . reset_steamcmd = ctk . CTkButton ( right_frame , text = " Reset SteamCMD " , command = self . settings_reset_steamcmd )
self . reset_steamcmd . grid ( row = 3 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " n " )
2023-09-20 16:18:57 +01:00
self . reset_steamcmd_tooltip = CTkToolTip ( self . reset_steamcmd , message = " This will remove steamapps folder + all the maps that are potentioaly corrupted \n or not so use at ur own risk (could fix some issues as well) " )
2023-09-20 02:28:20 -02:30
self . steam_to_boiii = ctk . CTkButton ( right_frame , text = " Steam to boiii " , command = self . from_steam_to_boiii_toplevel )
self . steam_to_boiii . grid ( row = 5 , column = 1 , padx = 20 , pady = ( 20 , 0 ) , sticky = " n " )
2023-09-20 16:18:57 +01:00
self . steam_to_boiii_tooltip = CTkToolTip ( self . steam_to_boiii , message = " Moves/copies maps and mods from steam to boiii (opens up a window) " )
2023-08-31 22:07:52 +01:00
# appearance
self . appearance_mode_label = ctk . CTkLabel ( right_frame , text = " Appearance Mode: " , anchor = " n " )
2023-09-20 02:28:20 -02:30
self . appearance_mode_label . grid ( row = 6 , column = 1 , padx = 20 , pady = ( 20 , 0 ) )
2023-08-31 22:07:52 +01:00
self . appearance_mode_optionemenu = ctk . CTkOptionMenu ( right_frame , values = [ " Light " , " Dark " , " System " ] ,
command = master . change_appearance_mode_event )
2023-09-20 02:28:20 -02:30
self . appearance_mode_optionemenu . grid ( row = 7 , column = 1 , padx = 20 , pady = ( 0 , 0 ) )
2023-08-31 22:07:52 +01:00
self . scaling_label = ctk . CTkLabel ( right_frame , text = " UI Scaling: " , anchor = " n " )
2023-09-20 02:28:20 -02:30
self . scaling_label . grid ( row = 8 , column = 1 , padx = 20 , pady = ( 10 , 0 ) )
2023-08-31 22:07:52 +01:00
self . scaling_optionemenu = ctk . CTkOptionMenu ( right_frame , values = [ " 80 % " , " 90 % " , " 100 % " , " 110 % " , " 120 % " ] ,
command = master . change_scaling_event )
2023-09-20 02:28:20 -02:30
self . scaling_optionemenu . grid ( row = 9 , column = 1 , padx = 20 , pady = ( 0 , 0 ) )
2023-08-31 22:07:52 +01:00
# self.custom_theme = ctk.CTkButton(right_frame, text="Custom theme", command=self.boiiiwd_custom_theme)
# self.custom_theme.grid(row=8, column=1, padx=20, pady=(20, 0), sticky="n")
self . theme_options_label = ctk . CTkLabel ( right_frame , text = " Themes: " , anchor = " n " )
2023-09-20 02:28:20 -02:30
self . theme_options_label . grid ( row = 10 , column = 1 , padx = 20 , pady = ( 10 , 0 ) )
2023-09-02 17:03:25 +01:00
self . theme_options = ctk . CTkOptionMenu ( right_frame , values = [ " Default " , " Blue " , " Grey " , " Obsidian " , " Ghost " , " NeonBanana " , " Custom " ] ,
2023-08-31 22:07:52 +01:00
command = self . theme_options_func )
2023-09-20 02:28:20 -02:30
self . theme_options . grid ( row = 11 , column = 1 , padx = 20 , pady = ( 0 , 0 ) )
2023-08-31 22:07:52 +01:00
self . theme_options . set ( value = self . load_settings ( " theme " , " Default " ) )
# Save button
self . save_button = ctk . CTkButton ( self , text = " Save " , command = self . save_settings , state = ' disabled ' )
self . save_button . grid ( row = 3 , column = 0 , padx = 20 , pady = ( 20 , 20 ) , sticky = " nw " )
#version
self . version_info = ctk . CTkLabel ( self , text = f " { VERSION } " )
self . version_info . grid ( row = 3 , column = 1 , padx = 20 , pady = ( 20 , 20 ) , sticky = " e " )
def reset_steamcmd_on_fail_func ( self , option : str ) :
if option == " Custom " :
try :
save_config ( " reset_on_fail " , " 10 " )
2023-09-04 01:35:00 +01:00
def callback ( ) :
msg = CTkMessagebox ( title = " config.ini " , message = " change reset_on_fail value to whatever you want " , icon = " info " , option_1 = " No " , option_2 = " Ok " , sound = True )
response = msg . get ( )
if response == " No " :
return
elif response == " Ok " :
2023-09-20 14:35:02 +01:00
os . system ( f " notepad { os . path . join ( application_path , ' config.ini ' ) } " )
2023-09-04 01:35:00 +01:00
else :
return
self . after ( 0 , callback )
2023-08-31 22:07:52 +01:00
except :
show_message ( " Couldn ' t open config.ini " , " you can do so by yourself and change reset_on_fail value to whatever you want " )
else :
2023-09-04 01:35:00 +01:00
return
2023-08-31 22:07:52 +01:00
def theme_options_func ( self , option : str ) :
if option == " Default " :
self . boiiiwd_custom_theme ( disable_only = True )
save_config ( " theme " , " boiiiwd_theme.json " )
if option == " Blue " :
self . boiiiwd_custom_theme ( disable_only = True )
save_config ( " theme " , " boiiiwd_blue.json " )
if option == " Grey " :
self . boiiiwd_custom_theme ( disable_only = True )
save_config ( " theme " , " boiiiwd_grey.json " )
2023-09-02 17:03:25 +01:00
if option == " Ghost " :
self . boiiiwd_custom_theme ( disable_only = True )
save_config ( " theme " , " boiiiwd_ghost.json " )
if option == " Obsidian " :
self . boiiiwd_custom_theme ( disable_only = True )
save_config ( " theme " , " boiiiwd_obsidian.json " )
if option == " NeonBanana " :
self . boiiiwd_custom_theme ( disable_only = True )
save_config ( " theme " , " boiiiwd_neonbanana.json " )
2023-08-31 22:07:52 +01:00
if option == " Custom " :
self . boiiiwd_custom_theme ( )
save_config ( " theme " , " boiiiwd_theme.json " )
if not option == " Custom " :
2023-09-07 14:58:08 +01:00
if show_message ( " Restart to take effect! " , f " { option } theme has been set ,please restart to take effect " , icon = " info " , _return = True , option_1 = " Ok " , option_2 = " Restart " ) :
try :
p = psutil . Process ( os . getpid ( ) )
for handler in p . open_files ( ) + p . connections ( ) :
os . close ( handler . fd )
except Exception :
pass
python = sys . executable
os . execl ( python , python , * sys . argv )
else :
pass
2023-08-31 22:07:52 +01:00
def enable_save_button ( self , * args ) :
2023-09-20 14:44:00 +01:00
try : self . save_button . configure ( state = ' normal ' )
except : pass
2023-08-31 22:07:52 +01:00
def save_settings ( self ) :
self . save_button . configure ( state = ' disabled ' )
2023-09-20 02:28:20 -02:30
if self . folder_options . get ( ) == " PublisherID " :
save_config ( " folder_naming " , " 0 " )
else :
save_config ( " folder_naming " , " 1 " )
if self . check_items_var . get ( ) :
save_config ( " check_items " , " on " )
else :
save_config ( " check_items " , " off " )
2023-08-31 22:07:52 +01:00
if self . check_updates_checkbox . get ( ) :
save_config ( " checkforupdtes " , " on " )
else :
save_config ( " checkforupdtes " , " off " )
if self . checkbox_show_console . get ( ) :
save_config ( " console " , " on " )
self . console = True
else :
save_config ( " console " , " off " )
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 ( ) :
save_config ( " clean_on_finish " , " on " )
self . clean_on_finish = True
else :
save_config ( " clean_on_finish " , " off " )
self . clean_on_finish = False
if self . checkbox_continuous . get ( ) :
save_config ( " continuous_download " , " on " )
self . continuous = True
else :
save_config ( " continuous_download " , " off " )
self . continuous = False
if self . estimated_progress_cb . get ( ) :
save_config ( " estimated_progress " , " on " )
self . estimated_progress = True
else :
save_config ( " estimated_progress " , " off " )
self . estimated_progress = False
if self . show_fails_cb . get ( ) :
save_config ( " show_fails " , " on " )
self . show_fails = True
else :
save_config ( " show_fails " , " off " )
self . show_fails = False
if self . reset_steamcmd_on_fail . get ( ) :
value = self . reset_steamcmd_on_fail . get ( )
if value == " Disable " :
self . steam_fail_counter_toggle = False
else :
self . steam_fail_counter_toggle = True
self . steam_fail_number = int ( value )
save_config ( " reset_on_fail " , value )
def load_settings ( self , setting , fallback = None ) :
2023-09-20 02:28:20 -02:30
if setting == " folder_naming " :
if check_config ( setting , fallback ) == " 1 " :
return " FolderName "
else :
return " PublisherID "
2023-08-31 22:07:52 +01:00
if setting == " console " :
if check_config ( setting , fallback ) == " on " :
self . console = True
return 1
else :
self . console = False
return 0
if setting == " continuous_download " :
if check_config ( setting , " on " ) == " on " :
self . continuous = True
return 1
else :
self . continuous = False
return 0
if setting == " clean_on_finish " :
if check_config ( setting , fallback ) == " on " :
self . clean_on_finish = True
return 1
else :
self . clean_on_finish = False
return 0
if setting == " estimated_progress " :
if check_config ( setting , fallback ) == " on " :
self . estimated_progress = True
return 1
else :
self . estimated_progress = False
return 0
if setting == " reset_on_fail " :
option = check_config ( setting , fallback )
if option == " Disable " or option == " Custom " :
self . steam_fail_counter_toggle = False
return " Disable "
else :
try :
self . steam_fail_number = int ( option )
self . steam_fail_counter_toggle = True
return option
except :
self . steam_fail_counter_toggle = True
self . steam_fail_number = 10
return " 10 "
if setting == " show_fails " :
if check_config ( setting , fallback ) == " on " :
self . show_fails = True
return 1
else :
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
if setting == " theme " :
2023-09-20 14:35:02 +01:00
if os . path . exists ( os . path . join ( application_path , " boiiiwd_theme.json " ) ) :
2023-08-31 22:07:52 +01:00
return " Custom "
if check_config ( " theme " , " boiiiwd_theme.json " ) == " boiiiwd_theme.json " :
return " Default "
if check_config ( " theme " , " boiiiwd_theme.json " ) == " boiiiwd_grey.json " :
return " Grey "
if check_config ( " theme " , " boiiiwd_theme.json " ) == " boiiiwd_blue.json " :
return " Blue "
2023-09-02 17:03:25 +01:00
if check_config ( " theme " , " boiiiwd_theme.json " ) == " boiiiwd_obsidian.json " :
return " Obsidian "
if check_config ( " theme " , " boiiiwd_theme.json " ) == " boiiiwd_ghost.json " :
return " Ghost "
if check_config ( " theme " , " boiiiwd_theme.json " ) == " boiiiwd_neonbanana.json " :
return " NeonBanana "
2023-08-31 22:07:52 +01:00
else :
if check_config ( setting , fallback ) == " on " :
return 1
else :
return 0
def boiiiwd_custom_theme ( self , disable_only = None ) :
2023-09-20 14:35:02 +01:00
file_to_rename = os . path . join ( application_path , " boiiiwd_theme.json " )
2023-08-31 22:07:52 +01:00
if os . path . exists ( file_to_rename ) :
2023-09-20 02:28:20 -02:30
timestamp = datetime . now ( ) . strftime ( " % Y- % m- %d - % H- % M- % S " )
2023-08-31 22:07:52 +01:00
new_name = f " boiiiwd_theme_ { timestamp } .json "
2023-09-20 14:35:02 +01:00
os . rename ( file_to_rename , os . path . join ( application_path , new_name ) )
2023-08-31 22:07:52 +01:00
if not disable_only :
show_message ( " Preset file renamed " , " Custom preset disabled, file has been renmaed \n * Restart the app to take effect " , icon = " info " )
else :
if disable_only :
return
try :
2023-09-20 14:35:02 +01:00
shutil . copy ( os . path . join ( RESOURCES_DIR , check_config ( " theme " , " boiiiwd_theme.json " ) ) , os . path . join ( application_path , " boiiiwd_theme.json " ) )
2023-08-31 22:07:52 +01:00
except :
2023-09-20 14:35:02 +01:00
shutil . copy ( os . path . join ( RESOURCES_DIR , " boiiiwd_theme.json " ) , os . path . join ( application_path , " boiiiwd_theme.json " ) )
2023-08-31 22:07:52 +01:00
show_message ( " Preset file created " , " You can now edit boiiiwd_theme.json in the current directory to your liking \n * Edits will apply next time you open boiiiwd \n * Program will always take boiiiwd_theme.json as the first theme option if found \n * Click on this button again to disable your custom theme or just rename boiiiwd_theme.json " , icon = " info " )
def settings_check_for_updates ( self ) :
check_for_updates_func ( self , ignore_up_todate = False )
def load_on_switch_screen ( self ) :
self . check_updates_var . set ( self . load_settings ( " checkforupdtes " ) )
self . console_var . set ( self . load_settings ( " console " ) )
self . reset_steamcmd_on_fail . set ( value = self . load_settings ( " reset_on_fail " , " 10 " ) )
self . estimated_progress_var . set ( self . load_settings ( " estimated_progress " , " on " ) )
self . clean_checkbox_var . set ( self . load_settings ( " clean_on_finish " , " on " ) )
self . continuous_var . set ( self . load_settings ( " continuous_download " ) )
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()
self . save_button . configure ( state = ' disabled ' )
def settings_launch_boiii ( self ) :
launch_boiii_func ( check_config ( " destinationfolder " ) )
def settings_reset_steamcmd ( self ) :
reset_steamcmd ( )
2023-09-20 02:28:20 -02:30
def from_steam_to_boiii_toplevel ( self ) :
def main_thread ( ) :
try :
top = ctk . CTkToplevel ( self )
if os . path . exists ( os . path . join ( RESOURCES_DIR , " ryuk.ico " ) ) :
top . after ( 210 , lambda : top . iconbitmap ( os . path . join ( RESOURCES_DIR , " ryuk.ico " ) ) )
top . title ( " Steam to boiii -> Workshop items " )
top . attributes ( ' -topmost ' , ' true ' )
top . resizable ( False , False )
# Create input boxes
center_frame = ctk . CTkFrame ( top )
center_frame . grid ( row = 0 , column = 0 , padx = 20 , pady = 20 )
# Create input boxes
steam_folder_label = ctk . CTkLabel ( center_frame , text = " Steam Folder: " )
steam_folder_label . grid ( row = 0 , column = 0 , padx = ( 20 , 20 ) , pady = ( 10 , 0 ) , sticky = ' w ' )
steam_folder_entry = ctk . CTkEntry ( center_frame , width = 225 )
steam_folder_entry . grid ( row = 1 , column = 0 , columnspan = 2 , padx = ( 0 , 20 ) , pady = ( 10 , 10 ) , sticky = ' nes ' )
button_steam_browse = ctk . CTkButton ( center_frame , text = " Select " , width = 10 )
button_steam_browse . grid ( row = 1 , column = 2 , padx = ( 0 , 20 ) , pady = ( 10 , 10 ) , sticky = " wnes " )
boiii_folder_label = ctk . CTkLabel ( center_frame , text = " boiii Folder: " )
boiii_folder_label . grid ( row = 2 , column = 0 , padx = ( 20 , 20 ) , pady = ( 10 , 0 ) , sticky = ' w ' )
boiii_folder_entry = ctk . CTkEntry ( center_frame , width = 225 )
boiii_folder_entry . grid ( row = 3 , column = 0 , columnspan = 2 , padx = ( 0 , 20 ) , pady = ( 10 , 10 ) , sticky = ' nes ' )
button_BOIII_browse = ctk . CTkButton ( center_frame , text = " Select " , width = 10 )
button_BOIII_browse . grid ( row = 3 , column = 2 , padx = ( 0 , 20 ) , pady = ( 10 , 10 ) , sticky = " wnes " )
# Create option to choose between cut or copy
operation_label = ctk . CTkLabel ( center_frame , text = " Choose operation: " )
operation_label . grid ( row = 4 , column = 0 , padx = ( 20 , 20 ) , pady = ( 10 , 10 ) , sticky = ' wnes ' )
copy_var = ctk . BooleanVar ( )
cut_var = ctk . BooleanVar ( )
copy_check = ctk . CTkCheckBox ( center_frame , text = " Copy " , variable = copy_var )
cut_check = ctk . CTkCheckBox ( center_frame , text = " Cut " , variable = cut_var )
copy_check . grid ( row = 4 , column = 1 , padx = ( 0 , 10 ) , pady = ( 10 , 10 ) , sticky = ' wnes ' )
cut_check . grid ( row = 4 , column = 2 , padx = ( 0 , 10 ) , pady = ( 10 , 10 ) , sticky = ' nes ' )
# Create progress bar
progress_bar = ctk . CTkProgressBar ( center_frame , mode = " determinate " , height = 20 , corner_radius = 7 )
progress_bar . grid ( row = 5 , column = 0 , columnspan = 3 , padx = ( 20 , 20 ) , pady = ( 10 , 10 ) , sticky = ' wnes ' )
progress_text = ctk . CTkLabel ( progress_bar , text = " 0 % " , font = ( " Helvetica " , 12 ) , fg_color = " transparent " , text_color = " white " , height = 0 , width = 0 , corner_radius = 0 )
progress_text . place ( relx = 0.5 , rely = 0.5 , anchor = " center " )
copy_button = ctk . CTkButton ( center_frame , text = " Start (Copy) " )
copy_button . grid ( row = 6 , column = 0 , columnspan = 3 , padx = ( 20 , 20 ) , pady = ( 10 , 10 ) , sticky = ' wnes ' )
# funcs
# had to use this shit again cuz of threading issues with widgets
def copy_with_progress ( src , dst ) :
try :
total_files = sum ( [ len ( files ) for root , dirs , files in os . walk ( src ) ] )
progress = 0
def copy_progress ( src , dst ) :
nonlocal progress
shutil . copy2 ( src , dst )
progress + = 1
top . after ( 0 , progress_text . configure ( text = f " Copying files: { progress } / { total_files } " ) )
value = ( progress / total_files ) * 100
valuep = value / 100
progress_bar . set ( valuep )
try :
shutil . copytree ( src , dst , dirs_exist_ok = True , copy_function = copy_progress )
except Exception as E :
show_message ( " Error " , f " Error copying files: { E } " , icon = " cancel " )
finally :
top . after ( 0 , progress_text . configure ( text = " 0 % " ) )
top . after ( 0 , progress_bar . set ( 0.0 ) )
def check_status ( var , op_var ) :
if var . get ( ) :
op_var . set ( False )
if cut_var . get ( ) :
copy_button . configure ( text = f " Start (Cut) " )
if copy_var . get ( ) :
copy_button . configure ( text = f " Start (Copy) " )
def open_BOIII_browser ( ) :
selected_folder = ctk . filedialog . askdirectory ( title = " Select boiii Folder " )
if selected_folder :
boiii_folder_entry . delete ( 0 , " end " )
boiii_folder_entry . insert ( 0 , selected_folder )
def open_steam_browser ( ) :
selected_folder = ctk . filedialog . askdirectory ( title = " Select Steam Folder (ex: C: \ Program Files (x86) \ Steam) " )
if selected_folder :
steam_folder_entry . delete ( 0 , " end " )
steam_folder_entry . insert ( 0 , selected_folder )
save_config ( " steam_folder " , steam_folder_entry . get ( ) )
def start_copy_operation ( ) :
def start_thread ( ) :
try :
if not cut_var . get ( ) and not copy_var . get ( ) :
show_message ( " Choose operation! " , " Please choose an operation, Copy or Cut files from steam! " )
return
copy_button . configure ( state = " disabled " )
steam_folder = steam_folder_entry . get ( )
ws_folder = os . path . join ( steam_folder , " steamapps/workshop/content/311210 " )
boiii_folder = boiii_folder_entry . get ( )
if not os . path . exists ( steam_folder ) and not os . path . exists ( ws_folder ) :
show_message ( " Not found " , " Either you have no items downloaded from Steam or wrong path, please recheck path (ex: C: \ Program Files (x86) \ Steam) " )
return
if not os . path . exists ( boiii_folder ) :
show_message ( " Not found " , " boiii folder not found, please recheck path " )
return
top . after ( 0 , progress_text . configure ( text = " Loading... " ) )
map_folder = os . path . join ( ws_folder )
subfolders = [ f for f in os . listdir ( map_folder ) if os . path . isdir ( os . path . join ( map_folder , f ) ) ]
total_folders = len ( subfolders )
if not subfolders :
show_message ( " No items found " , f " No items found in \n { map_folder } " )
return
for i , workshop_id in enumerate ( subfolders , start = 1 ) :
json_file_path = os . path . join ( map_folder , workshop_id , " workshop.json " )
copy_button . configure ( text = f " Working on -> { i } / { total_folders } " )
if os . path . exists ( json_file_path ) :
mod_type = extract_json_data ( json_file_path , " Type " )
2023-09-20 14:35:02 +01:00
items_file = os . path . join ( application_path , LIBRARY_FILE )
2023-09-20 02:28:20 -02:30
2023-09-20 17:59:00 +01:00
if main_app . app . library_tab . item_exists_in_file ( items_file , workshop_id ) :
get_folder_name = main_app . app . library_tab . get_item_by_id ( items_file , workshop_id , return_option = " folder_name " )
2023-09-20 02:28:20 -02:30
if get_folder_name :
folder_name = get_folder_name
else :
try :
2023-09-20 17:59:00 +01:00
folder_name = extract_json_data ( json_file_path , main_app . app . settings_tab . folder_options . get ( ) )
2023-09-20 02:28:20 -02:30
except :
folder_name = extract_json_data ( json_file_path , " publisherID " )
else :
try :
2023-09-20 17:59:00 +01:00
folder_name = extract_json_data ( json_file_path , main_app . app . settings_tab . folder_options . get ( ) )
2023-09-20 02:28:20 -02:30
except :
folder_name = extract_json_data ( json_file_path , " publisherID " )
if mod_type == " mod " :
mods_folder = os . path . join ( boiii_folder , " mods " )
folder_name_path = os . path . join ( mods_folder , folder_name , " zone " )
elif mod_type == " map " :
usermaps_folder = os . path . join ( boiii_folder , " usermaps " )
folder_name_path = os . path . join ( usermaps_folder , folder_name , " zone " )
else :
show_message ( " Error " , " Invalid workshop type in workshop.json, are you sure this is a map or a mod?. " , icon = " cancel " )
continue
os . makedirs ( folder_name_path , exist_ok = True )
try :
copy_with_progress ( os . path . join ( map_folder , workshop_id ) , folder_name_path )
except Exception as E :
show_message ( " Error " , f " Error copying files: { E } " , icon = " cancel " )
continue
if cut_var . get ( ) :
remove_tree ( os . path . join ( map_folder , workshop_id ) )
if subfolders :
2023-09-20 17:59:00 +01:00
main_app . app . show_complete_message ( message = f " All items were moved \n You can run the game now! \n PS: You have to restart the game \n (pressing launch will launch/restarts) " )
2023-09-20 02:28:20 -02:30
finally :
if cut_var . get ( ) :
copy_button . configure ( text = f " Start (Cut) " )
if copy_var . get ( ) :
copy_button . configure ( text = f " Start (Copy) " )
copy_button . configure ( state = " normal " )
top . after ( 0 , progress_bar . set ( 0 ) )
top . after ( 0 , progress_text . configure ( text = " 0 % " ) )
# prevents app hanging
threading . Thread ( target = start_thread ) . start ( )
# config
progress_color = get_button_state_colors ( check_custom_theme ( check_config ( " theme " , fallback = " boiiiwd_theme.json " ) ) , " progress_bar_fill_color " )
progress_bar . configure ( progress_color = progress_color )
steam_folder_entry . insert ( 1 , check_config ( " steam_folder " , " " ) )
2023-09-20 17:59:00 +01:00
boiii_folder_entry . insert ( 1 , main_app . app . edit_destination_folder . get ( ) )
2023-09-20 02:28:20 -02:30
button_BOIII_browse . configure ( command = open_BOIII_browser )
button_steam_browse . configure ( command = open_steam_browser )
copy_button . configure ( command = start_copy_operation )
cut_check . configure ( command = lambda : check_status ( cut_var , copy_var ) )
copy_check . configure ( command = lambda : check_status ( copy_var , cut_var ) )
2023-09-20 17:59:00 +01:00
main_app . app . create_context_menu ( steam_folder_entry )
main_app . app . create_context_menu ( boiii_folder_entry )
2023-09-20 02:28:20 -02:30
copy_var . set ( True )
progress_bar . set ( 0 )
except Exception as e :
show_message ( " Error " , f " { e } " , icon = " cancel " )
2023-09-20 17:59:00 +01:00
main_app . app . after ( 0 , main_thread )