Core: add layer for patches that don't use `Patch.py` (#2889)
* Core: add layer for patches that don't use `Patch.py` * bump container version * APAutoPatchInterface name * mystic quest change * OoT and Adventure changes * missed name in docstring * container version compatibility
This commit is contained in:
parent
fa233b2583
commit
e534abeab0
4
Patch.py
4
Patch.py
|
@ -8,7 +8,7 @@ if __name__ == "__main__":
|
|||
import ModuleUpdate
|
||||
ModuleUpdate.update()
|
||||
|
||||
from worlds.Files import AutoPatchRegister, APPatch
|
||||
from worlds.Files import AutoPatchRegister, APAutoPatchInterface
|
||||
|
||||
|
||||
class RomMeta(TypedDict):
|
||||
|
@ -20,7 +20,7 @@ class RomMeta(TypedDict):
|
|||
def create_rom_file(patch_file: str) -> Tuple[RomMeta, str]:
|
||||
auto_handler = AutoPatchRegister.get_handler(patch_file)
|
||||
if auto_handler:
|
||||
handler: APPatch = auto_handler(patch_file)
|
||||
handler: APAutoPatchInterface = auto_handler(patch_file)
|
||||
target = os.path.splitext(patch_file)[0]+handler.result_file_ending
|
||||
handler.patch(target)
|
||||
return {"server": handler.server,
|
||||
|
|
|
@ -6,7 +6,7 @@ import zipfile
|
|||
import os
|
||||
import threading
|
||||
|
||||
from typing import ClassVar, Dict, Tuple, Any, Optional, Union, BinaryIO
|
||||
from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO
|
||||
|
||||
import bsdiff4
|
||||
|
||||
|
@ -38,7 +38,7 @@ class AutoPatchRegister(abc.ABCMeta):
|
|||
return None
|
||||
|
||||
|
||||
current_patch_version: int = 5
|
||||
container_version: int = 6
|
||||
|
||||
|
||||
class InvalidDataError(Exception):
|
||||
|
@ -50,7 +50,7 @@ class InvalidDataError(Exception):
|
|||
|
||||
class APContainer:
|
||||
"""A zipfile containing at least archipelago.json"""
|
||||
version: int = current_patch_version
|
||||
version: int = container_version
|
||||
compression_level: int = 9
|
||||
compression_method: int = zipfile.ZIP_DEFLATED
|
||||
game: Optional[str] = None
|
||||
|
@ -124,14 +124,31 @@ class APContainer:
|
|||
"game": self.game,
|
||||
# minimum version of patch system expected for patching to be successful
|
||||
"compatible_version": 5,
|
||||
"version": current_patch_version,
|
||||
"version": container_version,
|
||||
}
|
||||
|
||||
|
||||
class APPatch(APContainer, abc.ABC, metaclass=AutoPatchRegister):
|
||||
class APPatch(APContainer):
|
||||
"""
|
||||
An abstract `APContainer` that defines the requirements for an object
|
||||
to be used by the `Patch.create_rom_file` function.
|
||||
An `APContainer` that represents a patch file.
|
||||
It includes the `procedure` key in the manifest to indicate that it is a patch.
|
||||
|
||||
Your implementation should inherit from this if your output file
|
||||
represents a patch file, but will not be applied with AP's `Patch.py`
|
||||
"""
|
||||
procedure: Union[Literal["custom"], List[Tuple[str, List[Any]]]] = "custom"
|
||||
|
||||
def get_manifest(self) -> Dict[str, Any]:
|
||||
manifest = super(APPatch, self).get_manifest()
|
||||
manifest["procedure"] = self.procedure
|
||||
manifest["compatible_version"] = 6
|
||||
return manifest
|
||||
|
||||
|
||||
class APAutoPatchInterface(APPatch, abc.ABC, metaclass=AutoPatchRegister):
|
||||
"""
|
||||
An abstract `APPatch` that defines the requirements for a patch
|
||||
to be applied with AP's `Patch.py`
|
||||
"""
|
||||
result_file_ending: str = ".sfc"
|
||||
|
||||
|
@ -140,14 +157,15 @@ class APPatch(APContainer, abc.ABC, metaclass=AutoPatchRegister):
|
|||
""" create the output file with the file name `target` """
|
||||
|
||||
|
||||
class APDeltaPatch(APPatch):
|
||||
"""An APPatch that additionally has delta.bsdiff4
|
||||
containing a delta patch to get the desired file, often a rom."""
|
||||
class APDeltaPatch(APAutoPatchInterface):
|
||||
"""An implementation of `APAutoPatchInterface` that additionally
|
||||
has delta.bsdiff4 containing a delta patch to get the desired file."""
|
||||
|
||||
hash: Optional[str] # base checksum of source file
|
||||
patch_file_ending: str = ""
|
||||
delta: Optional[bytes] = None
|
||||
source_data: bytes
|
||||
procedure = None # delete this line when APPP is added
|
||||
|
||||
def __init__(self, *args: Any, patched_path: str = "", **kwargs: Any) -> None:
|
||||
self.patched_path = patched_path
|
||||
|
@ -158,6 +176,7 @@ class APDeltaPatch(APPatch):
|
|||
manifest["base_checksum"] = self.hash
|
||||
manifest["result_file_ending"] = self.result_file_ending
|
||||
manifest["patch_file_ending"] = self.patch_file_ending
|
||||
manifest["compatible_version"] = 5 # delete this line when APPP is added
|
||||
return manifest
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -7,7 +7,7 @@ from typing import Optional, Any
|
|||
import Utils
|
||||
from .Locations import AdventureLocation, LocationData
|
||||
from settings import get_settings
|
||||
from worlds.Files import APDeltaPatch, AutoPatchRegister, APContainer
|
||||
from worlds.Files import APPatch, AutoPatchRegister
|
||||
|
||||
import bsdiff4
|
||||
|
||||
|
@ -78,7 +78,7 @@ class BatNoTouchLocation:
|
|||
return ret_dict
|
||||
|
||||
|
||||
class AdventureDeltaPatch(APContainer, metaclass=AutoPatchRegister):
|
||||
class AdventureDeltaPatch(APPatch, metaclass=AutoPatchRegister):
|
||||
hash = ADVENTUREHASH
|
||||
game = "Adventure"
|
||||
patch_file_ending = ".apadvn"
|
||||
|
|
|
@ -4,7 +4,7 @@ import zipfile
|
|||
from copy import deepcopy
|
||||
from .Regions import object_id_table
|
||||
from Utils import __version__
|
||||
from worlds.Files import APContainer
|
||||
from worlds.Files import APPatch
|
||||
import pkgutil
|
||||
|
||||
settings_template = yaml.load(pkgutil.get_data(__name__, "data/settings.yaml"), yaml.Loader)
|
||||
|
@ -116,10 +116,10 @@ def generate_output(self, output_directory):
|
|||
APMQ.write_contents(zf)
|
||||
|
||||
|
||||
class APMQFile(APContainer):
|
||||
class APMQFile(APPatch):
|
||||
game = "Final Fantasy Mystic Quest"
|
||||
|
||||
def get_manifest(self):
|
||||
manifest = super().get_manifest()
|
||||
manifest["patch_file_ending"] = ".apmq"
|
||||
return manifest
|
||||
return manifest
|
||||
|
|
|
@ -29,14 +29,14 @@ from .TextBox import character_table, NORMAL_LINE_WIDTH, rom_safe_text
|
|||
from .texture_util import ci4_rgba16patch_to_ci8, rgba16_patch
|
||||
from .Utils import __version__
|
||||
|
||||
from worlds.Files import APContainer
|
||||
from worlds.Files import APPatch
|
||||
from Utils import __version__ as ap_version
|
||||
|
||||
AP_PROGRESSION = 0xD4
|
||||
AP_JUNK = 0xD5
|
||||
|
||||
|
||||
class OoTContainer(APContainer):
|
||||
class OoTContainer(APPatch):
|
||||
game: str = 'Ocarina of Time'
|
||||
|
||||
def __init__(self, patch_data: bytes, base_path: str, output_directory: str,
|
||||
|
|
|
@ -5,7 +5,7 @@ import zipfile
|
|||
from typing_extensions import override
|
||||
|
||||
import Utils
|
||||
from worlds.Files import APPatch
|
||||
from worlds.Files import APAutoPatchInterface
|
||||
|
||||
from zilliandomizer.patch import Patcher
|
||||
|
||||
|
@ -14,7 +14,7 @@ from .gen_data import GenData
|
|||
USHASH = 'd4bf9e7bcf9a48da53785d2ae7bc4270'
|
||||
|
||||
|
||||
class ZillionPatch(APPatch):
|
||||
class ZillionPatch(APAutoPatchInterface):
|
||||
hash = USHASH
|
||||
game = "Zillion"
|
||||
patch_file_ending = ".apzl"
|
||||
|
|
Loading…
Reference in New Issue