From df8f0b3067aed7b9b25753c050cd88428b776f7b Mon Sep 17 00:00:00 2001 From: Ada Werefox Date: Wed, 28 Feb 2024 18:50:22 -0600 Subject: [PATCH] Works well enough to start framing into an API for front-end dev for now. --- lib/entrances.py | 48 +++++++++++++++++++++++++++++++++++++++++++ lib/saves.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 46 +++++++++++++++++++++++++++++++++++++++++ requirements.txt | 22 ++++++++++++++++++++ start.py | 25 ----------------------- 5 files changed, 169 insertions(+), 25 deletions(-) create mode 100644 lib/entrances.py create mode 100644 lib/saves.py create mode 100755 main.py delete mode 100755 start.py diff --git a/lib/entrances.py b/lib/entrances.py new file mode 100644 index 0000000..7140f03 --- /dev/null +++ b/lib/entrances.py @@ -0,0 +1,48 @@ +#!/usr/bin/python + +import logging +import re + + +def import_entrances(spoiler_log='/home/alice/Games/steam/steamapps/compatdata/553420/pfx/drive_c/users/steamuser/AppData/LocalLow/Andrew Shouldice/Secret Legend/Randomizer/Spoiler.log'): + """A function to import the entrance mappings from the user's spoiler log. + + Args: + spoiler_log (str, optional): The filepath of the spoiler log. Defaults to '/home/alice/Games/steam/steamapps/compatdata/553420/pfx/drive_c/users/steamuser/AppData/LocalLow/Andrew Shouldice/Secret Legend/Randomizer/Spoiler.log'. + """ + + try: + with open(spoiler_log, 'r') as f: + spoiler_text = f.read() + entrances_map = re.findall('\s+- (.+) -- (.+)\n', spoiler_text) + # logging.debug(entrances_map) + except: + logging.error(f'Could not find spoiler log from path: {spoiler_log}') + return + + return dict(entrances_map) + + +def log_entrances(e): + """A debug function to ensure entrance parsing has been done successfully. + """ + + for l in e: + logging.debug(f'{l[0]} <---> {l[1]}') + + +def check_mapped_entrances(new_entrances, entrances_map): + """A function to check off when a new entrance pair has been visited and validate it with the spoiler log. + + Args: + new_entrances (tuple): A pairing of two strings containing the entrance names. + entrances_map (dict): An imported dictionary mapping the entrances as listed in the spoiler log. + """ + if new_entrances[0] in entrances_map.keys(): + logging.debug(f'Validated that {new_entrances[0]} connects to {new_entrances[1]}') + elif new_entrances[1] in entrances_map.keys(): + logging.debug(f'Validated that {new_entrances[1]} connects to {new_entrances[0]}') + else: + logging.warn(f'No connection in spoiler log between {new_entrances[0]} and {new_entrances[1]}') + return False + return True \ No newline at end of file diff --git a/lib/saves.py b/lib/saves.py new file mode 100644 index 0000000..94378ce --- /dev/null +++ b/lib/saves.py @@ -0,0 +1,53 @@ +import logging +import glob +import os +import re +# from collections import deque + + +def get_current_save_filename(saves_dir='/home/alice/Games/steam/steamapps/compatdata/553420/pfx/drive_c/users/steamuser/AppData/LocalLow/Andrew Shouldice/Secret Legend/SAVES'): + """Get the last modified save file in the saves directory. + + Args: + saves_dir (str, optional): Path to the saves directory. Defaults to '/home/alice/Games/steam/steamapps/compatdata/553420/pfx/drive_c/users/steamuser/AppData/LocalLow/Andrew Shouldice/Secret Legend/SAVES'. + """ + + try: + list_files = glob.glob(f'{saves_dir}/*.tunic') + except: + logging.error( + f'Something went wrong in looking for the saves directory at {saves_dir}') + + try: + latest_save_path = max(list_files, key=os.path.getmtime) + except: + logging.warn('A save file was deleted.') + return + + try: + latest_save_filename = re.search( + '([0-9]*)[a-z-]*~([0-9]*)\.tunic', latest_save_path) + except: + logging.error(f'Cannot perform regex successfully on save path: {latest_save_path}') + return + + if latest_save_filename != None: + return (latest_save_filename[0], latest_save_filename[1]) + return (None, None) + + +def get_visited_entrances(save_filename, saves_dir='/home/alice/Games/steam/steamapps/compatdata/553420/pfx/drive_c/users/steamuser/AppData/LocalLow/Andrew Shouldice/Secret Legend/SAVES'): + try: + with open(f'{saves_dir}/{save_filename}', 'r') as save: + save_file_text = save.read() + try: + save_entrances = re.findall('portal (.*)\|1\n', save_file_text) + except: + logging.error( + f'Unable to perform findall successfully on {save_filename}') + return + except: + logging.error(f'Could not find save file from path: {save_filename}') + return + + return save_entrances diff --git a/main.py b/main.py new file mode 100755 index 0000000..db1c7a0 --- /dev/null +++ b/main.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +import logging +from time import sleep +from lib import entrances as e +from lib import saves as s + +# Set up a default logger, later this should be changed to default only errors. +logging.basicConfig(level=logging.DEBUG) + +entrances_map = e.import_entrances() +visited_entrances = None +save_filename = '' +save = '' + +# Make this an optional command based on CLI flags +# e.log_entrances(entrances_map) + +while (True): + current_save_filename, current_save = s.get_current_save_filename() + if (current_save != save): + save = current_save + logging.debug(f'Updated current save to: {current_save}') + visited_entrances = None + logging.debug(f'Re-initializing visited entrances.') + if (current_save_filename != save_filename): + save_filename = current_save_filename + logging.debug(f'Updated latest save filename to: {save_filename}') + try: + updated_visited_entrances = s.get_visited_entrances(save_filename) + except: + logging.error( + f'Could not get visited entrances from save file at {save_filename}') + if (visited_entrances != updated_visited_entrances): + if (visited_entrances != None): + new_entrances = [ + x for x in updated_visited_entrances if x not in visited_entrances] + logging.debug(new_entrances) + if (e.check_mapped_entrances(new_entrances, entrances_map)): + visited_entrances = updated_visited_entrances + logging.debug( + f'Updated visited entrances to: {visited_entrances}') + else: + visited_entrances = updated_visited_entrances + logging.debug(f'Updated visited entrances to: {visited_entrances}') + sleep(1) diff --git a/requirements.txt b/requirements.txt index e69de29..4cfb869 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,22 @@ +annotated-types==0.6.0 +anyio==4.3.0 +autopep8==2.0.4 +click==8.1.7 +fastapi==0.110.0 +h11==0.14.0 +httptools==0.6.1 +idna==3.6 +numpy==1.26.4 +pyarrow==15.0.0 +pycodestyle==2.11.1 +pydantic==2.6.3 +pydantic_core==2.16.3 +python-dotenv==1.0.1 +PyYAML==6.0.1 +sniffio==1.3.1 +starlette==0.36.3 +typing_extensions==4.10.0 +uvicorn==0.27.1 +uvloop==0.19.0 +watchfiles==0.21.0 +websockets==12.0 diff --git a/start.py b/start.py deleted file mode 100755 index 4ee29ea..0000000 --- a/start.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python - -import logging -import re - -log = logging.getLogger(__name__) -entrances_map = '' - - -def import_entrances(spoiler_log='/home/alice/Games/steam/steamapps/compatdata/553420/pfx/drive_c/users/steamuser/AppData/LocalLow/Andrew Shouldice/Secret Legend/Randomizer/Spoiler.log'): - """A function to import the entrance mappings from the user's spoiler log. - - Args: - spoiler_log (str, optional): The filepath of the spoiler log. Defaults to '/home/alice/Games/steam/steamapps/compatdata/553420/pfx/drive_c/users/steamuser/AppData/LocalLow/Andrew Shouldice/Secret Legend/Randomizer/Spoiler.log'. - """ - - try: - with open(spoiler_log, 'r') as f: - spoiler_text = f.read() - entrances_map = re.findall('\s+- (.+) -- (.+)\n', spoiler_text) - except: - print(f'Could not find spoiler log from path: {spoiler_log}') - - for l in entrances_map: - print(f'{l[0]} <---> {l[1]}')