Skip to content

Commit f4b7c28

Browse files
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>
1 parent 12864f7 commit f4b7c28

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

worlds/Files.py

+20-14
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import os
88
import threading
99

10-
from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload
10+
from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload, Sequence
1111

1212
import bsdiff4
1313

@@ -41,7 +41,7 @@ def get_handler(file: str) -> Optional[AutoPatchRegister]:
4141

4242
class AutoPatchExtensionRegister(abc.ABCMeta):
4343
extension_types: ClassVar[Dict[str, AutoPatchExtensionRegister]] = {}
44-
required_extensions: List[str] = []
44+
required_extensions: Tuple[str, ...] = ()
4545

4646
def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> AutoPatchExtensionRegister:
4747
# construct class
@@ -51,7 +51,9 @@ def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> Aut
5151
return new_class
5252

5353
@staticmethod
54-
def get_handler(game: str) -> Union[AutoPatchExtensionRegister, List[AutoPatchExtensionRegister]]:
54+
def get_handler(game: Optional[str]) -> Union[AutoPatchExtensionRegister, List[AutoPatchExtensionRegister]]:
55+
if not game:
56+
return APPatchExtension
5557
handler = AutoPatchExtensionRegister.extension_types.get(game, APPatchExtension)
5658
if handler.required_extensions:
5759
handlers = [handler]
@@ -191,7 +193,7 @@ class APProcedurePatch(APAutoPatchInterface):
191193
hash: Optional[str] # base checksum of source file
192194
source_data: bytes
193195
patch_file_ending: str = ""
194-
files: Dict[str, bytes] = {}
196+
files: Dict[str, bytes]
195197

196198
@classmethod
197199
def get_source_data(cls) -> bytes:
@@ -206,6 +208,7 @@ def get_source_data_with_cache(cls) -> bytes:
206208

207209
def __init__(self, *args: Any, **kwargs: Any):
208210
super(APProcedurePatch, self).__init__(*args, **kwargs)
211+
self.files = {}
209212

210213
def get_manifest(self) -> Dict[str, Any]:
211214
manifest = super(APProcedurePatch, self).get_manifest()
@@ -277,7 +280,7 @@ def __init__(self, *args: Any, patched_path: str = "", **kwargs: Any) -> None:
277280
super(APDeltaPatch, self).__init__(*args, **kwargs)
278281
self.patched_path = patched_path
279282

280-
def write_contents(self, opened_zipfile: zipfile.ZipFile):
283+
def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None:
281284
self.write_file("delta.bsdiff4",
282285
bsdiff4.diff(self.get_source_data_with_cache(), open(self.patched_path, "rb").read()))
283286
super(APDeltaPatch, self).write_contents(opened_zipfile)
@@ -296,21 +299,21 @@ class APTokenMixin:
296299
"""
297300
A class that defines functions for generating a token binary, for use in patches.
298301
"""
299-
tokens: List[
302+
_tokens: Sequence[
300303
Tuple[APTokenTypes, int, Union[
301304
bytes, # WRITE
302305
Tuple[int, int], # COPY, RLE
303306
int # AND_8, OR_8, XOR_8
304-
]]] = []
307+
]]] = ()
305308

306309
def get_token_binary(self) -> bytes:
307310
"""
308311
Returns the token binary created from stored tokens.
309312
:return: A bytes object representing the token data.
310313
"""
311314
data = bytearray()
312-
data.extend(len(self.tokens).to_bytes(4, "little"))
313-
for token_type, offset, args in self.tokens:
315+
data.extend(len(self._tokens).to_bytes(4, "little"))
316+
for token_type, offset, args in self._tokens:
314317
data.append(token_type)
315318
data.extend(offset.to_bytes(4, "little"))
316319
if token_type in [APTokenTypes.AND_8, APTokenTypes.OR_8, APTokenTypes.XOR_8]:
@@ -351,11 +354,14 @@ def write_token(self,
351354
data: bytes) -> None:
352355
...
353356

354-
def write_token(self, token_type: APTokenTypes, offset: int, data: Union[bytes, Tuple[int, int], int]):
357+
def write_token(self, token_type: APTokenTypes, offset: int, data: Union[bytes, Tuple[int, int], int]) -> None:
355358
"""
356359
Stores a token to be used by patching.
357360
"""
358-
self.tokens.append((token_type, offset, data))
361+
if not isinstance(self._tokens, list):
362+
assert len(self._tokens) == 0, f"{type(self)}._tokens was tampered with."
363+
self._tokens = []
364+
self._tokens.append((token_type, offset, data))
359365

360366

361367
class APPatchExtension(metaclass=AutoPatchExtensionRegister):
@@ -371,10 +377,10 @@ class APPatchExtension(metaclass=AutoPatchExtensionRegister):
371377
Patch extension functions must return the changed bytes.
372378
"""
373379
game: str
374-
required_extensions: List[str] = []
380+
required_extensions: ClassVar[Tuple[str, ...]] = ()
375381

376382
@staticmethod
377-
def apply_bsdiff4(caller: APProcedurePatch, rom: bytes, patch: str):
383+
def apply_bsdiff4(caller: APProcedurePatch, rom: bytes, patch: str) -> bytes:
378384
"""Applies the given bsdiff4 from the patch onto the current file."""
379385
return bsdiff4.patch(rom, caller.get_file(patch))
380386

@@ -411,7 +417,7 @@ def apply_tokens(caller: APProcedurePatch, rom: bytes, token_file: str) -> bytes
411417
return bytes(rom_data)
412418

413419
@staticmethod
414-
def calc_snes_crc(caller: APProcedurePatch, rom: bytes):
420+
def calc_snes_crc(caller: APProcedurePatch, rom: bytes) -> bytes:
415421
"""Calculates and applies a valid CRC for the SNES rom header."""
416422
rom_data = bytearray(rom)
417423
if len(rom) < 0x8000:

0 commit comments

Comments
 (0)