diff --git a/Patch.py b/Patch.py index b136e932..af0a5e5e 100644 --- a/Patch.py +++ b/Patch.py @@ -1,3 +1,5 @@ +# TODO: convert this into a system like AutoWorld + import bsdiff4 import yaml import os @@ -14,16 +16,25 @@ current_patch_version = 3 GAME_ALTTP = "A Link to the Past" GAME_SM = "Super Metroid" -supported_games = {"A Link to the Past", "Super Metroid"} +GAME_SOE = "Secret of Evermore" +supported_games = {"A Link to the Past", "Super Metroid", "Secret of Evermore"} + +preferred_endings = { + GAME_ALTTP: "apbp", + GAME_SM: "apm3", + GAME_SOE: "apsoe" +} def generate_yaml(patch: bytes, metadata: Optional[dict] = None, game: str = GAME_ALTTP) -> bytes: if game == GAME_ALTTP: - from worlds.alttp.Rom import JAP10HASH + from worlds.alttp.Rom import JAP10HASH as HASH elif game == GAME_SM: - from worlds.sm.Rom import JAP10HASH + from worlds.sm.Rom import JAP10HASH as HASH + elif game == GAME_SOE: + from worlds.soe.Patch import USHASH as HASH else: - raise RuntimeError("Selected game for base rom not found.") + raise RuntimeError(f"Selected game {game} for base rom not found.") patch = yaml.dump({"meta": metadata, "patch": patch, @@ -31,7 +42,7 @@ def generate_yaml(patch: bytes, metadata: Optional[dict] = None, game: str = GAM # minimum version of patch system expected for patching to be successful "compatible_version": 3, "version": current_patch_version, - "base_checksum": JAP10HASH}) + "base_checksum": HASH}) return patch.encode(encoding="utf-8-sig") @@ -40,6 +51,9 @@ def generate_patch(rom: bytes, metadata: Optional[dict] = None, game: str = GAME from worlds.alttp.Rom import get_base_rom_bytes elif game == GAME_SM: from worlds.sm.Rom import get_base_rom_bytes + elif game == GAME_SOE: + file_name = Utils.get_options()["soe_options"]["rom"] + get_base_rom_bytes = lambda: bytes(read_rom(open(file_name, "rb"))) else: raise RuntimeError("Selected game for base rom not found.") diff --git a/Utils.py b/Utils.py index c5a0a48c..e7b468b3 100644 --- a/Utils.py +++ b/Utils.py @@ -166,6 +166,9 @@ def get_default_options() -> dict: "sni": "SNI", "rom_start": True, }, + "soe_options": { + "rom_file": "Secret of Evermore (USA).sfc", + }, "lttp_options": { "rom_file": "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc", "sni": "SNI", diff --git a/WebHostLib/downloads.py b/WebHostLib/downloads.py index e7856a12..ce623c1e 100644 --- a/WebHostLib/downloads.py +++ b/WebHostLib/downloads.py @@ -1,10 +1,11 @@ from flask import send_file, Response, render_template from pony.orm import select -from Patch import update_patch_data +from Patch import update_patch_data, preferred_endings from WebHostLib import app, Slot, Room, Seed, cache import zipfile + @app.route("/dl_patch//") def download_patch(room_id, patch_id): patch = Slot.get(id=patch_id) @@ -19,7 +20,8 @@ def download_patch(room_id, patch_id): patch_data = update_patch_data(patch.data, server=f"{app.config['PATCH_TARGET']}:{last_port}") patch_data = io.BytesIO(patch_data) - fname = f"P{patch.player_id}_{patch.player_name}_{app.jinja_env.filters['suuid'](room_id)}.apbp" + fname = f"P{patch.player_id}_{patch.player_name}_{app.jinja_env.filters['suuid'](room_id)}." \ + f"{preferred_endings[patch.game]}" return send_file(patch_data, as_attachment=True, attachment_filename=fname) @@ -28,23 +30,6 @@ def download_spoiler(seed_id): return Response(Seed.get(id=seed_id).spoiler, mimetype="text/plain") -@app.route("/dl_raw_patch//") -def download_raw_patch(seed_id, player_id: int): - seed = Seed.get(id=seed_id) - patch = select(patch for patch in seed.slots if - patch.player_id == player_id).first() - - if not patch: - return "Patch not found" - else: - import io - - patch_data = update_patch_data(patch.data, server="") - patch_data = io.BytesIO(patch_data) - - fname = f"P{patch.player_id}_{patch.player_name}_{app.jinja_env.filters['suuid'](seed_id)}.apbp" - return send_file(patch_data, as_attachment=True, attachment_filename=fname) - @app.route("/slot_file//") def download_slot_file(room_id, player_id: int): room = Room.get(id=room_id) diff --git a/WebHostLib/templates/viewSeed.html b/WebHostLib/templates/viewSeed.html index 36271cad..62763629 100644 --- a/WebHostLib/templates/viewSeed.html +++ b/WebHostLib/templates/viewSeed.html @@ -28,34 +28,16 @@ Download {% endif %} - {% if seed.multidata %} - - Rooms:  - - {% call macros.list_rooms(rooms) %} -
  • - Create New Room -
  • - {% endcall %} - - - {% else %} - Files:  - - + {% endcall %} - {% endif %} diff --git a/WebHostLib/upload.py b/WebHostLib/upload.py index 64537295..8e461071 100644 --- a/WebHostLib/upload.py +++ b/WebHostLib/upload.py @@ -10,10 +10,7 @@ from pony.orm import flush, select from WebHostLib import app, Seed, Room, Slot from Utils import parse_yaml - -accepted_zip_contents = {"patches": ".apbp", - "spoiler": ".txt", - "multidata": ".archipelago"} +from Patch import preferred_endings banned_zip_contents = (".sfc",) @@ -29,15 +26,17 @@ def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, s if file.filename.endswith(banned_zip_contents): return "Uploaded data contained a rom file, which is likely to contain copyrighted material. " \ "Your file was deleted." - elif file.filename.endswith(".apbp"): + elif file.filename.endswith(tuple(preferred_endings.values())): data = zfile.open(file, "r").read() yaml_data = parse_yaml(lzma.decompress(data).decode("utf-8-sig")) if yaml_data["version"] < 2: - return "Old format cannot be uploaded (outdated .apbp)", 500 + return "Old format cannot be uploaded (outdated .apbp)" metadata = yaml_data["meta"] - slots.add(Slot(data=data, player_name=metadata["player_name"], + + slots.add(Slot(data=data, + player_name=metadata["player_name"], player_id=metadata["player_id"], - game="A Link to the Past")) + game=yaml_data["game"])) elif file.filename.endswith(".apmc"): data = zfile.open(file, "r").read() diff --git a/worlds/soe/__init__.py b/worlds/soe/__init__.py index 104f2e86..6fa8e0ae 100644 --- a/worlds/soe/__init__.py +++ b/worlds/soe/__init__.py @@ -204,7 +204,12 @@ class SoEWorld(World): flags, money, exp)): raise RuntimeError() with lzma.LZMAFile(patch_file, 'wb') as f: - f.write(generate_patch(rom_file, out_file)) + f.write(generate_patch(rom_file, out_file, + { + # used by WebHost + "player_name": self.world.player_name[self.player], + "player_id": self.player + })) except: raise finally: