APProcedurePatch: hotfix changing class variables to instance variables (#2996)
* change class variables to instance variables * Update worlds/Files.py Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * Update worlds/Files.py Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * move required_extensions to tuple * fix missing tuple ellipsis * fix classvar mixup * rename tokens to _tokens. use hasattr * type hint cleanup * Update Files.py * check using isinstance instead --------- Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
This commit is contained in:
parent
12864f7b24
commit
f4b7c28a33
|
@ -7,7 +7,7 @@ from enum import IntEnum
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload
|
from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload, Sequence
|
||||||
|
|
||||||
import bsdiff4
|
import bsdiff4
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class AutoPatchRegister(abc.ABCMeta):
|
||||||
|
|
||||||
class AutoPatchExtensionRegister(abc.ABCMeta):
|
class AutoPatchExtensionRegister(abc.ABCMeta):
|
||||||
extension_types: ClassVar[Dict[str, AutoPatchExtensionRegister]] = {}
|
extension_types: ClassVar[Dict[str, AutoPatchExtensionRegister]] = {}
|
||||||
required_extensions: List[str] = []
|
required_extensions: Tuple[str, ...] = ()
|
||||||
|
|
||||||
def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> AutoPatchExtensionRegister:
|
def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> AutoPatchExtensionRegister:
|
||||||
# construct class
|
# construct class
|
||||||
|
@ -51,7 +51,9 @@ class AutoPatchExtensionRegister(abc.ABCMeta):
|
||||||
return new_class
|
return new_class
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_handler(game: str) -> Union[AutoPatchExtensionRegister, List[AutoPatchExtensionRegister]]:
|
def get_handler(game: Optional[str]) -> Union[AutoPatchExtensionRegister, List[AutoPatchExtensionRegister]]:
|
||||||
|
if not game:
|
||||||
|
return APPatchExtension
|
||||||
handler = AutoPatchExtensionRegister.extension_types.get(game, APPatchExtension)
|
handler = AutoPatchExtensionRegister.extension_types.get(game, APPatchExtension)
|
||||||
if handler.required_extensions:
|
if handler.required_extensions:
|
||||||
handlers = [handler]
|
handlers = [handler]
|
||||||
|
@ -191,7 +193,7 @@ class APProcedurePatch(APAutoPatchInterface):
|
||||||
hash: Optional[str] # base checksum of source file
|
hash: Optional[str] # base checksum of source file
|
||||||
source_data: bytes
|
source_data: bytes
|
||||||
patch_file_ending: str = ""
|
patch_file_ending: str = ""
|
||||||
files: Dict[str, bytes] = {}
|
files: Dict[str, bytes]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_source_data(cls) -> bytes:
|
def get_source_data(cls) -> bytes:
|
||||||
|
@ -206,6 +208,7 @@ class APProcedurePatch(APAutoPatchInterface):
|
||||||
|
|
||||||
def __init__(self, *args: Any, **kwargs: Any):
|
def __init__(self, *args: Any, **kwargs: Any):
|
||||||
super(APProcedurePatch, self).__init__(*args, **kwargs)
|
super(APProcedurePatch, self).__init__(*args, **kwargs)
|
||||||
|
self.files = {}
|
||||||
|
|
||||||
def get_manifest(self) -> Dict[str, Any]:
|
def get_manifest(self) -> Dict[str, Any]:
|
||||||
manifest = super(APProcedurePatch, self).get_manifest()
|
manifest = super(APProcedurePatch, self).get_manifest()
|
||||||
|
@ -277,7 +280,7 @@ class APDeltaPatch(APProcedurePatch):
|
||||||
super(APDeltaPatch, self).__init__(*args, **kwargs)
|
super(APDeltaPatch, self).__init__(*args, **kwargs)
|
||||||
self.patched_path = patched_path
|
self.patched_path = patched_path
|
||||||
|
|
||||||
def write_contents(self, opened_zipfile: zipfile.ZipFile):
|
def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None:
|
||||||
self.write_file("delta.bsdiff4",
|
self.write_file("delta.bsdiff4",
|
||||||
bsdiff4.diff(self.get_source_data_with_cache(), open(self.patched_path, "rb").read()))
|
bsdiff4.diff(self.get_source_data_with_cache(), open(self.patched_path, "rb").read()))
|
||||||
super(APDeltaPatch, self).write_contents(opened_zipfile)
|
super(APDeltaPatch, self).write_contents(opened_zipfile)
|
||||||
|
@ -296,12 +299,12 @@ class APTokenMixin:
|
||||||
"""
|
"""
|
||||||
A class that defines functions for generating a token binary, for use in patches.
|
A class that defines functions for generating a token binary, for use in patches.
|
||||||
"""
|
"""
|
||||||
tokens: List[
|
_tokens: Sequence[
|
||||||
Tuple[APTokenTypes, int, Union[
|
Tuple[APTokenTypes, int, Union[
|
||||||
bytes, # WRITE
|
bytes, # WRITE
|
||||||
Tuple[int, int], # COPY, RLE
|
Tuple[int, int], # COPY, RLE
|
||||||
int # AND_8, OR_8, XOR_8
|
int # AND_8, OR_8, XOR_8
|
||||||
]]] = []
|
]]] = ()
|
||||||
|
|
||||||
def get_token_binary(self) -> bytes:
|
def get_token_binary(self) -> bytes:
|
||||||
"""
|
"""
|
||||||
|
@ -309,8 +312,8 @@ class APTokenMixin:
|
||||||
:return: A bytes object representing the token data.
|
:return: A bytes object representing the token data.
|
||||||
"""
|
"""
|
||||||
data = bytearray()
|
data = bytearray()
|
||||||
data.extend(len(self.tokens).to_bytes(4, "little"))
|
data.extend(len(self._tokens).to_bytes(4, "little"))
|
||||||
for token_type, offset, args in self.tokens:
|
for token_type, offset, args in self._tokens:
|
||||||
data.append(token_type)
|
data.append(token_type)
|
||||||
data.extend(offset.to_bytes(4, "little"))
|
data.extend(offset.to_bytes(4, "little"))
|
||||||
if token_type in [APTokenTypes.AND_8, APTokenTypes.OR_8, APTokenTypes.XOR_8]:
|
if token_type in [APTokenTypes.AND_8, APTokenTypes.OR_8, APTokenTypes.XOR_8]:
|
||||||
|
@ -351,11 +354,14 @@ class APTokenMixin:
|
||||||
data: bytes) -> None:
|
data: bytes) -> None:
|
||||||
...
|
...
|
||||||
|
|
||||||
def write_token(self, token_type: APTokenTypes, offset: int, data: Union[bytes, Tuple[int, int], int]):
|
def write_token(self, token_type: APTokenTypes, offset: int, data: Union[bytes, Tuple[int, int], int]) -> None:
|
||||||
"""
|
"""
|
||||||
Stores a token to be used by patching.
|
Stores a token to be used by patching.
|
||||||
"""
|
"""
|
||||||
self.tokens.append((token_type, offset, data))
|
if not isinstance(self._tokens, list):
|
||||||
|
assert len(self._tokens) == 0, f"{type(self)}._tokens was tampered with."
|
||||||
|
self._tokens = []
|
||||||
|
self._tokens.append((token_type, offset, data))
|
||||||
|
|
||||||
|
|
||||||
class APPatchExtension(metaclass=AutoPatchExtensionRegister):
|
class APPatchExtension(metaclass=AutoPatchExtensionRegister):
|
||||||
|
@ -371,10 +377,10 @@ class APPatchExtension(metaclass=AutoPatchExtensionRegister):
|
||||||
Patch extension functions must return the changed bytes.
|
Patch extension functions must return the changed bytes.
|
||||||
"""
|
"""
|
||||||
game: str
|
game: str
|
||||||
required_extensions: List[str] = []
|
required_extensions: ClassVar[Tuple[str, ...]] = ()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def apply_bsdiff4(caller: APProcedurePatch, rom: bytes, patch: str):
|
def apply_bsdiff4(caller: APProcedurePatch, rom: bytes, patch: str) -> bytes:
|
||||||
"""Applies the given bsdiff4 from the patch onto the current file."""
|
"""Applies the given bsdiff4 from the patch onto the current file."""
|
||||||
return bsdiff4.patch(rom, caller.get_file(patch))
|
return bsdiff4.patch(rom, caller.get_file(patch))
|
||||||
|
|
||||||
|
@ -411,7 +417,7 @@ class APPatchExtension(metaclass=AutoPatchExtensionRegister):
|
||||||
return bytes(rom_data)
|
return bytes(rom_data)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def calc_snes_crc(caller: APProcedurePatch, rom: bytes):
|
def calc_snes_crc(caller: APProcedurePatch, rom: bytes) -> bytes:
|
||||||
"""Calculates and applies a valid CRC for the SNES rom header."""
|
"""Calculates and applies a valid CRC for the SNES rom header."""
|
||||||
rom_data = bytearray(rom)
|
rom_data = bytearray(rom)
|
||||||
if len(rom) < 0x8000:
|
if len(rom) < 0x8000:
|
||||||
|
|
Loading…
Reference in New Issue