diff --git a/Gui.py b/Gui.py index a7755f80..cc2286b0 100755 --- a/Gui.py +++ b/Gui.py @@ -1566,22 +1566,22 @@ class SpriteSelector(object): @property def alttpr_sprite_dir(self): if is_bundled(): - return output_path("sprites/alttpr") + return output_path("sprites", "alttpr") return self.local_alttpr_sprite_dir @property def local_alttpr_sprite_dir(self): - return local_path("data/sprites/alttpr") + return local_path("data", "sprites", "alttpr") @property def custom_sprite_dir(self): if is_bundled(): - return output_path("sprites/custom") + return output_path("sprites", "custom") return self.local_custom_sprite_dir @property def local_custom_sprite_dir(self): - return local_path("data/sprites/custom") + return local_path("data", "sprites", "custom") def get_image_for_sprite(sprite): diff --git a/GuiUtils.py b/GuiUtils.py index e9361632..0bebfda6 100644 --- a/GuiUtils.py +++ b/GuiUtils.py @@ -5,10 +5,10 @@ import tkinter as tk from Utils import local_path def set_icon(window): - er16 = tk.PhotoImage(file=local_path('data/ER16.gif')) - er32 = tk.PhotoImage(file=local_path('data/ER32.gif')) - er48 = tk.PhotoImage(file=local_path('data/ER32.gif')) - window.tk.call('wm', 'iconphoto', window._w, er16, er32, er48) # pylint: disable=protected-access + er16 = tk.PhotoImage(file=local_path('data', 'ER16.gif')) + er32 = tk.PhotoImage(file=local_path('data', 'ER32.gif')) + er48 = tk.PhotoImage(file=local_path('data', 'ER32.gif')) + window.tk.call('wm', 'iconphoto', window._w, er16, er32, er48) # pylint: disable=protected-access # Although tkinter is intended to be thread safe, there are many reports of issues # some which may be platform specific, or depend on if the TCL library was compiled without diff --git a/Rom.py b/Rom.py index 5be942dd..7ba8b6a1 100644 --- a/Rom.py +++ b/Rom.py @@ -19,8 +19,10 @@ from Regions import location_table from Text import MultiByteTextMapper, CompressedTextMapper, text_addresses, Credits, TextTable from Text import Uncle_texts, Ganon1_texts, TavernMan_texts, Sahasrahla2_texts, Triforce_texts, Blind_texts, BombShop2_texts, junk_texts -from Text import KingsReturn_texts, Sanctuary_texts, Kakariko_texts, Blacksmiths_texts, DeathMountain_texts, LostWoods_texts, WishingWell_texts, DesertPalace_texts, MountainTower_texts, LinksHouse_texts, Lumberjacks_texts, SickKid_texts, FluteBoy_texts, Zora_texts, MagicShop_texts, Sahasrahla_names -from Utils import output_path, local_path, int16_as_bytes, int32_as_bytes, snes_to_pc +from Text import KingsReturn_texts, Sanctuary_texts, Kakariko_texts, Blacksmiths_texts, DeathMountain_texts, \ + LostWoods_texts, WishingWell_texts, DesertPalace_texts, MountainTower_texts, LinksHouse_texts, Lumberjacks_texts, \ + SickKid_texts, FluteBoy_texts, Zora_texts, MagicShop_texts, Sahasrahla_names +from Utils import output_path, local_path, int16_as_bytes, int32_as_bytes, snes_to_pc, is_bundled from Items import ItemFactory from EntranceShuffle import door_addresses import Patch @@ -78,12 +80,12 @@ class LocalRom(object): if self.verify(buffer): self.buffer = buffer - if not os.path.exists(local_path(os.path.join('data', 'basepatch.bmbp'))): + if not os.path.exists(local_path('data', 'basepatch.bmbp')): Patch.create_patch_file(local_path('basepatch.sfc')) return - if os.path.isfile(local_path(os.path.join('data', 'basepatch.bmbp'))): - _, target, buffer = Patch.create_rom_bytes(local_path(os.path.join('data', 'basepatch.bmbp'))) + if os.path.isfile(local_path('data', 'basepatch.bmbp')): + _, target, buffer = Patch.create_rom_bytes(local_path('data', 'basepatch.bmbp')) if self.verify(buffer): self.buffer = bytearray(buffer) with open(local_path('basepatch.sfc'), 'wb') as stream: @@ -99,7 +101,7 @@ class LocalRom(object): self.buffer.extend(bytearray([0x00]) * (0x200000 - len(self.buffer))) # load randomizer patches - with open(local_path('data/base2current.json')) as stream: + with open(local_path('data', 'base2current.json')) as stream: patches = json.load(stream) for patch in patches: if isinstance(patch, dict): @@ -111,8 +113,8 @@ class LocalRom(object): with open(local_path('basepatch.sfc'), 'wb') as stream: stream.write(self.buffer) Patch.create_patch_file(local_path('basepatch.sfc'), - destination=local_path(os.path.join('data', 'basepatch.bmbp'))) - os.remove(local_path('data/base2current.json')) + destination=local_path('data', 'basepatch.bmbp')) + os.remove(local_path('data', 'base2current.json')) else: raise RuntimeError( 'Provided Base Rom unsuitable for patching. Please provide a JAP(1.0) "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc" rom to use as a base.') @@ -355,7 +357,7 @@ def _populate_sprite_table(): logging.debug(f"Spritefile {file} could not be loaded as a valid sprite.") with concurrent.futures.ThreadPoolExecutor() as pool: - for dir in [local_path('data/sprites/alttpr'), local_path('data/sprites/custom')]: + for dir in [local_path('data', 'sprites', 'alttpr'), local_path('data', 'sprites', 'custom')]: for file in os.listdir(dir): pool.submit(load_sprite_from_file, os.path.join(dir, file)) @@ -430,7 +432,7 @@ class Sprite(object): @staticmethod def default_link_sprite(): - return Sprite(local_path('data/default.zspr')) + return Sprite(local_path('data', 'default.zspr')) def decode8(self, pos): arr = [[0 for _ in range(8)] for _ in range(8)] diff --git a/Utils.py b/Utils.py index d0d17bb9..e27c53e0 100644 --- a/Utils.py +++ b/Utils.py @@ -61,9 +61,9 @@ def is_bundled() -> bool: return getattr(sys, 'frozen', False) -def local_path(path): +def local_path(*path): if local_path.cached_path: - return os.path.join(local_path.cached_path, path) + return os.path.join(local_path.cached_path, *path) elif is_bundled(): if hasattr(sys, "_MEIPASS"): @@ -77,15 +77,16 @@ def local_path(path): import __main__ local_path.cached_path = os.path.dirname(os.path.abspath(__main__.__file__)) - return os.path.join(local_path.cached_path, path) + return os.path.join(local_path.cached_path, *path) local_path.cached_path = None -def output_path(path): + +def output_path(*path): if output_path.cached_path: - return os.path.join(output_path.cached_path, path) + return os.path.join(output_path.cached_path, *path) output_path.cached_path = local_path(get_options()["general_options"]["output_path"]) - path = os.path.join(output_path.cached_path, path) + path = os.path.join(output_path.cached_path, *path) os.makedirs(os.path.dirname(path), exist_ok=True) return path diff --git a/WebUI.py b/WebUI.py index ab9143d6..b2a994b6 100644 --- a/WebUI.py +++ b/WebUI.py @@ -143,7 +143,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler): Handler = partial(RequestHandler, - directory=Utils.local_path(os.path.join("data", "web", "public"))) + directory=Utils.local_path("data", "web", "public")) def start_server(socket_port: int, on_start=lambda: None): diff --git a/requirements.txt b/requirements.txt index 259195ab..3ed91e35 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ fuzzywuzzy>=0.18.0 bsdiff4>=1.2.0 prompt_toolkit>=3.0.6 appdirs>=1.4.4 +maseya-z3pr>=1.0.0.dev5 \ No newline at end of file diff --git a/setup.py b/setup.py index 7a241565..2281a7d3 100644 --- a/setup.py +++ b/setup.py @@ -80,7 +80,7 @@ cx_Freeze.setup( "build_exe": { "includes": [], "zip_include_packages": ["*"], - "zip_exclude_packages": ["maseya"], + "zip_exclude_packages": [], "include_files": [], "include_msvcr": True, "replace_paths": [("*", "")], @@ -91,15 +91,14 @@ cx_Freeze.setup( ) - -def installfile(path): +def installfile(path, keep_content=False): lbuildfolder = buildfolder print('copying', path, '->', lbuildfolder) if path.is_dir(): lbuildfolder /= path.name - if lbuildfolder.is_dir(): + if lbuildfolder.is_dir() and not keep_content: shutil.rmtree(lbuildfolder) - shutil.copytree(path, lbuildfolder) + shutil.copytree(path, lbuildfolder, dirs_exist_ok=True) elif path.is_file(): shutil.copy(path, lbuildfolder) else: