From 2404d90f93db7df32ea36b11b68cae915301604e Mon Sep 17 00:00:00 2001 From: Mohd Ali Date: Mon, 6 Feb 2023 23:00:37 -0500 Subject: [PATCH 1/5] initial --- b2.bat | 6 +-- orb.py | 138 ++++----------------------------------------------------- 2 files changed, 12 insertions(+), 132 deletions(-) diff --git a/b2.bat b/b2.bat index 15d1640..c5e0883 100644 --- a/b2.bat +++ b/b2.bat @@ -1,3 +1,3 @@ -C:\Users\lenovo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\Scripts\pyinstaller.exe --distpath \\wsl$\Ubuntu\home\mohd\projects\orbiter-mods.com\dist --specpath \\wsl$\Ubuntu\home\mohd\projects\orbiter-mods.com\ --paths=C:\Users\lenovo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages --hidden-import tkinter --noconfirm \\wsl$\Ubuntu\home\mohd\projects\orbiter-mods.com\orb.py -copy \\wsl$\Ubuntu\home\mohd\projects\orbiter-mods.com\orb.py E:\Orbiter2016 -xcopy \\wsl$\Ubuntu\home\mohd\projects\orbiter-mods.com\dist\orb E:\Orbiter2016\ /E/H \ No newline at end of file +C:\Users\mohd\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\Scripts\pyinstaller.exe --distpath C:\projects\orbiter-mods.com\dist --specpath C:\projects\orbiter-mods.com\ --paths=C:\Users\mohd\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages --hidden-import tkinter --noconfirm .\orb.py +copy C:\projects\orbiter-mods.com\orb.py C:\projects\orbiter-mods.com-test +xcopy C:\projects\orbiter-mods.com\dist\orb C:\projects\orbiter-mods.com-test\orb /E/H \ No newline at end of file diff --git a/orb.py b/orb.py index c609987..c1cc754 100644 --- a/orb.py +++ b/orb.py @@ -86,105 +86,6 @@ def get_download_folder_path(): return os.path.join(os.environ['USERPROFILE'], 'Downloads') else: return os.path.join(os.environ['HOME'], 'Downloads') - -def should_generate_hash(path): - # check if path is a dir or file - if path.is_dir(): - return False - # check if path is a .py file - if path.suffix == '.py': - return False - # skip orb.exe - if path.name == 'orb.exe': - return False - # skip orb - if path.name == 'orb': - return False - if path.name == 'Orbiter2016.json': - return False - if path.name == 'Orbiter.cfg': - return False - if path.name == 'Orbiter_NG.cfg': - return False - - full_path = str(path) - # skip orb_cache - if full_path.startswith('./orb_cache') or full_path.startswith('orb_cache'): - return False - return True - -def generate_file_hash(full_path): - with open(full_path, 'rb') as f: - content = f.read() - # generate md5 hash for content string - return hashlib.md5(content).hexdigest() - -def generate_orbiter_hash(output_hash_file): - files = {} - for path in Path('./').rglob('*.*'): - try: - if not should_generate_hash(path): - continue - # get full path name - full_path = str(path) - files[full_path] = generate_file_hash(full_path) - print(full_path) - except Exception as e: - print(e) - with open(output_hash_file, 'w') as f: - json.dump(files, f) - -def verify_orbiter_hash(hash_file): - with open(hash_file, 'r') as f: - files = json.load(f) - files_to_revert = [] - for path in Path('./').rglob('*.*'): - try: - if not should_generate_hash(path): - continue - # get full path name - full_path = str(path) - if full_path not in files: - print(f'{full_path} is not in the hash file') - continue - if files[full_path] != generate_file_hash(full_path): - print(f'{full_path} has changed') - files_to_revert.append(full_path) - except Exception as e: - print(e) - return files_to_revert - -def download_orbiter_2016_if_needed(orb): - # check if orbiter 2016 is already downloaded and unzipped in orb_cache - if os.path.exists('./orb_cache/Orbiter2016'): - pass - else: - # check if Orbiter2016.zip is in orb_cache - if is_file_cached('Orbiter2016.zip'): - print('Orbiter2016.zip is already in cache') - else: - orbiter_url = 'https://orbiter-mods.com/files/Orbiter2016.zip' - if DEBUG == 1: - orbiter_url = 'http://localhost:8000/Orbiter2016.zip' - - # ask user if they want to continue to download Orbiter2016 - print('Orbiter2016 is not in cache. would you like to download it?') - if input('(y/n) ') != 'y': - print('aborting orbiter2016 download') - return - orb.download_zip(orbiter_url, 'Orbiter2016.zip') - # unzip Orbiter2016.zip to orb_cache/Orbiter2016 - print('unzipping Orbiter2016.zip - this will only take a bit and will speed things up in the future!') - with zipfile.ZipFile(f'orb_cache/Orbiter2016.zip', 'r') as zip_ref: - zip_ref.extractall('./orb_cache/Orbiter2016') - # check if orbiter.exe is in the current folder - if not os.path.exists('orbiter.exe'): - # ask user if they'd like to install a fresh copy of orbiter 2016 - print('orbiter.exe is not in the current folder. would you like to install a fresh copy of orbiter 2016?') - if input('(y/n): ') == 'y': - # copy all files from orb_cache/Orbiter2016 to current folder keeping directory structure in tact - print('copying files from Orbiter2016 to current folder') - shutil.copytree(os.path.join('orb_cache', 'Orbiter2016'), '.', dirs_exist_ok=True) def del_orbiter(): test = input('Are you sure you want to delete the orbiter install? (y/n): ') @@ -201,23 +102,6 @@ def del_orbiter(): else: os.remove(file) -def reset_orbiter(): - # ask user to confirm as doing this action will destroy the current orbiter install - test = input('Are you sure you want to reset the orbiter install? (y/n): ') - if test.lower() != 'y': - print('aborting orbiter install reset') - time.sleep(3) - return - # verify current orbiter install hash using ./Orbiter2016.json as reference hash_file - files_to_revert = verify_orbiter_hash('./Orbiter2016.json') - orb = Orb() - download_orbiter_2016_if_needed(orb) - for file_to_revert in files_to_revert: - print(f'reverting {file_to_revert}') - os.remove(file_to_revert) - # copy removed file from orb_cache/Orbiter2016 to ./ - shutil.copy(f'orb_cache/Orbiter2016/{file_to_revert}', file_to_revert) - class Orb: def __init__(self, scn_dir=None): self.scn_dir = scn_dir @@ -475,9 +359,10 @@ def set_experience_list(self, experiences): self.experience_list = experiences def install_orbiter_mods_experience(self, experience_id): - xp = [x for x in self.experience_list if 'id' in x and x['id'] == experience_id] + xp = [x for x in self.experience_list if 'id' in x and int(x['id']) == int(experience_id)] if len(xp) == 0: print(f'experience {experience_id} not found') + print([e for e in self.experience_list if e['name'] == 'NASSP 8 beta']) return execute_script(self.experience_list, xp[0]) @@ -500,7 +385,6 @@ def execute_script(all_experiences, experience): experience_name = experience['name'] orb = Orb() orb.set_scn_dir(experience_name) - orb.set_experience_list(all_experiences) # fetch experience_script_url and save it in orb_cache experience_script_file_name = experience_name + '.py' @@ -511,15 +395,6 @@ def execute_script(all_experiences, experience): # load experience_script_file_name mod = load_experience_module(f'orb_cache/{experience_script_file_name}') - if mod.requires_fresh_install(): - print('This experience requires a fresh install') - test = input('continue? (y/n): ') - if test.lower() != 'y': - print('ok, bye!') - time.sleep(3) - sys.exit(1) - print('reseting orbiter') - reset_orbiter() try: mod.main(orb) except Exception as e: @@ -546,8 +421,6 @@ def main(): orb = Orb() - download_orbiter_2016_if_needed(orb) - experiences = fetch_experiences() # find all *.py files in orb_cache dir @@ -562,6 +435,13 @@ def main(): 'experience_script': open(f'orb_cache/{experience_file}').read() }) + orb.set_experience_list(experiences) + + if '--experience-id' in sys.argv: + experience_id = sys.argv[sys.argv.index('--experience-id') + 1] + orb.install_orbiter_mods_experience(experience_id) + return + if len(experiences) == 0: print('no experiences found, terminating') time.sleep(3) From 269903e85d811255b3ffd9d2a51e4f0474b6cf67 Mon Sep 17 00:00:00 2001 From: Mohd Ali Date: Tue, 13 Jun 2023 17:34:41 -0400 Subject: [PATCH 2/5] added runas admin support --- orb.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/orb.py b/orb.py index c1cc754..f1549ce 100644 --- a/orb.py +++ b/orb.py @@ -364,7 +364,7 @@ def install_orbiter_mods_experience(self, experience_id): print(f'experience {experience_id} not found') print([e for e in self.experience_list if e['name'] == 'NASSP 8 beta']) return - execute_script(self.experience_list, xp[0]) + execute_script(self, self.experience_list, xp[0]) # fetch experiences from https://orbiter-mods.com/fetch_experiences def fetch_experiences(): @@ -380,10 +380,18 @@ def fetch_experiences(): pass return [] -def execute_script(all_experiences, experience): +def launch_with_elevation(experience_id): + args = sys.argv + # remove --experience-id from args + args = [x for x in args if not x.startswith('--experience-id')] + args.append(f'--experience-id {experience_id}') + print(" ".join(args)) + ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(args), None, 1) + +def execute_script(orb, all_experiences, experience): experience_script = experience['experience_script'] experience_name = experience['name'] - orb = Orb() + experience_id = experience['id'] orb.set_scn_dir(experience_name) # fetch experience_script_url and save it in orb_cache @@ -397,6 +405,12 @@ def execute_script(all_experiences, experience): try: mod.main(orb) + except OSError as e: + # check for win error 740 requires elevation + if e.winerror == 740 or e.errno == 740: + # run self as admin and pass experience_id as argument + print('running as admin') + launch_with_elevation(experience_id) except Exception as e: print(f'Please contact the author of this experience script: {str(e)}') traceback.print_exc() @@ -460,7 +474,7 @@ def main(): sys.exit(1) experience = experiences[mod_index] - execute_script(experiences, experience) + execute_script(orb, experiences, experience) print('ok, bye!') time.sleep(3) From 8fedfb539e7f3b6018b2a21188e04e8ac0b38812 Mon Sep 17 00:00:00 2001 From: Mohd Ali Date: Wed, 14 Jun 2023 00:18:48 -0400 Subject: [PATCH 3/5] udpate --- orb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orb.py b/orb.py index f1549ce..b2b34a7 100644 --- a/orb.py +++ b/orb.py @@ -95,7 +95,7 @@ def del_orbiter(): return # delete everything in current directory except for orb_cache, orb.exe, Orbiter2016.json for file in os.listdir('.'): - if file == 'orb_cache' or file == 'orb' or file == 'Orbiter2016.json' or file == 'orb.bat': + if file == 'orb_cache' or file == 'orb' or file == 'Orbiter2016.json' or file == 'orb.bat' or file.lower().startswith('orb_install_'): continue if os.path.isdir(file): shutil.rmtree(file) From f4257e510ad87afd9eb944d704ed6d28104380b7 Mon Sep 17 00:00:00 2001 From: Mohd Ali Date: Mon, 26 Jun 2023 00:41:29 -0400 Subject: [PATCH 4/5] update --- orb.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/orb.py b/orb.py index b2b34a7..bc06b8f 100644 --- a/orb.py +++ b/orb.py @@ -364,7 +364,7 @@ def install_orbiter_mods_experience(self, experience_id): print(f'experience {experience_id} not found') print([e for e in self.experience_list if e['name'] == 'NASSP 8 beta']) return - execute_script(self, self.experience_list, xp[0]) + execute_script(self.experience_list, xp[0]) # fetch experiences from https://orbiter-mods.com/fetch_experiences def fetch_experiences(): @@ -388,10 +388,12 @@ def launch_with_elevation(experience_id): print(" ".join(args)) ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(args), None, 1) -def execute_script(orb, all_experiences, experience): +def execute_script(all_experiences, experience): experience_script = experience['experience_script'] experience_name = experience['name'] experience_id = experience['id'] + orb = Orb() + orb.set_experience_list(all_experiences) orb.set_scn_dir(experience_name) # fetch experience_script_url and save it in orb_cache @@ -456,6 +458,17 @@ def main(): orb.install_orbiter_mods_experience(experience_id) return + if '--experiences' in sys.argv: + # get all args after --experiences + experience_ids = sys.argv[sys.argv.index('--experiences') + 1:] + # remove --experiences from sys.args + sys.argv = [x for x in sys.argv if x != '--experiences'] + for experience_id in experience_ids: + orb.install_orbiter_mods_experience(experience_id) + print('ok, bye!') + time.sleep(3) + return + if len(experiences) == 0: print('no experiences found, terminating') time.sleep(3) @@ -474,7 +487,7 @@ def main(): sys.exit(1) experience = experiences[mod_index] - execute_script(orb, experiences, experience) + execute_script(experiences, experience) print('ok, bye!') time.sleep(3) From cf2e2aa2fc9274634c0297936f28ce1853c9007e Mon Sep 17 00:00:00 2001 From: Mohd Ali Date: Fri, 7 Jul 2023 00:24:52 -0400 Subject: [PATCH 5/5] ignoring deletion of all files starting with orb_ prefix --- orb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orb.py b/orb.py index bc06b8f..0f12055 100644 --- a/orb.py +++ b/orb.py @@ -95,7 +95,7 @@ def del_orbiter(): return # delete everything in current directory except for orb_cache, orb.exe, Orbiter2016.json for file in os.listdir('.'): - if file == 'orb_cache' or file == 'orb' or file == 'Orbiter2016.json' or file == 'orb.bat' or file.lower().startswith('orb_install_'): + if file == 'orb_cache' or file == 'orb' or file == 'Orbiter2016.json' or file == 'orb.bat' or file == 'orbiter.sh' or file.lower().startswith('orb_'): continue if os.path.isdir(file): shutil.rmtree(file)