mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-20 20:01:31 -06:00
LttP: remove sprite download from setup flow & make sprite repo dynamic (#4830)
This commit is contained in:
@@ -32,6 +32,7 @@ GAME_ALTTP = "A Link to the Past"
|
|||||||
WINDOW_MIN_HEIGHT = 525
|
WINDOW_MIN_HEIGHT = 525
|
||||||
WINDOW_MIN_WIDTH = 425
|
WINDOW_MIN_WIDTH = 425
|
||||||
|
|
||||||
|
|
||||||
class AdjusterWorld(object):
|
class AdjusterWorld(object):
|
||||||
class AdjusterSubWorld(object):
|
class AdjusterSubWorld(object):
|
||||||
def __init__(self, random):
|
def __init__(self, random):
|
||||||
@@ -48,6 +49,7 @@ class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
|
|||||||
def _get_help_string(self, action):
|
def _get_help_string(self, action):
|
||||||
return textwrap.dedent(action.help)
|
return textwrap.dedent(action.help)
|
||||||
|
|
||||||
|
|
||||||
# See argparse.BooleanOptionalAction
|
# See argparse.BooleanOptionalAction
|
||||||
class BooleanOptionalActionWithDisable(argparse.Action):
|
class BooleanOptionalActionWithDisable(argparse.Action):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@@ -363,10 +365,10 @@ def run_sprite_update():
|
|||||||
logging.info("Done updating sprites")
|
logging.info("Done updating sprites")
|
||||||
|
|
||||||
|
|
||||||
def update_sprites(task, on_finish=None):
|
def update_sprites(task, on_finish=None, repository_url: str = "https://alttpr.com/sprites"):
|
||||||
resultmessage = ""
|
resultmessage = ""
|
||||||
successful = True
|
successful = True
|
||||||
sprite_dir = user_path("data", "sprites", "alttpr")
|
sprite_dir = user_path("data", "sprites", "alttp", "remote")
|
||||||
os.makedirs(sprite_dir, exist_ok=True)
|
os.makedirs(sprite_dir, exist_ok=True)
|
||||||
ctx = get_cert_none_ssl_context()
|
ctx = get_cert_none_ssl_context()
|
||||||
|
|
||||||
@@ -376,11 +378,11 @@ def update_sprites(task, on_finish=None):
|
|||||||
on_finish(successful, resultmessage)
|
on_finish(successful, resultmessage)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
task.update_status("Downloading alttpr sprites list")
|
task.update_status("Downloading remote sprites list")
|
||||||
with urlopen('https://alttpr.com/sprites', context=ctx) as response:
|
with urlopen(repository_url, context=ctx) as response:
|
||||||
sprites_arr = json.loads(response.read().decode("utf-8"))
|
sprites_arr = json.loads(response.read().decode("utf-8"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
resultmessage = "Error getting list of alttpr sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e)
|
resultmessage = "Error getting list of remote sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e)
|
||||||
successful = False
|
successful = False
|
||||||
task.queue_event(finished)
|
task.queue_event(finished)
|
||||||
return
|
return
|
||||||
@@ -388,13 +390,13 @@ def update_sprites(task, on_finish=None):
|
|||||||
try:
|
try:
|
||||||
task.update_status("Determining needed sprites")
|
task.update_status("Determining needed sprites")
|
||||||
current_sprites = [os.path.basename(file) for file in glob(sprite_dir + '/*')]
|
current_sprites = [os.path.basename(file) for file in glob(sprite_dir + '/*')]
|
||||||
alttpr_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path))
|
remote_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path))
|
||||||
for sprite in sprites_arr if sprite["author"] != "Nintendo"]
|
for sprite in sprites_arr if sprite["author"] != "Nintendo"]
|
||||||
needed_sprites = [(sprite_url, filename) for (sprite_url, filename) in alttpr_sprites if
|
needed_sprites = [(sprite_url, filename) for (sprite_url, filename) in remote_sprites if
|
||||||
filename not in current_sprites]
|
filename not in current_sprites]
|
||||||
|
|
||||||
alttpr_filenames = [filename for (_, filename) in alttpr_sprites]
|
remote_filenames = [filename for (_, filename) in remote_sprites]
|
||||||
obsolete_sprites = [sprite for sprite in current_sprites if sprite not in alttpr_filenames]
|
obsolete_sprites = [sprite for sprite in current_sprites if sprite not in remote_filenames]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
resultmessage = "Error Determining which sprites to update. Sprites not updated.\n\n%s: %s" % (
|
resultmessage = "Error Determining which sprites to update. Sprites not updated.\n\n%s: %s" % (
|
||||||
type(e).__name__, e)
|
type(e).__name__, e)
|
||||||
@@ -446,7 +448,7 @@ def update_sprites(task, on_finish=None):
|
|||||||
successful = False
|
successful = False
|
||||||
|
|
||||||
if successful:
|
if successful:
|
||||||
resultmessage = "alttpr sprites updated successfully"
|
resultmessage = "Remote sprites updated successfully"
|
||||||
|
|
||||||
task.queue_event(finished)
|
task.queue_event(finished)
|
||||||
|
|
||||||
@@ -867,7 +869,7 @@ class SpriteSelector():
|
|||||||
def open_custom_sprite_dir(_evt):
|
def open_custom_sprite_dir(_evt):
|
||||||
open_file(self.custom_sprite_dir)
|
open_file(self.custom_sprite_dir)
|
||||||
|
|
||||||
alttpr_frametitle = Label(self.window, text='ALTTPR Sprites')
|
remote_frametitle = Label(self.window, text='Remote Sprites')
|
||||||
|
|
||||||
custom_frametitle = Frame(self.window)
|
custom_frametitle = Frame(self.window)
|
||||||
title_text = Label(custom_frametitle, text="Custom Sprites")
|
title_text = Label(custom_frametitle, text="Custom Sprites")
|
||||||
@@ -876,8 +878,8 @@ class SpriteSelector():
|
|||||||
title_link.pack(side=LEFT)
|
title_link.pack(side=LEFT)
|
||||||
title_link.bind("<Button-1>", open_custom_sprite_dir)
|
title_link.bind("<Button-1>", open_custom_sprite_dir)
|
||||||
|
|
||||||
self.icon_section(alttpr_frametitle, self.alttpr_sprite_dir,
|
self.icon_section(remote_frametitle, self.remote_sprite_dir,
|
||||||
'ALTTPR sprites not found. Click "Update alttpr sprites" to download them.')
|
'Remote sprites not found. Click "Update remote sprites" to download them.')
|
||||||
self.icon_section(custom_frametitle, self.custom_sprite_dir,
|
self.icon_section(custom_frametitle, self.custom_sprite_dir,
|
||||||
'Put sprites in the custom sprites folder (see open link above) to have them appear here.')
|
'Put sprites in the custom sprites folder (see open link above) to have them appear here.')
|
||||||
if not randomOnEvent:
|
if not randomOnEvent:
|
||||||
@@ -890,11 +892,18 @@ class SpriteSelector():
|
|||||||
button = Button(frame, text="Browse for file...", command=self.browse_for_sprite)
|
button = Button(frame, text="Browse for file...", command=self.browse_for_sprite)
|
||||||
button.pack(side=RIGHT, padx=(5, 0))
|
button.pack(side=RIGHT, padx=(5, 0))
|
||||||
|
|
||||||
button = Button(frame, text="Update alttpr sprites", command=self.update_alttpr_sprites)
|
button = Button(frame, text="Update remote sprites", command=self.update_remote_sprites)
|
||||||
button.pack(side=RIGHT, padx=(5, 0))
|
button.pack(side=RIGHT, padx=(5, 0))
|
||||||
|
|
||||||
|
repository_label = Label(frame, text='Sprite Repository:')
|
||||||
|
self.repository_url = StringVar(frame, "https://alttpr.com/sprites")
|
||||||
|
repository_entry = Entry(frame, textvariable=self.repository_url)
|
||||||
|
|
||||||
|
repository_entry.pack(side=RIGHT, expand=True, fill=BOTH, pady=1)
|
||||||
|
repository_label.pack(side=RIGHT, expand=False, padx=(0, 5))
|
||||||
|
|
||||||
button = Button(frame, text="Do not adjust sprite",command=self.use_default_sprite)
|
button = Button(frame, text="Do not adjust sprite",command=self.use_default_sprite)
|
||||||
button.pack(side=LEFT,padx=(0,5))
|
button.pack(side=LEFT, padx=(0, 5))
|
||||||
|
|
||||||
button = Button(frame, text="Default Link sprite", command=self.use_default_link_sprite)
|
button = Button(frame, text="Default Link sprite", command=self.use_default_link_sprite)
|
||||||
button.pack(side=LEFT, padx=(0, 5))
|
button.pack(side=LEFT, padx=(0, 5))
|
||||||
@@ -1054,7 +1063,7 @@ class SpriteSelector():
|
|||||||
for i, button in enumerate(frame.buttons):
|
for i, button in enumerate(frame.buttons):
|
||||||
button.grid(row=i // self.spritesPerRow, column=i % self.spritesPerRow)
|
button.grid(row=i // self.spritesPerRow, column=i % self.spritesPerRow)
|
||||||
|
|
||||||
def update_alttpr_sprites(self):
|
def update_remote_sprites(self):
|
||||||
# need to wrap in try catch. We don't want errors getting the json or downloading the files to break us.
|
# need to wrap in try catch. We don't want errors getting the json or downloading the files to break us.
|
||||||
self.window.destroy()
|
self.window.destroy()
|
||||||
self.parent.update()
|
self.parent.update()
|
||||||
@@ -1067,7 +1076,8 @@ class SpriteSelector():
|
|||||||
messagebox.showerror("Sprite Updater", resultmessage)
|
messagebox.showerror("Sprite Updater", resultmessage)
|
||||||
SpriteSelector(self.parent, self.callback, self.adjuster)
|
SpriteSelector(self.parent, self.callback, self.adjuster)
|
||||||
|
|
||||||
BackgroundTaskProgress(self.parent, update_sprites, "Updating Sprites", on_finish)
|
BackgroundTaskProgress(self.parent, update_sprites, "Updating Sprites",
|
||||||
|
on_finish, self.repository_url.get())
|
||||||
|
|
||||||
def browse_for_sprite(self):
|
def browse_for_sprite(self):
|
||||||
sprite = filedialog.askopenfilename(
|
sprite = filedialog.askopenfilename(
|
||||||
@@ -1157,12 +1167,13 @@ class SpriteSelector():
|
|||||||
os.makedirs(self.custom_sprite_dir)
|
os.makedirs(self.custom_sprite_dir)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def alttpr_sprite_dir(self):
|
def remote_sprite_dir(self):
|
||||||
return user_path("data", "sprites", "alttpr")
|
return user_path("data", "sprites", "alttp", "remote")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def custom_sprite_dir(self):
|
def custom_sprite_dir(self):
|
||||||
return user_path("data", "sprites", "custom")
|
return user_path("data", "sprites", "alttp", "custom")
|
||||||
|
|
||||||
|
|
||||||
def get_image_for_sprite(sprite, gif_only: bool = False):
|
def get_image_for_sprite(sprite, gif_only: bool = False):
|
||||||
if not sprite.valid:
|
if not sprite.valid:
|
||||||
|
@@ -14,7 +14,7 @@ def update_sprites_lttp():
|
|||||||
from LttPAdjuster import update_sprites
|
from LttPAdjuster import update_sprites
|
||||||
|
|
||||||
# Target directories
|
# Target directories
|
||||||
input_dir = user_path("data", "sprites", "alttpr")
|
input_dir = user_path("data", "sprites", "alttp", "remote")
|
||||||
output_dir = local_path("WebHostLib", "static", "generated") # TODO: move to user_path
|
output_dir = local_path("WebHostLib", "static", "generated") # TODO: move to user_path
|
||||||
|
|
||||||
os.makedirs(os.path.join(output_dir, "sprites"), exist_ok=True)
|
os.makedirs(os.path.join(output_dir, "sprites"), exist_ok=True)
|
||||||
|
@@ -53,10 +53,6 @@ Name: "full"; Description: "Full installation"
|
|||||||
Name: "minimal"; Description: "Minimal installation"
|
Name: "minimal"; Description: "Minimal installation"
|
||||||
Name: "custom"; Description: "Custom installation"; Flags: iscustom
|
Name: "custom"; Description: "Custom installation"; Flags: iscustom
|
||||||
|
|
||||||
[Components]
|
|
||||||
Name: "core"; Description: "Archipelago"; Types: full minimal custom; Flags: fixed
|
|
||||||
Name: "lttp_sprites"; Description: "Download ""A Link to the Past"" player sprites"; Types: full;
|
|
||||||
|
|
||||||
[Dirs]
|
[Dirs]
|
||||||
NAME: "{app}"; Flags: setntfscompression; Permissions: everyone-modify users-modify authusers-modify;
|
NAME: "{app}"; Flags: setntfscompression; Permissions: everyone-modify users-modify authusers-modify;
|
||||||
|
|
||||||
@@ -76,7 +72,6 @@ Name: "{commondesktop}\{#MyAppName} Launcher"; Filename: "{app}\ArchipelagoLaunc
|
|||||||
[Run]
|
[Run]
|
||||||
|
|
||||||
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/passive /norestart"; Check: IsVCRedist64BitNeeded; StatusMsg: "Installing VC++ redistributable..."
|
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/passive /norestart"; Check: IsVCRedist64BitNeeded; StatusMsg: "Installing VC++ redistributable..."
|
||||||
Filename: "{app}\ArchipelagoLttPAdjuster"; Parameters: "--update_sprites"; StatusMsg: "Updating Sprite Library..."; Components: lttp_sprites
|
|
||||||
Filename: "{app}\ArchipelagoLauncher"; Parameters: "--update_settings"; StatusMsg: "Updating host.yaml..."; Flags: runasoriginaluser runhidden
|
Filename: "{app}\ArchipelagoLauncher"; Parameters: "--update_settings"; StatusMsg: "Updating host.yaml..."; Flags: runasoriginaluser runhidden
|
||||||
Filename: "{app}\ArchipelagoLauncher"; Description: "{cm:LaunchProgram,{#StringChange('Launcher', '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
Filename: "{app}\ArchipelagoLauncher"; Description: "{cm:LaunchProgram,{#StringChange('Launcher', '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||||
|
|
||||||
|
8
setup.py
8
setup.py
@@ -199,9 +199,10 @@ extra_libs = ["libssl.so", "libcrypto.so"] if is_linux else []
|
|||||||
|
|
||||||
|
|
||||||
def remove_sprites_from_folder(folder: Path) -> None:
|
def remove_sprites_from_folder(folder: Path) -> None:
|
||||||
for file in os.listdir(folder):
|
if os.path.isdir(folder):
|
||||||
if file != ".gitignore":
|
for file in os.listdir(folder):
|
||||||
os.remove(folder / file)
|
if file != ".gitignore":
|
||||||
|
os.remove(folder / file)
|
||||||
|
|
||||||
|
|
||||||
def _threaded_hash(filepath: str | Path) -> str:
|
def _threaded_hash(filepath: str | Path) -> str:
|
||||||
@@ -410,6 +411,7 @@ class BuildExeCommand(cx_Freeze.command.build_exe.build_exe):
|
|||||||
os.system(signtool + os.path.join(self.buildfolder, "lib", "worlds", "oot", "data", *exe_path))
|
os.system(signtool + os.path.join(self.buildfolder, "lib", "worlds", "oot", "data", *exe_path))
|
||||||
|
|
||||||
remove_sprites_from_folder(self.buildfolder / "data" / "sprites" / "alttpr")
|
remove_sprites_from_folder(self.buildfolder / "data" / "sprites" / "alttpr")
|
||||||
|
remove_sprites_from_folder(self.buildfolder / "data" / "sprites" / "alttp" / "remote")
|
||||||
|
|
||||||
self.create_manifest()
|
self.create_manifest()
|
||||||
|
|
||||||
|
@@ -515,7 +515,8 @@ def _populate_sprite_table():
|
|||||||
logging.debug(f"Spritefile {file} could not be loaded as a valid sprite.")
|
logging.debug(f"Spritefile {file} could not be loaded as a valid sprite.")
|
||||||
|
|
||||||
with concurrent.futures.ThreadPoolExecutor() as pool:
|
with concurrent.futures.ThreadPoolExecutor() as pool:
|
||||||
sprite_paths = [user_path('data', 'sprites', 'alttpr'), user_path('data', 'sprites', 'custom')]
|
sprite_paths = [user_path("data", "sprites", "alttp", "remote"),
|
||||||
|
user_path("data", "sprites", "alttp", "custom")]
|
||||||
for dir in [dir for dir in sprite_paths if os.path.isdir(dir)]:
|
for dir in [dir for dir in sprite_paths if os.path.isdir(dir)]:
|
||||||
for file in os.listdir(dir):
|
for file in os.listdir(dir):
|
||||||
pool.submit(load_sprite_from_file, os.path.join(dir, file))
|
pool.submit(load_sprite_from_file, os.path.join(dir, file))
|
||||||
|
Reference in New Issue
Block a user