From f88ccd144757e90ee48547abd3158329d15994ef Mon Sep 17 00:00:00 2001 From: Silvris <58583688+Silvris@users.noreply.github.com> Date: Sat, 9 Sep 2023 23:51:21 -0500 Subject: [PATCH] further work on docstrings and typing --- worlds/Files.py | 52 ++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/worlds/Files.py b/worlds/Files.py index 3635660174..d6687c2f65 100644 --- a/worlds/Files.py +++ b/worlds/Files.py @@ -196,7 +196,7 @@ class APProcedurePatch(APContainer, metaclass=AutoPatchRegister): """ Writes a file to the patch package, to be retrieved upon patching. """ self.files[file_name] = file - def patch(self, target: str): + def patch(self, target: str) -> None: self.read() base_data = self.get_source_data_with_cache() patch_extender = AutoPatchExtensionRegister.get_handler(self.game) @@ -247,22 +247,22 @@ class APTokenMixin: """ tokens: List[ Tuple[int, int, - Union[ - bytes, # WRITE - Tuple[int, int], # COPY, RLE - int # AND_8, OR_8, XOR_8 - ]]] = [] + Union[ + bytes, # WRITE + Tuple[int, int], # COPY, RLE + int # AND_8, OR_8, XOR_8 + ]]] = [] def get_token_binary(self) -> bytes: data = bytearray() data.extend(struct.pack("I", len(self.tokens))) - for type, offset, args in self.tokens: - data.append(type) + for token_type, offset, args in self.tokens: + data.append(token_type) data.extend(struct.pack("I", offset)) - if type in [APTokenTypes.AND_8, APTokenTypes.OR_8, APTokenTypes.XOR_8]: + if token_type in [APTokenTypes.AND_8, APTokenTypes.OR_8, APTokenTypes.XOR_8]: data.extend(struct.pack("I", 1)) data.append(args) - elif type in [APTokenTypes.COPY, APTokenTypes.RLE]: + elif token_type in [APTokenTypes.COPY, APTokenTypes.RLE]: data.extend(struct.pack("I", 8)) data.extend(struct.pack("I", args[0])) data.extend(struct.pack("I", args[1])) @@ -271,8 +271,8 @@ class APTokenMixin: data.extend(args) return data - def write_token(self, type, offset, data): - self.tokens.append((type, offset, data)) + def write_token(self, token_type: APTokenTypes, offset: int, data: Union[bytes, Tuple[int, int], int]): + self.tokens.append((token_type, offset, data)) class APPatchExtension(metaclass=AutoPatchExtensionRegister): @@ -281,38 +281,50 @@ class APPatchExtension(metaclass=AutoPatchExtensionRegister): @staticmethod def apply_bsdiff4(caller: APProcedurePatch, rom: bytes, patch: str): + """Applies the given bsdiff4 from the patch onto the current file.""" return bsdiff4.patch(rom, caller.get_file(patch)) @staticmethod def apply_tokens(caller: APProcedurePatch, rom: bytes, token_file: str) -> bytes: + """Applies the given token file from the patch onto the current file.""" token_data = caller.get_file(token_file) rom_data = bytearray(rom) token_count = struct.unpack("I", token_data[0:4])[0] bpr = 4 for _ in range(token_count): - type = token_data[bpr:bpr + 1][0] + token_type = token_data[bpr:bpr + 1][0] offset = struct.unpack("I", token_data[bpr + 1:bpr + 5])[0] size = struct.unpack("I", token_data[bpr + 5:bpr + 9])[0] data = token_data[bpr + 9:bpr + 9 + size] - if type in [APTokenTypes.AND_8, APTokenTypes.OR_8, APTokenTypes.XOR_8]: + if token_type in [APTokenTypes.AND_8, APTokenTypes.OR_8, APTokenTypes.XOR_8]: arg = data[0] - if type == APTokenTypes.AND_8: + if token_type == APTokenTypes.AND_8: rom_data[offset] = rom_data[offset] & arg - elif type == APTokenTypes.OR_8: + elif token_type == APTokenTypes.OR_8: rom_data[offset] = rom_data[offset] | arg else: rom_data[offset] = rom_data[offset] ^ arg - elif type in [APTokenTypes.COPY, APTokenTypes.RLE]: + elif token_type in [APTokenTypes.COPY, APTokenTypes.RLE]: args = struct.unpack("II", data) - if type == APTokenTypes.COPY: + if token_type == APTokenTypes.COPY: length = args[0] target = args[1] - rom_data[offset: offset+length] = rom_data[target: target+length] + rom_data[offset: offset + length] = rom_data[target: target + length] else: length = args[0] val = args[1] - rom_data[offset: offset+length] = bytes([val] * length) + rom_data[offset: offset + length] = bytes([val] * length) else: rom_data[offset:offset + len(data)] = data bpr += 9 + size return rom_data + + @staticmethod + def calc_snes_crc(caller: APProcedurePatch, rom: bytes): + """Calculates and applies a valid CRC for the SNES rom header.""" + rom_data = bytearray(rom) + crc = (sum(rom_data[:0x7FDC] + rom_data[0x7FE0:]) + 0x01FE) & 0xFFFF + inv = crc ^ 0xFFFF + rom_data[0x7FDC:0x7FE0] = [inv & 0xFF, (inv >> 8) & 0xFF, crc & 0xFF, (crc >> 8) & 0xFF] + return rom_data +