diff --git a/doltool/doltest.py b/doltool/doltest.py index f71ba5b..8a94a5c 100644 --- a/doltool/doltest.py +++ b/doltool/doltest.py @@ -1,122 +1,157 @@ -from doltool import parse_action_replay_ini, Dol -from doltool import InvalidIniFileEntryError, InvalidImgOffsetError, InvalidVirtualAddressError, SectionsOverflowError -import shutil +from doltool import Dol, MemoryObject, Section, ActionReplayCode +from doltool import SectionType, IntervalDiv +from doltool import InvalidImgOffsetError, InvalidVirtualAddressError, InvalidIniFileEntryError, OutOfMemoryError, InvalidSectionAlignError, SectionsOverflowError +from doltool import parse_action_replay_ini, get_overlapping_arcodes, get_unmapped_intervals + +import copy +import os from pathlib import Path +import shutil from time import time -__version__ = "0.0.2" + +__version__ = "0.0.3" __author__ = "rigodron, algoflash, GGLinnk" __license__ = "MIT" __status__ = "developpement" + ################################################## # Installation ################################################## -# Original "eu.dol" has to be placed in the folder. - -test_path = Path("doltool_tests") +# Original Gotcha Force "eu.dol" has to be placed in the same folder than this script. +################################################## +# Path of test folder +################################################## +# Dols samples path +dols_path = Path("dol_samples") +# Inis path +ini_path = Path("ini_tests") +# Used to create dols. +dol_tests_path = Path("dol_tests") +# Dols parsed and rebuild path +dols_save_path = Path("dol_save") ################################################## # doltool.py commands wrappers ################################################## -def doltool_resolve_img2virtual(dol_path:Path, offset:int): - if os.system(f"python doltool.py -i2v \"{dol_path}\" offset") != 0: - raise Exception("Error while resolving dol offset to virtual address.") -def doltool_resolve_virtual2img(dol_path:Path, offset:int): - if os.system(f"python doltool.py -i2v \"{dol_path}\" offset") != 0: - raise Exception("Error while resolving virtual address to dol offset.") +def doltool_par(dol_path:Path, output_path:Path, ini_path:Path): + if os.system(f"python doltool.py -par \"{dol_path}\" -o \"{output_path}\" -ini \"{ini_path}\"") != 0: + raise Exception("Error while patching dol using ARCodes ini file.") +def doltool_par_sr(dol_path:Path, output_path:Path, ini_path:Path): + if os.system(f"python doltool.py -par \"{dol_path}\" -o \"{output_path}\" -ini \"{ini_path}\" -sr\"") != 0: + raise Exception("Error while patching dol using ARCodes ini file and section remapping.") -""" -def doltool_stats(path): - if os.system(f"python doltool.py -s \"{path}\" > NUL") != 0: - raise Exception("Error while getting stats.") -""" +################################################## +# Helpers +################################################## +class DolDescriptor: + def __init__(self, index:int, offset:int, address:int, length:int, byte:bytes): + self.index = index + self.offset = offset + 0x100 + self.address = address + self.length = length + self.byte = byte + def boffset(self): return self.offset.to_bytes(4,"big") + def baddress(self): return (self.address + 0x80003100).to_bytes(4,"big") + def blength(self): return self.length.to_bytes(4,"big") -TEST_COUNT = 4 +def map_offsets(datas:bytes, offsets_map:list, intervals:list): + max_address = 0 + for beg,length,dest in offsets_map: + max_address = max(max_address, dest+length) + remapped_datas = bytearray(b"\x00"*max_address) + for [beg, length, dest] in offsets_map: + remapped_datas[dest:dest+length] = datas[beg:beg+length] + for beg,end,byte in intervals: + remapped_datas[beg:end] = byte * (end - beg) + for [beg, length, dest] in offsets_map: + datas[beg:beg+length] = remapped_datas[dest:dest+length] + return datas + + +def create_dol(dol_name:str, descriptors_list:list, bss_addr:int = 20, bss_length:int = 100, entry_point:int = 0): + """ + input: [DolDescriptor, ...] + create a dol with specified values in dol_tests_path + """ + descriptors_list.sort(key=lambda x:x.index) + + offsets = b"" + address = b"" + lengths = b"" + tmp_list = copy.deepcopy(descriptors_list) + for index in range(18): + if len(tmp_list) > 0: + if tmp_list[0].index == index: + offsets += tmp_list[0].boffset() + address += tmp_list[0].baddress() + lengths += tmp_list[0].blength() + + tmp_list.pop(0) + continue + offsets += b"\x00\x00\x00\x00" + address += b"\x00\x00\x00\x00" + lengths += b"\x00\x00\x00\x00" + + datas = (offsets + address + lengths + (bss_addr + 0x80003100).to_bytes(4,"big") + bss_length.to_bytes(4,"big") + (entry_point + 0x80003100).to_bytes(4,"big")).ljust(0x100, b"\x00") + + descriptors_list.sort(key=lambda x:x.offset) + for descriptor in descriptors_list: + if len(datas) != descriptor.offset: raise Exception("doltest.py - Invalid dol creation offset.") + datas += descriptor.byte * descriptor.length + Path(dol_tests_path / dol_name).write_bytes(datas) + + +def to_action_replay_list(memory_objects:list): + arc_list = [] + for memory_object in memory_objects: + arc_list.append(ActionReplayCode("04003100 12345678", 0)) + arc_list[-1].set_address(memory_object.address()) + arc_list[-1].set_end_address(memory_object.end_address()) + arc_list[-1].set_datas(b"a" * memory_object.length()) + return arc_list + + +def memory_objects_to_ini_txt(memory_objects:list): + str_buffer = "" + for memory_object in memory_objects: + addr = memory_object.address() & 0x01FFFFFF + str_buffer += f"" + if memory_object.length() == 4: + str_buffer += f"{addr | 0x04000000:08x} " + f"{memory_object.datas()[0]:02x}"*4 + "\n" + elif memory_object.length() % 2 == 0: + str_buffer += f"{addr | 0x02000000:08x} {((memory_object.length() // 2) - 1):04x}" + f"{memory_object.datas()[0]:02x}"*2 + "\n" + else: + print(f"{memory_object.address():08x} {memory_object.length():08x}") + raise("doltest: Invalid ARCode length - should be aligned to 2 or 4") + return str_buffer + + +def create_memory_objects_from_intervals(*intervals:list): + res = [] + for interval in intervals: + memory_object = MemoryObject(0x80003100 + interval[0], end_address = 0x80003100 + interval[1]) + res.append( memory_object ) + if len(interval) == 3: + memory_object.set_datas(interval[2] * memory_object.length()) + return res + + +TEST_COUNT = 8 start = time() print("###############################################################################") print("# Checking tests folder") print("###############################################################################") # Check if tests folders exist -if test_path.is_dir(): - raise Exception(f"Error - Please remove:\n-{test_path}") +if ini_path.is_dir() or dol_tests_path.is_dir() or dols_save_path.is_dir(): + raise Exception(f"Error - Please remove:\n-{ini_path}\n-{dol_tests_path}\n-{dols_save_path}") print("###############################################################################") print(f"# TEST 1/{TEST_COUNT}") -print("# Testing valid action_replay_code parsing.") -print("###############################################################################") -test_path.mkdir() - -valid_action_replay_ini = """[ActionReplay_Enabled] -$Costs -$HP -$B Ammo and Refill Codes -$B Mode and Reload Codes -$X Ammo and Refill Codes -$X Mode and Reload Codes -$Warehouse Full - -[ActionReplay] -$Costs -022E2CC0 00050096 -022E2CCC 00050136 -022E2CD8 0005012C -022E2CE4 000500D2 -042E4E2A 0000005A -042E4F92 000001E0 -042E50FA 0000005A -042E5262 0001003C -042E53CA 00000078 -042E5532 0000003C -042E569A 0000003C -042E5802 00000078 -042E596A 0000000A -""" - -(test_path / "test1.ini").write_text(valid_action_replay_ini) -valid_list = parse_action_replay_ini(test_path / "test1.ini") - -expected_result = [ - (int("802E2CC0", 16), b"\x00\x96\x00\x96\x00\x96\x00\x96\x00\x96\x00\x96"), - (int("802E2CCC", 16), b"\x01\x36\x01\x36\x01\x36\x01\x36\x01\x36\x01\x36"), - (int("802E2CD8", 16), b"\x01\x2C\x01\x2C\x01\x2C\x01\x2C\x01\x2C\x01\x2C"), - (int("802E2CE4", 16), b"\x00\xD2\x00\xD2\x00\xD2\x00\xD2\x00\xD2\x00\xD2"), - (int("802E4E2A", 16), b"\x00\x00\x00\x5A"), - (int("802E4F92", 16), b"\x00\x00\x01\xE0"), - (int("802E50FA", 16), b"\x00\x00\x00\x5A"), - (int("802E5262", 16), b"\x00\x01\x00\x3C"), - (int("802E53CA", 16), b"\x00\x00\x00\x78"), - (int("802E5532", 16), b"\x00\x00\x00\x3C"), - (int("802E569A", 16), b"\x00\x00\x00\x3C"), - (int("802E5802", 16), b"\x00\x00\x00\x78"), - (int("802E596A", 16), b"\x00\x00\x00\x0A")] - -if valid_list != expected_result: - raise Exception("Error - Invalid ini parsing.") -print("Valid parsing as Expected.") - -for invalid_action_replay_ini in ["a\n082E2CC0 00050096\n","0002E2CC0 00050096","082E2CC0 00050096", "\n122E2CC0 00050096\n"]: - try: - (test_path / "test2.ini").write_text(invalid_action_replay_ini) - valid_list = parse_action_replay_ini(test_path / "test2.ini") - raise Exception("Error - InvalidIniFileEntryError Exception should have been triggered.") - except InvalidIniFileEntryError: - print("Correct InvalidIniFileEntryError triggered.") - -for invalid_action_replay_ini in ["a\n082E2CC0 00050096\n","0002E2CC0 00050096","082E2CC0 00050096", "\n122E2CC0 00050096\n"]: - try: - (test_path / "test3.ini").write_text(invalid_action_replay_ini) - valid_list = parse_action_replay_ini(test_path / "test3.ini") - raise Exception("Error - InvalidIniFileEntryError Exception should have been triggered.") - except InvalidIniFileEntryError: - print("Correct InvalidIniFileEntryError triggered.") - -print("###############################################################################") -print(f"# TEST 2/{TEST_COUNT}") print("# Testing valid dol.resolve_img2virtual conversion.") print("###############################################################################") -# For EU dol: dol = Dol(Path("eu.dol")) print("Testing first offset of each segments with correct output:") for (offset, virtual_address) in [(0x100, 0x80003100), (0x25e0, 0x800055e0), (0x2aede0, 0x802b1de0), (0x2aee00, 0x802b1e00), (0x2aee20, 0x802b1e20), (0x2bde80, 0x802c0e80), (0x3b3bc0, 0x8043cbe0), (0x3b66e0, 0x80440080)]: @@ -141,15 +176,15 @@ for invalid_offset in [0x9f, 0x3bd400]: print("Correct InvalidImgOffsetError triggered.") print("###############################################################################") -print(f"# TEST 3/{TEST_COUNT}") +print(f"# TEST 2/{TEST_COUNT}") print("# Testing valid dol.resolve_virtual2img conversion.") print("###############################################################################") -# For EU dol: print("Testing first virtual address of each segments with correct output:") for (offset, virtual_address) in [(0x100, 0x80003100), (0x25e0, 0x800055e0), (0x2aede0, 0x802b1de0), (0x2aee00, 0x802b1e00), (0x2aee20, 0x802b1e20), (0x2bde80, 0x802c0e80), (0x3b3bc0, 0x8043cbe0), (0x3b66e0, 0x80440080)]: if dol.resolve_virtual2img(virtual_address) == offset: print("Correct translation") else: + print(f"{dol.resolve_virtual2img(virtual_address):08x}") raise Exception(f"Error - resolve_virtual2img invalid translation for offset {virtual_address:08x}:{offset:08x}.") print("Testing last virtual address of each segments with correct output:") @@ -168,42 +203,1031 @@ for invalid_offset in [0x800030ff, 0x803b6bc0, 0x803b6bc0, 0x8043cbe0 - 1, 0x804 print("Correct InvalidVirtualAddressError triggered.") print("###############################################################################") -print(f"# TEST 4/{TEST_COUNT}") -print("# Testing correct split when patching the end of sections (overflows).") +print(f"# TEST 3/{TEST_COUNT}") +print("# Testing MemoryObject.") print("###############################################################################") -# Testing correct split between two .data section + 1 -# .data2 on .data3 -print(dol._Dol__get_section_mapped_values(0x802c0e7d, b"\x01\x23\x45\x67")) -if dol._Dol__get_section_mapped_values(0x802c0e7d, b"\x01\x23\x45\x67") != [[dol.resolve_virtual2img(0x802c0e7d), b"\x01\x23\x45"], [dol.resolve_virtual2img(0x802c0e80), b"\x67"]]: - raise Exception("Error - Invalid sections split on .data2 overflowing from 1 byte to .data3.") -print("Correct split.") +print("Testing __init__ & __str__") +# address:int, section_type:SectionType = SectionType.UNMAPPED, name:str = None, length:int = None, end_address:int = None +memory_object1 = MemoryObject(0x80003100 + 100, SectionType.BSS, "abcd", length=10) +if str(memory_object1) != f"| {'abcd'.ljust(11)} | {0x80003100+100:08x} | {0x80003100+110:08x} | {10:08x} |" or memory_object1.type() != SectionType.BSS: + raise Exception("Invalid MemoryObject constructor or __str__.") -# Testing correct split between two .data section - 1 -# .data2 on .data3 -if dol._Dol__get_section_mapped_values(0x802c0e7f, b"\x01\x23\x45\x67") != [[dol.resolve_virtual2img(0x802c0e7f), b"\x01"], [dol.resolve_virtual2img(0x802c0e80), b"\x23\x45\x67"]]: - raise Exception("Error - Invalid sections split on .data2 overflowing from 3 byte to .data3.") -print("Correct split.") +memory_object2 = MemoryObject(0x80003100 + 200, name="efgh", end_address=0x80003100 + 310) +if str(memory_object2) != f"| {'efgh'.ljust(11)} | {0x80003100+200:08x} | {0x80003100+310:08x} | {110:08x} |" or memory_object2.type() != SectionType.UNMAPPED: + raise Exception("Invalid MemoryObject constructor or __str__.") -# Testing Not Overflowing at the end of section -# .data3 on .bss0 -if dol._Dol__get_section_mapped_values(0x803b6bbc, b"\x01\x23\x45\x67") != [[dol.resolve_virtual2img(0x803b6bbc), b"\x01\x23\x45\x67"]]: - raise Exception("Error - Invalid sections split on the last 4 bytes of .data3.") -print("Correct end split.") +print("Testing set_address and set_name") +memory_object1.set_end_address(0x80003100 + 200) +memory_object1.set_name("blah") +if str(memory_object1) != f"| {'blah'.ljust(11)} | {0x80003100+100:08x} | {0x80003100+200:08x} | {100:08x} |": + raise Exception("Invalid MemoryObject set_end_address.") -# Testing Overflowing at the end of section + 1 -# .data3 on .bss0 +print("Testing set_end_address") +memory_object1.set_address(0x80003100 + 150) +if str(memory_object1) != f"| {'blah'.ljust(11)} | {0x80003100+150:08x} | {0x80003100+200:08x} | {50:08x} |": + raise Exception("Invalid MemoryObject set_address.") + +print("Testing OutOfMemoryError") +MemoryObject(0x811fffff, length = 1) +MemoryObject(0x80003100, length = 1) try: - dol._Dol__get_section_mapped_values(0x803b6bbd, b"\x01\x23\x45\x67") - raise Exception("Error - SectionsOverflowError Exception should have been triggered.") -except SectionsOverflowError: - print("Correct SectionsOverflowError triggered.") + MemoryObject(0x800030ff, length = 2) + raise Exception("Error - OutOfMemoryError should have been triggered.") +except OutOfMemoryError: + print("Correct OutOfMemoryError triggered.") +try: + MemoryObject(0x80003000, end_address = 0x80003800) + raise Exception("Error - OutOfMemoryError should have been triggered.") +except OutOfMemoryError: + print("Correct OutOfMemoryError triggered.") +try: + MemoryObject(0x811fff00, end_address = 0x811fff00 + 0x200) + raise Exception("Error - OutOfMemoryError should have been triggered.") +except OutOfMemoryError: + print("Correct OutOfMemoryError triggered.") +try: + MemoryObject(0x811fffff, length = 2) + raise Exception("Error - OutOfMemoryError should have been triggered.") +except OutOfMemoryError: + print("Correct OutOfMemoryError triggered.") +try: + MemoryObject(0x81200000, length = 1) + raise Exception("Error - OutOfMemoryError should have been triggered.") +except OutOfMemoryError: + print("Correct OutOfMemoryError triggered.") +print("Testing __sub__:") +interval = MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20) + +for [intervals_to_remove, expected_res] in [ + [create_memory_objects_from_intervals([0,10]), create_memory_objects_from_intervals([10,20])], # Before + [create_memory_objects_from_intervals([20,30]), create_memory_objects_from_intervals([10,20])], # After + [create_memory_objects_from_intervals([0,10],[20,30]), create_memory_objects_from_intervals([10,20])], # Before and after + [create_memory_objects_from_intervals([0,11],[20,30]), create_memory_objects_from_intervals([11,20])], # left truncate + [create_memory_objects_from_intervals([0,11],[19,30]), create_memory_objects_from_intervals([11,19])], # left and right truncate + [create_memory_objects_from_intervals([0,10],[19,30]), create_memory_objects_from_intervals([10,19])], # right truncate + [create_memory_objects_from_intervals([0,11],[12,13],[14,15],[19,30]), create_memory_objects_from_intervals([11,12],[13,14],[15,19])], # left middle and right truncate + [create_memory_objects_from_intervals([0,11],[11,13],[13,15],[19,30]), create_memory_objects_from_intervals([15,19])], # following truncates left truncate rigth truncate + [create_memory_objects_from_intervals([0,11],[11,13],[13,15],[15,20]), None], # following truncates overlap with end match + [create_memory_objects_from_intervals([10,13],[13,15],[15,25]), None], # following truncates overlap with begin match + [create_memory_objects_from_intervals([10,13],[13,15],[15,20]), None], # following truncates in with begin and end match + [create_memory_objects_from_intervals([11,13],[13,15],[15,19]), create_memory_objects_from_intervals([10,11],[19,20])], # following truncates in + [create_memory_objects_from_intervals([10,13],[13,15],[15,19]), create_memory_objects_from_intervals([19,20])], # following truncates in with begin match + [create_memory_objects_from_intervals([11,13],[13,15],[15,20]), create_memory_objects_from_intervals([10,11])], # following truncates in with end match + [create_memory_objects_from_intervals([0,30]), None], # total overlap overflowing left right + [create_memory_objects_from_intervals([10,30]), None], # total overlap overflowing left + [create_memory_objects_from_intervals([0,20]), None], # total overlap overflowing right + [create_memory_objects_from_intervals([10,20]), None]]: # total match + res_interval = interval - intervals_to_remove + if expected_res is None and res_interval is None: + print("Correct result.") + continue + + for a in res_interval: + print(a) + + if len(res_interval) != len(expected_res): + raise Exception("Error - Invalid __sub__ result.") + + for index, res_interval in enumerate(res_interval): + if res_interval.address() != expected_res[index].address() or res_interval.end_address() != expected_res[index].end_address(): + raise Exception("Error - Invalid __sub__ result.") + print("Correct result.") + +interval = MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20) + +print("Testing __lt__:") +for interval_lt, expected_res in [ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 9), True], # __lt__ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10), True], # __lt__ matching + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 11), False], # __le__ + 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 11), False], # __le__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False], # __le__ - 1 byte with matching + [MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19), False], # __contains__ + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15), False], # __contains__ matching left + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), False], # __contains__ matching left and right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20), False], # __contains__ matching right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 21), False], # __ge__ + 1 byte + [MemoryObject(0x80003100 + 19, end_address=0x80003100 + 21), False], # __ge__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # __ge__ + 1 byte with matching + [MemoryObject(0x80003100 + 20, end_address=0x80003100 + 25), False], # __gt__ matching + [MemoryObject(0x80003100 + 21, end_address=0x80003100 + 25), False], # __gt__ + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 21), False], # total overlap + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # total overlap matching left + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False]]: # total overlap matching right + if (interval_lt < interval) != expected_res: + raise Exception("Error - Invalid __lt__ result.") + else: + print("Correct result.") + +print("Testing __le__:") +for interval_le, expected_res in [ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 9), False], # __lt__ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10), False], # __lt__ matching + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 11), True], # __le__ + 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 11), True], # __le__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), True], # __le__ - 1 byte with matching + [MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19), False], # __contains__ + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15), False], # __contains__ matching left + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), False], # __contains__ matching left and right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20), False], # __contains__ matching right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 21), False], # __ge__ + 1 byte + [MemoryObject(0x80003100 + 19, end_address=0x80003100 + 21), False], # __ge__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # __ge__ + 1 byte with matching + [MemoryObject(0x80003100 + 20, end_address=0x80003100 + 25), False], # __gt__ matching + [MemoryObject(0x80003100 + 21, end_address=0x80003100 + 25), False], # __gt__ + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 21), False], # total overlap + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # total overlap matching left + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), True]]: # total overlap matching right + if (interval_le <= interval) != expected_res: + raise Exception("Error - Invalid __le__ result.") + else: + print("Correct result.") + +print("Testing __ge__:") +for interval_ge, expected_res in [ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 9), False], # __lt__ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10), False], # __lt__ matching + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 11), False], # __le__ + 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 11), False], # __le__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False], # __le__ - 1 byte with matching + [MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19), False], # __contains__ + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15), False], # __contains__ matching left + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), False], # __contains__ matching left and right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20), False], # __contains__ matching right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 21), True], # __ge__ + 1 byte + [MemoryObject(0x80003100 + 19, end_address=0x80003100 + 21), True], # __ge__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), True], # __ge__ + 1 byte with matching + [MemoryObject(0x80003100 + 20, end_address=0x80003100 + 25), False], # __gt__ matching + [MemoryObject(0x80003100 + 21, end_address=0x80003100 + 25), False], # __gt__ + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 21), False], # total overlap + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), True], # total overlap matching left + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False]]: # total overlap matching right + if (interval_ge >= interval) != expected_res: + raise Exception("Error - Invalid __ge__ result.") + else: + print("Correct result.") + +print("Testing __gt__:") +for interval_gt, expected_res in [ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 9), False], # __lt__ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10), False], # __lt__ matching + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 11), False], # __le__ + 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 11), False], # __le__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False], # __le__ - 1 byte with matching + [MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19), False], # __contains__ + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15), False], # __contains__ matching left + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), False], # __contains__ matching left and right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20), False], # __contains__ matching right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 21), False], # __ge__ + 1 byte + [MemoryObject(0x80003100 + 19, end_address=0x80003100 + 21), False], # __ge__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # __ge__ + 1 byte with matching + [MemoryObject(0x80003100 + 20, end_address=0x80003100 + 25), True], # __gt__ matching + [MemoryObject(0x80003100 + 21, end_address=0x80003100 + 25), True], # __gt__ + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 21), False], # total overlap + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # total overlap matching left + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False]]: # total overlap matching right + if (interval_gt > interval) != expected_res: + raise Exception("Error - Invalid __gt__ result.") + else: + print("Correct result.") + +print("Testing __contains__:") +for interval_contains, expected_res in [ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 9), False], # __lt__ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10), False], # __lt__ matching + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 11), False], # __le__ + 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 11), False], # __le__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False], # __le__ - 1 byte with matching + [MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19), True], # __contains__ + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15), True], # __contains__ matching left + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), True], # __contains__ matching left and right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20), True], # __contains__ matching right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 21), False], # __ge__ + 1 byte + [MemoryObject(0x80003100 + 19, end_address=0x80003100 + 21), False], # __ge__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # __ge__ + 1 byte with matching + [MemoryObject(0x80003100 + 20, end_address=0x80003100 + 25), False], # __gt__ matching + [MemoryObject(0x80003100 + 21, end_address=0x80003100 + 25), False], # __gt__ + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 21), False], # total overlap + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), False], # total overlap matching left + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), False]]: # total overlap matching right + if (interval_contains in interval) != expected_res: + raise Exception("Error - Invalid __contains__ result.") + else: + print("Correct result.") + +print("Testing __and__:") +for interval_and, expected_res in [ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 9), False], # __lt__ + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10), False], # __lt__ matching + [MemoryObject(0x80003100 + 0, end_address=0x80003100 + 11), True], # __le__ + 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 11), True], # __le__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), True], # __le__ - 1 byte with matching + [MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19), True], # __contains__ + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15), True], # __contains__ matching left + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), True], # __contains__ matching left and right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20), True], # __contains__ matching right + [MemoryObject(0x80003100 + 15, end_address=0x80003100 + 21), True], # __ge__ + 1 byte + [MemoryObject(0x80003100 + 19, end_address=0x80003100 + 21), True], # __ge__ + 1 byte - 1 byte + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), True], # __ge__ + 1 byte with matching + [MemoryObject(0x80003100 + 20, end_address=0x80003100 + 25), False], # __gt__ matching + [MemoryObject(0x80003100 + 21, end_address=0x80003100 + 25), False], # __gt__ + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 21), True], # total overlap + [MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21), True], # total overlap matching left + [MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20), True]]: # total overlap matching right + if (interval_and & interval) != expected_res: + raise Exception("Error - Invalid __and__ result.") + else: + print("Correct result.") + +print("Testing __truediv__:") +intervals_truediv = [] +intervals_truediv.append( MemoryObject(0x80003100 + 0, end_address=0x80003100 + 9) ) +intervals_truediv[0].set_datas(b"l"*9) +intervals_truediv.append( MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10) ) +intervals_truediv[1].set_datas(b"l"*10) +intervals_truediv.append( MemoryObject(0x80003100 + 0, end_address=0x80003100 + 11) ) +intervals_truediv[2].set_datas(b"l"*10 + b"i") +intervals_truediv.append( MemoryObject(0x80003100 + 9, end_address=0x80003100 + 11) ) +intervals_truediv[3].set_datas(b"l" + b"i") +intervals_truediv.append( MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20) ) +intervals_truediv[4].set_datas(b"l" + 10*b"i") +intervals_truediv.append( MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19) ) +intervals_truediv[5].set_datas(b"i"*8) +intervals_truediv.append( MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15) ) +intervals_truediv[6].set_datas(b"i"*5) +intervals_truediv.append( MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20) ) +intervals_truediv[7].set_datas(b"i"*10) +intervals_truediv.append( MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20) ) +intervals_truediv[8].set_datas(b"i"*5) +intervals_truediv.append( MemoryObject(0x80003100 + 15, end_address=0x80003100 + 21) ) +intervals_truediv[9].set_datas(b"i"*5 + b"r") +intervals_truediv.append( MemoryObject(0x80003100 + 19, end_address=0x80003100 + 21) ) +intervals_truediv[10].set_datas(b"i" + b"r") +intervals_truediv.append( MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21) ) +intervals_truediv[11].set_datas(b"i"*10 + b"r") +intervals_truediv.append( MemoryObject(0x80003100 + 20, end_address=0x80003100 + 25) ) +intervals_truediv[12].set_datas(b"r"*5) +intervals_truediv.append( MemoryObject(0x80003100 + 21, end_address=0x80003100 + 25) ) +intervals_truediv[13].set_datas(b"r"*4) +intervals_truediv.append( MemoryObject(0x80003100 + 9, end_address=0x80003100 + 21) ) +intervals_truediv[14].set_datas(b"l" + b"i"*10 + b"r") +intervals_truediv.append( MemoryObject(0x80003100 + 10, end_address=0x80003100 + 21) ) +intervals_truediv[15].set_datas(b"i"*10 + b"r") +intervals_truediv.append( MemoryObject(0x80003100 + 9, end_address=0x80003100 + 20) ) +intervals_truediv[16].set_datas(b"l" + b"i"*10) + +expected_truediv_res = [] +expected_truediv_res.append(None) # __lt__ +expected_truediv_res.append(None) # __lt__ matching + +# __le__ + 1 byte +expected_truediv_res.append({IntervalDiv.LEFT: MemoryObject(0x80003100 + 0, end_address=0x80003100 + 10), IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 11)}) +expected_truediv_res[2][IntervalDiv.LEFT].set_datas(b"l"*10) +expected_truediv_res[2][IntervalDiv.IN].set_datas(b"i") + +# __le__ + 1 byte - 1 byte +expected_truediv_res.append({IntervalDiv.LEFT: MemoryObject(0x80003100 + 9, end_address=0x80003100 + 10), IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 11)}) +expected_truediv_res[3][IntervalDiv.LEFT].set_datas(b"l") +expected_truediv_res[3][IntervalDiv.IN].set_datas(b"i") + +# __le__ - 1 byte with matching +expected_truediv_res.append({IntervalDiv.LEFT: MemoryObject(0x80003100 + 9, end_address=0x80003100 + 10), IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20)}) +expected_truediv_res[4][IntervalDiv.LEFT].set_datas(b"l") +expected_truediv_res[4][IntervalDiv.IN].set_datas(b"i"*10) + +# __contains__ +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 11, end_address=0x80003100 + 19)}) +expected_truediv_res[5][IntervalDiv.IN].set_datas(b"i"*8) + +# __contains__ matching left +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 15)}) +expected_truediv_res[6][IntervalDiv.IN].set_datas(b"i"*5) + +# __contains__ matching left and right +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20)}) +expected_truediv_res[7][IntervalDiv.IN].set_datas(b"i"*10) + +# __contains__ matching right +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20)}) +expected_truediv_res[8][IntervalDiv.IN].set_datas(b"i"*5) + +# __ge__ + 1 byte +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 15, end_address=0x80003100 + 20), IntervalDiv.RIGHT: MemoryObject(0x80003100 + 20, end_address=0x80003100 + 21)}) +expected_truediv_res[9][IntervalDiv.IN].set_datas(b"i"*5) +expected_truediv_res[9][IntervalDiv.RIGHT].set_datas(b"r") + +# __ge__ + 1 byte - 1 byte +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 19, end_address=0x80003100 + 20), IntervalDiv.RIGHT: MemoryObject(0x80003100 + 20, end_address=0x80003100 + 21)}) +expected_truediv_res[10][IntervalDiv.IN].set_datas(b"i") +expected_truediv_res[10][IntervalDiv.RIGHT].set_datas(b"r") + +# __ge__ + 1 byte with matching +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), IntervalDiv.RIGHT: MemoryObject(0x80003100 + 20, end_address=0x80003100 + 21)}) +expected_truediv_res[11][IntervalDiv.IN].set_datas(b"i"*10) +expected_truediv_res[11][IntervalDiv.RIGHT].set_datas(b"r") + +expected_truediv_res.append(None) # __gt__ matching +expected_truediv_res.append(None) # __gt__ + +# total overlap +expected_truediv_res.append({IntervalDiv.LEFT: MemoryObject(0x80003100 + 9, end_address=0x80003100 + 10), IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), IntervalDiv.RIGHT: MemoryObject(0x80003100 + 20, end_address=0x80003100 + 21)}) +expected_truediv_res[14][IntervalDiv.LEFT].set_datas(b"l") +expected_truediv_res[14][IntervalDiv.IN].set_datas(b"i"*10) +expected_truediv_res[14][IntervalDiv.RIGHT].set_datas(b"r") + +# total overlap matching left +expected_truediv_res.append({IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20), IntervalDiv.RIGHT: MemoryObject(0x80003100 + 20, end_address=0x80003100 + 21)}) +expected_truediv_res[15][IntervalDiv.IN].set_datas(b"i"*10) +expected_truediv_res[15][IntervalDiv.RIGHT].set_datas(b"r") + +# total overlap matching right +expected_truediv_res.append({IntervalDiv.LEFT: MemoryObject(0x80003100 + 9, end_address=0x80003100 + 10), IntervalDiv.IN: MemoryObject(0x80003100 + 10, end_address=0x80003100 + 20)}) +expected_truediv_res[16][IntervalDiv.LEFT].set_datas(b"l") +expected_truediv_res[16][IntervalDiv.IN].set_datas(b"i"*10) + +for index in range(len(expected_truediv_res)): + interval_truediv = intervals_truediv[index] + expected_res = expected_truediv_res[index] + + new_intervals = interval_truediv / interval + if expected_res is None and new_intervals is None: + print("Correct result") + continue + + for key in expected_res.keys(): + if key not in new_intervals: + raise Exception("Error - Invalid __truediv__ result.") + if new_intervals[key].address() != expected_res[key].address() or new_intervals[key].end_address() != expected_res[key].end_address() or new_intervals[key].datas() != expected_res[key].datas(): + raise Exception("Error - Invalid __truediv__ result.") + print("Correct result.") + +print("Testing to_memory_object:") +memory_object3 = MemoryObject(0x80003100 + 20, end_address=0x80003100 + 42) + +print("Testing set_datas:") +memory_object3.set_datas(b"11333333333333333333BB") +if memory_object3.datas() != b"11333333333333333333BB": + raise Exception("Error - Invalid set_datas result.") +print("Correct result.") + +memory_object3.set_datas(b"00112233445566778899AA") +if memory_object3.datas() != b"00112233445566778899AA": + raise Exception("Error - Invalid set_datas result.") +print("Correct result.") + +print("Testing update_datas:") +update = MemoryObject(0x80003100 + 21, end_address=0x80003100 + 41) +update.set_datas(b"cccccccccccccccccccc") +memory_object3.update_datas(update) +if memory_object3.datas() != b"0ccccccccccccccccccccA": + raise Exception("Error - Invalid update_datas result.") +print("Correct result.") + +update.set_datas(b"9999999999999999999999") +update.set_address(0x80003100 + 20) +update.set_end_address(0x80003100 + 42) +memory_object3.update_datas(update) +if memory_object3.datas() != b"9999999999999999999999": + raise Exception("Error - Invalid update_datas result.") +print("Correct result.") + +print("Testing align:") +memory_object3.set_address(0x80003100 + 3) +memory_object3.set_end_address(0x80003100 + 9) +memory_object3.align() +if memory_object3.address() != 0x80003100 + 0 or memory_object3.end_address() != 0x80003100 + 32: + raise Exception("Error - Invalid align result.") +print("Correct result.") + +print("###############################################################################") +print(f"# TEST 4/{TEST_COUNT}") +print("# Testing valid action_replay_code parsing.") +print("###############################################################################") +ini_path.mkdir() +dol_tests_path.mkdir() +valid_action_replay_ini = "[ActionReplay_Enabled]\n$Costs\n$HP\n$B Ammo and Refill Codes\n$B Mode and Reload Codes\n$X Ammo and Refill Codes\n$X Mode and Reload Codes\n$Warehouse Full\n\n[ActionReplay]\n$Costs\n022E2CC0 00050096\n022E2CCC 00050136\n022E2CD8 0005012C\n022E2CE4 000500D2\n042E4E2A 0000005A\n042E4F92 000001E0\n042E50FA 0000005A\n042E5262 0001003C\n042E53CA 00000078\n042E5532 0000003C\n042E569A 0000003C\n042E5802 00000078\n042E596A 0000000A\n" + +(ini_path / "test1.ini").write_text(valid_action_replay_ini) +action_replay_list = parse_action_replay_ini(ini_path / "test1.ini") + +expected_res6 = [ + (int("802E2CC0", 16), b"\x00\x96\x00\x96\x00\x96\x00\x96\x00\x96\x00\x96"), + (int("802E2CCC", 16), b"\x01\x36\x01\x36\x01\x36\x01\x36\x01\x36\x01\x36"), + (int("802E2CD8", 16), b"\x01\x2C\x01\x2C\x01\x2C\x01\x2C\x01\x2C\x01\x2C"), + (int("802E2CE4", 16), b"\x00\xD2\x00\xD2\x00\xD2\x00\xD2\x00\xD2\x00\xD2"), + (int("802E4E2A", 16), b"\x00\x00\x00\x5A"), + (int("802E4F92", 16), b"\x00\x00\x01\xE0"), + (int("802E50FA", 16), b"\x00\x00\x00\x5A"), + (int("802E5262", 16), b"\x00\x01\x00\x3C"), + (int("802E53CA", 16), b"\x00\x00\x00\x78"), + (int("802E5532", 16), b"\x00\x00\x00\x3C"), + (int("802E569A", 16), b"\x00\x00\x00\x3C"), + (int("802E5802", 16), b"\x00\x00\x00\x78"), + (int("802E596A", 16), b"\x00\x00\x00\x0A")] +if len(expected_res6) != len(action_replay_list): + raise Exception("Error - Invalid ini parsing.") +for index, exp_res in enumerate(expected_res6): + if action_replay_list[index].address() != expected_res6[index][0] or action_replay_list[index].datas() != expected_res6[index][1]: + raise Exception("Error - Invalid ini parsing.") +print("Valid parsing as Expected.") + +for invalid_action_replay_ini in ["a\n082E2CC0 00050096\n","0002E2CC0 00050096","082E2CC0 00050096", "\n122E2CC0 00050096\n"]: + try: + (ini_path / "test2.ini").write_text(invalid_action_replay_ini) + parse_action_replay_ini(ini_path / "test2.ini") + raise Exception("Error - InvalidIniFileEntryError Exception should have been triggered.") + except InvalidIniFileEntryError: + print("Correct InvalidIniFileEntryError triggered.") +# 41200000 +for invalid_action_replay_ini in ["\n020030ff 00050096\n","05200000 00050096","05800000 00050096", "\n02000000 04050096\n"]: + try: + (ini_path / "test3.ini").write_text(invalid_action_replay_ini) + parse_action_replay_ini(ini_path / "test3.ini") + raise Exception("Error - OutOfMemoryError Exception should have been triggered.") + except OutOfMemoryError: + print("Correct OutOfMemoryError triggered.") + +print("###############################################################################") +print(f"# TEST 5/{TEST_COUNT}") +print("# Testing intervals functions.") +print("###############################################################################") +print("Testing _Dol__get_merged_mapped_memory.") +# There is always sections +# * Sections never overlap +# * unsorted intervals + +create_dol("dol0.dol", [ + DolDescriptor(index=0, offset=107, address=160, length=40, byte=b"a"), # [160, 200] # * > 1 spacing + DolDescriptor(index=1, offset=95, address=128, length=12, byte=b"b"), # [128, 140] # * 0 spacing x2 + DolDescriptor(index=3, offset=63, address=96, length=32, byte=b"b"), # [96, 128] # * 0 spacing + DolDescriptor(index=5, offset=0, address=32, length=31, byte=b"c"), # [32, 63] + DolDescriptor(index=7, offset=31, address=64, length=32, byte=b"d")]) # [64, 96] # * 1 spacing between two intervals +expected_res7 = create_memory_objects_from_intervals([32,63],[64,140],[160,200]) + +dol0 = Dol(dol_tests_path / "dol0.dol") +merged_list = dol0._Dol__get_merged_mapped_memory() + +if len(expected_res7) != len(merged_list): + raise Exception("Error - Invalid merged_list.") + +for index, merged in enumerate(merged_list): + if merged.address() != expected_res7[index].address() or merged.end_address() != expected_res7[index].end_address(): + raise Exception("Error - Invalid intervals merge.") +print("Correct result.") + +print("Testing get_overlapping_arcodes.") +arcode0 = ActionReplayCode("04003100 AAAAAAAA", 1) +arcode1 = ActionReplayCode("04003104 BBBBBBBB", 2) # matching +arcode2 = ActionReplayCode("04003107 BBBBBBBB", 3) # overlapping from 1 byte +arcode3 = ActionReplayCode("0400310C BBBBBBBB", 4) # interval 1 byte +arcode4 = ActionReplayCode("0400310C BBBBBBBB", 5) # total overlap +arcode5 = ActionReplayCode("0400310E BBBBBBBB", 6) # overlapping from 2 bytes +arcode6 = ActionReplayCode("02003114 000FBBBB", 7) # overlapping totaly next +arcode7 = ActionReplayCode("04003118 ABCFBBBB", 8) # totaly overlapped + +expected_res8 = [[arcode1, arcode2], [arcode3, arcode4], [arcode4, arcode5], [arcode6, arcode7]] + +overlaps0 = get_overlapping_arcodes([arcode0,arcode1,arcode2,arcode3,arcode4,arcode5,arcode6,arcode7]) +if len(overlaps0) != len(expected_res8): + raise Exception("Error - Invalid get_overlapping_arcodes result.") + +for index, (overlap0, overlap1) in enumerate(overlaps0): + if overlap0 != expected_res8[index][0] or overlap1 != expected_res8[index][1]: + raise Exception("Error - Invalid get_overlapping_arcodes result.") + +print("Testing get_unmapped_intervals.") + +merged_memo_res = [[ # Testing all limits + create_memory_objects_from_intervals([50,75],[100,200],[250,260],[270,280],[300,400]), + create_memory_objects_from_intervals( + [0,5], # before all intervals group + [10,12],[15,20], [25,50], # map before + # in group + [50,75], # in with begin and end map + # new group + [80,90], # between group + [91,92], # between group + [94,95], # between group + [95,101], # overlap begining with 1 byte + # in group + [101,195], # in match previous interval to test end and next interval to test begin + [195,200], # in with end map + # empty group + [250,258], # in with begin map + # new group + [259,264], # overlap ending with 1 byte + # new group + [280,285], # map after + # new group + [420,430], # after group + [450,470]), + create_memory_objects_from_intervals([0,50],[80,100],[260,264],[280,285],[420,470]), + ],[ # All before with overlap + create_memory_objects_from_intervals([75,200],[250,260],[270,280]), + create_memory_objects_from_intervals([0,5],[10,12],[15,20],[25,50],[50,76]), + create_memory_objects_from_intervals([0,75]) + ],[ # All after with overlap + create_memory_objects_from_intervals([50,75],[100,120],[140,196]), + create_memory_objects_from_intervals([195,200],[250,258],[259,264],[450,470]), + create_memory_objects_from_intervals([196,470]) + ],[ # All between with overlap + create_memory_objects_from_intervals([10,20],[50,196],[469,520],[600,700]), + create_memory_objects_from_intervals( + [195,200], # before overlap + [250,258], # between + [259,264], # between + [450,470]), # after overlap + create_memory_objects_from_intervals([196, 469]) + ],[ # All between with begin and end match + create_memory_objects_from_intervals([10,20],[50,196],[469,520],[600,700]), + create_memory_objects_from_intervals([196,200], [250,258], [259,264], [450,469]), + create_memory_objects_from_intervals([196, 469]) + ],[ # All in + create_memory_objects_from_intervals([0,500]), + create_memory_objects_from_intervals([195,200],[250,258],[259,264],[450,470]), + None + ]] +for merged_intervals, memory_objects_list, expected_res in merged_memo_res: + unmapped_intervals = get_unmapped_intervals(merged_intervals, to_action_replay_list(memory_objects_list)) + if expected_res is None and unmapped_intervals is None: + print("Corrects get_unmapped_intervals test.") + continue + + if len(unmapped_intervals) != len(expected_res): + raise Exception(f"Error - get_unmapped_intervals invalid result.") + + for index, unmapped_interval in enumerate(unmapped_intervals): + if expected_res[index].address() != unmapped_interval.address() or expected_res[index].end_address() != unmapped_interval.end_address(): + raise Exception(f"Error - get_unmapped_intervals invalid result.") + print("Corrects get_unmapped_intervals test.") + +print("###############################################################################") +print(f"# TEST 6/{TEST_COUNT}") +print("# Testing Section align.") +print("###############################################################################") +# index:int, offset:int, address:int, length:int) + +try: + Section(0, 0x1000, 0x80003101, 10) +except InvalidSectionAlignError: + print("Correct invalid Section align.") +try: + Section(0, 0x1000, 0x8000311F, 10) +except InvalidSectionAlignError: + print("Correct invalid Section align.") + +print("###############################################################################") +print(f"# TEST 7/{TEST_COUNT}") +print("# Testing dol._Dol__save.") +print("###############################################################################") +dols_save_path.mkdir() +for input_path in dols_path.glob("*"): + dol = Dol(input_path) + dol._Dol__save(dols_save_path / input_path.name) + if input_path.read_bytes() != (dols_save_path / input_path.name).read_bytes(): + raise Exception(f"Error - Invalid dol parsing and save for dol {input_path}.") + else: + print(f"Correct parsing and saving.") + +print("###############################################################################") +print(f"# TEST 8/{TEST_COUNT}") +print("# Testing --patch-action-replay commands.") +print("###############################################################################") +# Testing correct patch between two section + 1 +# Sections: [0, 32], [32, 64], [64, 96], [96, 128], [128, 160], [160, 192], [192, 224], [224, 256], [256, 288], +# [288, 320], [320, 352], [352, 384], [384, 416], [416, 448] +print("Following sections sorted with offset == address; offset != address and so on.") +# Following sections sorted by offset +create_dol("dol1.dol", [ + DolDescriptor(index=0, offset=0, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=2, offset=32, address=32, length=32, byte=b"\x20"), + DolDescriptor(index=3, offset=64, address=64, length=32, byte=b"\x30"), + DolDescriptor(index=5, offset=96, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=8, offset=128, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=9, offset=160, address=160, length=32, byte=b"\x60"), + DolDescriptor(index=10, offset=192, address=192, length=32, byte=b"\x70"), + DolDescriptor(index=11, offset=224, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=12, offset=256, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=13, offset=288, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=14, offset=320, address=320, length=32, byte=b"\xB0"), + DolDescriptor(index=15, offset=352, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=16, offset=384, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=17, offset=416, address=416, length=32, byte=b"\xE0")]) +# Following sections reverse sorted by offset +# Here there can't be out overlappings because of address sorting. +create_dol("dol2.dol", [ + DolDescriptor(index=0, offset=416, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=2, offset=384, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=3, offset=352, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=5, offset=320, address=320, length=32, byte=b"\xB0"), + DolDescriptor(index=8, offset=288, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=9, offset=256, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=10, offset=224, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=11, offset=192, address=192, length=32, byte=b"\x70"), + DolDescriptor(index=12, offset=160, address=160, length=32, byte=b"\x60"), + DolDescriptor(index=13, offset=128, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=14, offset=96, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=15, offset=64, address=64, length=32, byte=b"\x30"), + DolDescriptor(index=16, offset=32, address=32, length=32, byte=b"\x20"), + DolDescriptor(index=17, offset=0, address=0, length=32, byte=b"\x10")]) +# Following sections shuffled +# Here there can't be out overlappings because of address sorting. +# Following sections unsorted by offset +create_dol("dol3.dol", [ + DolDescriptor(index=0, offset=192, address=192, length=32, byte=b"\x70"), + DolDescriptor(index=2, offset=64, address=64, length=32, byte=b"\x30"), + DolDescriptor(index=3, offset=160, address=160, length=32, byte=b"\x60"), + DolDescriptor(index=5, offset=288, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=8, offset=128, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=9, offset=32, address=32, length=32, byte=b"\x20"), + DolDescriptor(index=10, offset=96, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=11, offset=224, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=12, offset=416, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=13, offset=352, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=14, offset=320, address=320, length=32, byte=b"\xB0"), + DolDescriptor(index=15, offset=384, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=16, offset=0, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=17, offset=256, address=256, length=32, byte=b"\x90")]) + + +mappeurs_dict = {} + +# Sames as previously but with offset reverse sorted / shuffled / from addresses +create_dol("dol4.dol", [ + DolDescriptor(index=0, offset=416, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=2, offset=384, address=32, length=32, byte=b"\x20"), + DolDescriptor(index=3, offset=352, address=64, length=32, byte=b"\x30"), + DolDescriptor(index=5, offset=320, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=8, offset=288, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=9, offset=256, address=160, length=32, byte=b"\x60"), + DolDescriptor(index=10, offset=224, address=192, length=32, byte=b"\x70"), + DolDescriptor(index=11, offset=192, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=12, offset=160, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=13, offset=128, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=14, offset=96, address=320, length=32, byte=b"\xB0"), + DolDescriptor(index=15, offset=64, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=16, offset=32, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=17, offset=0, address=416, length=32, byte=b"\xE0")]) +mappeurs_dict[4] = [ + [416, 32, 0], + [384, 32, 32], + [352, 32, 64], + [320, 32, 96], + [288, 32, 128], + [256, 32, 160], + [224, 32, 192], + [192, 32, 224], + [160, 32, 256], + [128, 32, 288], + [96, 32, 320], + [64, 32, 352], + [32, 32, 384], + [0, 32, 416]] + +create_dol("dol5.dol", [ + DolDescriptor(index=0, offset=0, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=2, offset=32, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=3, offset=64, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=5, offset=96, address=320, length=32, byte=b"\xB0"), + DolDescriptor(index=8, offset=128, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=9, offset=160, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=10, offset=192, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=11, offset=224, address=192, length=32, byte=b"\x70"), + DolDescriptor(index=12, offset=256, address=160, length=32, byte=b"\x60"), + DolDescriptor(index=13, offset=288, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=14, offset=320, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=15, offset=352, address=64, length=32, byte=b"\x30"), + DolDescriptor(index=16, offset=384, address=32, length=32, byte=b"\x20"), + DolDescriptor(index=17, offset=416, address=0, length=32, byte=b"\x10")]) +mappeurs_dict[5] = [ + [0, 32, 416], + [32, 32, 384], + [64, 32, 352], + [96, 32, 320], + [128, 32, 288], + [160, 32, 256], + [192, 32, 224], + [224, 32, 192], + [256, 32, 160], + [288, 32, 128], + [320, 32, 96], + [352, 32, 64], + [384, 32, 32], + [416, 32, 0]] + +create_dol("dol6.dol", [ + DolDescriptor(index=0, offset=416, address=192, length=32, byte=b"\x70"), + DolDescriptor(index=2, offset=0, address=64, length=32, byte=b"\x30"), + DolDescriptor(index=3, offset=192, address=160, length=32, byte=b"\x60"), + DolDescriptor(index=5, offset=160, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=8, offset=128, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=9, offset=64, address=32, length=32, byte=b"\x20"), + DolDescriptor(index=10, offset=320, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=11, offset=384, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=12, offset=224, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=13, offset=32, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=14, offset=96, address=320, length=32, byte=b"\xB0"), + DolDescriptor(index=15, offset=288, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=16, offset=352, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=17, offset=256, address=256, length=32, byte=b"\x90")]) +mappeurs_dict[6] = [ + [416, 32, 192], + [0, 32, 64], + [192, 32, 160], + [160, 32, 288], + [128, 32, 128], + [64, 32, 32], + [320, 32, 96], + [384, 32, 224], + [224, 32, 416], + [32, 32, 352], + [96, 32, 320], + [288, 32, 384], + [352, 32, 0], + [256, 32, 256]] + +# Here there can't be out overlappings. +# Beginning of dol file # [0, 24] 24 \x11 +# Middle -1 + 1 # [33, 63] 30 \x22 +# Middle # [80, 84] 4 \x33 +# Overlapping + 1 # [93, 97] 4 \x44 +# Overlapping - 1 # [127, 131] 4 \x55 +# Endin map # [156, 160] 4 \x66 +# Begin map # [160, 164] 4 \x77 +# Begin and ending map # [192, 224] 32 \x88 +# Total overlapping +1 -1 # [255, 289] 34 \x99 +# Total overlapping 3 sec # [319, 417] 98 \xAA +# Ending of dol file # [444, 448] 4 \xBB +# [[begin, end, byte], ...] +intervals_list = [] +intervals_list.append([[0, 24, b"\x11"], [33, 63, b"\x22"], [80, 84, b"\x33"], [93, 97, b"\x44"], + [127, 131, b"\x55"], [156, 160, b"\x66"], [160, 164, b"\x77"], [192, 224, b"\x88"], + [255, 289, b"\x99"], [319, 417, b"\xAA"], [444, 448, b"\xBB"]]) +# same reverse sorted +intervals_list.append(sorted(intervals_list[0], key=lambda x: x, reverse=True)) +# same but shuffled +intervals_list.append([[156, 160, b"\x66"], [255, 289, b"\x99"], [160, 164, b"\x77"], [93, 97, b"\x44"],\ + [444, 448, b"\xBB"], [80, 84, b"\x33"], [319, 417, b"\xAA"], [33, 63, b"\x22"],\ + [0, 24, b"\x11"], [127, 131, b"\x55"], [192, 224, b"\x88"]]) + +# just to remember, sames sections: +# [0, 32], [32, 64], [64, 96], [96, 128], [128, 160], [160, 192], [192, 224], [224, 256], [256, 288], +# [288, 320], [320, 352], [352, 384], [384, 416], [416, 448] +intervals_list.append([ + [24, 64, b"\x11"], # overlap left match right + [96, 130, b"\x11"], # overlap right match left + [120, 170, b"\x11"], # overlap left and right + [191, 225, b"\x11"], # overlap left and right +1-1 + [255, 353, b"\x11"]]) # overlap left and right +- 3 sections (reversed) +intervals_list.append([ # same but reverse sorted + [255, 353, b"\x11"], # overlap left and right +- 3 sections (reversed) + [191, 225, b"\x11"], # overlap left and right +1-1 + [120, 170, b"\x11"], # overlap left and right + [96, 130, b"\x11"], # overlap right match left + [24, 64, b"\x11"]]) # overlap left match right +intervals_list.append([ # same but shuffled + [120, 170, b"\x11"], # overlap left and right + [255, 353, b"\x11"], # overlap left and right +- 3 sections (reversed) + [96, 130, b"\x11"], # overlap right match left + [24, 64, b"\x11"], # overlap left match right + [191, 225, b"\x11"]]) # overlap left and right +1-1 +# total file patch +# overlap right (match left) 3 sections dol1 <- sorted +# overlap left match right 3 sections dol3 <- reverse sorted +intervals_list.append([[0, 448, b"\x11"]]) +# overlap left and right +3 sections +# overlap left and right -3 sections +intervals_list.append([[254, 448, b"\x11"]]) +# overlap left and right +-3 sections <- dol2 1st section +intervals_list.append([[100, 340, b"\x11"]]) + +""" +dol123_datas = b"".join(list(map(lambda x: x.to_bytes(4, "big"), [ + 0x100+0, 0, 0x100+32, 0x100+64, 0, 0x100+96, 0, 0, 0x100+128, 0x100+160, 0x100+192, 0x100+224, 0x100+256, 0x100+288, 0x100+320, 0x100+352, 0x100+384, 0x100+416, + 0x80003100+0, 0, 0x80003100+32, 0x80003100+64, 0, 0x80003100+96, 0, 0, 0x80003100+128, 0x80003100+160, 0x80003100+192, 0x80003100+224, 0x80003100+256, 0x80003100+288, 0x80003100+320, 0x80003100+352, 0x80003100+384, 0x80003100+416, + 32, 0, 32, 32, 0, 32, 0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 0x80003100+20,100, 0x80003100]))).ljust(0x100, b"\x00") + b"\x10"*32 + b"\x20"*32 + \ + b"\x30"*32 + b"\x40"*32 + b"\x50"*32 + b"\x60"*32 + b"\x70"*32 + b"\x80"*32 + b"\x90"*32 + b"\xA0"*32 + b"\xB0"*32 + \ + b"\xC0"*32 + b"\xD0"*32 + b"\xE0"*32 +""" +def test_dols(range_dols, intervals_list:list): + for interval_index, intervals in enumerate(intervals_list): + for dol_index in range_dols: + dol_path = f"dol{dol_index}.dol" + dol_patched_path = f"dol{dol_index}_{interval_index}_patched.dol" + dol_ini_path = f"dol{dol_index}_{interval_index}.ini" + + # write ini file with same sorting than intervals + (ini_path / dol_ini_path).write_text( memory_objects_to_ini_txt(create_memory_objects_from_intervals(*intervals)) ) + + dol_datas = bytearray((dol_tests_path / dol_path).read_bytes()) + dol_header = dol_datas[:0x100] + dol_datas = dol_datas[0x100:] + + if dol_index in mappeurs_dict: + dol_datas = map_offsets(dol_datas, mappeurs_dict[dol_index], intervals) + else: + for beg,end,byte in intervals: + dol_datas[beg:end] = byte * (end - beg) + + Path(dol_tests_path / f"dol{dol_index}_{interval_index}_patched.dol.expected").write_bytes(dol_header + dol_datas) + + doltool_par(dol_tests_path / dol_path, dol_tests_path / dol_patched_path, ini_path / dol_ini_path) + if dol_header + dol_datas != (dol_tests_path / dol_patched_path).read_bytes(): + raise Exception("Error - Invalid -par result.") +test_dols(range(1,7), intervals_list) +# Testing Overflowing at the end of section + 1 +intervals_list = [] +intervals_list.append([[445, 449, b"\x11"], [33, 63, b"\x22"]]) +intervals_list.append([[0, 24, b"\x11"], [445, 449, b"\x22"]]) +intervals_list.append([[0, 24, b"\x11"], [447, 451, b"\x22"]]) +intervals_list.append([[447, 451, b"\x11"], [33, 63, b"\x22"]]) +intervals_list.append([[447, 451, b"\x11"]]) +intervals_list.append([[445, 449, b"\x11"]]) + +for interval_index, intervals in enumerate(intervals_list): + + for dol_index in range(1,7): + try: + dol_ini_path = f"dol{dol_index}_{interval_index}_exception.ini" + (ini_path / dol_ini_path).write_text( memory_objects_to_ini_txt(create_memory_objects_from_intervals(*intervals)) ) + + dol = Dol(dol_tests_path / f"dol{dol_index}.dol") + + action_replay_list = parse_action_replay_ini(ini_path / dol_ini_path) + dol.patch_memory_objects(dol_tests_path / f"dol{dol_index}_patched.dol", action_replay_list) + + raise Exception("Error - SectionsOverflowError Exception should have been triggered.") + except SectionsOverflowError: + print("Correct SectionsOverflowError triggered.") + +mappeurs_dict = {} +# Sections: [0, 32], [96, 128], [128, 160], [224, 256], [256, 288], [288, 320], [352, 384], [384, 416], [416, 448] +print("Following sections sorted with offset == address - section patch using offset is safe.") +# Following sections sorted by offset +create_dol("dol7.dol", [ + DolDescriptor(index=1, offset=0, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=5, offset=32, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=8, offset=64, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=10, offset=96, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=11, offset=128, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=12, offset=160, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=13, offset=192, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=14, offset=224, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=15, offset=256, address=416, length=32, byte=b"\xE0")]) +mappeurs_dict[7] = [ + [0, 32, 0], + [32, 32, 96], + [64, 32, 128], + [96, 32, 224], + [128, 32, 256], + [160, 32, 288], + [192, 32, 352], + [224, 32, 384], + [256, 32, 416]] + +# Following sections reverse sorted by offset +create_dol("dol8.dol", [ + DolDescriptor(index=1, offset=256, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=5, offset=224, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=8, offset=192, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=10, offset=160, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=11, offset=128, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=12, offset=96, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=13, offset=64, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=14, offset=32, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=15, offset=0, address=0, length=32, byte=b"\x10")]) +mappeurs_dict[8] = [ + [256, 32, 416], + [224, 32, 384], + [192, 32, 352], + [160, 32, 288], + [128, 32, 256], + [96, 32, 224], + [64, 32, 128], + [32, 32, 96], + [0, 32, 0]] + +# shuffled +# Following sections unsorted by offset +create_dol("dol9.dol", [ + DolDescriptor(index=1, offset=64, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=5, offset=0, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=8, offset=32, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=10, offset=224, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=11, offset=192, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=12, offset=96, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=13, offset=256, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=14, offset=160, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=15, offset=128, address=256, length=32, byte=b"\x90")]) +mappeurs_dict[9] = [ + [64, 32, 128], + [0, 32, 0], + [32, 32, 96], + [224, 32, 384], + [192, 32, 352], + [96, 32, 224], + [256, 32, 416], + [160, 32, 288], + [128, 32, 256]] + +# Sames as previously but with offset reverse sorted / shuffled / from addresses +# offset reverse sorted from address +create_dol("dol10.dol", [ + DolDescriptor(index=1, offset=256, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=5, offset=224, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=8, offset=192, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=10, offset=160, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=11, offset=128, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=12, offset=96, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=13, offset=64, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=14, offset=32, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=15, offset=0, address=416, length=32, byte=b"\xE0")]) +mappeurs_dict[10] = [ + [256, 32, 0], + [224, 32, 96], + [192, 32, 128], + [160, 32, 224], + [128, 32, 256], + [96, 32, 288], + [64, 32, 352], + [32, 32, 384], + [0, 32, 416]] + +# offset reverse sorted from address / reversed +create_dol("dol11.dol", [ + DolDescriptor(index=1, offset=0, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=5, offset=32, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=8, offset=64, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=10, offset=96, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=11, offset=128, address=256, length=32, byte=b"\x90"), + DolDescriptor(index=12, offset=160, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=13, offset=192, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=14, offset=224, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=15, offset=256, address=0, length=32, byte=b"\x10")]) +mappeurs_dict[11] = [ + [0, 32, 416], + [32, 32, 384], + [64, 32, 352], + [96, 32, 288], + [128, 32, 256], + [160, 32, 224], + [192, 32, 128], + [224, 32, 96], + [256, 32, 0]] + +# offset shuffled from address +create_dol("dol12.dol", [ + DolDescriptor(index=1, offset=192, address=128, length=32, byte=b"\x50"), + DolDescriptor(index=5, offset=224, address=0, length=32, byte=b"\x10"), + DolDescriptor(index=8, offset=160, address=96, length=32, byte=b"\x40"), + DolDescriptor(index=10, offset=64, address=384, length=32, byte=b"\xD0"), + DolDescriptor(index=11, offset=0, address=352, length=32, byte=b"\xC0"), + DolDescriptor(index=12, offset=32, address=224, length=32, byte=b"\x80"), + DolDescriptor(index=13, offset=128, address=416, length=32, byte=b"\xE0"), + DolDescriptor(index=14, offset=256, address=288, length=32, byte=b"\xA0"), + DolDescriptor(index=15, offset=96, address=256, length=32, byte=b"\x90")]) +mappeurs_dict[12] = [ + [192, 32, 128], + [224, 32, 0], + [160, 32, 96], + [64, 32, 384], + [0, 32, 352], + [32, 32, 224], + [128, 32, 416], + [256, 32, 288], + [96, 32, 256]] + # Overlapping +3 sections matching right # [126, 320] +# Middle -1 + 1 # [353, 383] \x55 +intervals_list = [] +# Sections: [0, 32], [96, 128], [128, 160], [224, 256], [256, 288], [288, 320], [352, 384], [384, 416], [416, 448] +# Beginning of dol file # [0, 24] \x11 +# Matching right before empty # [28, 32] \x22 +# Matching left after empty # [96, 100] \x33 +# Overlapping +3 sections matching right # [225, 383] \x55 +# Middle # [390, 394] \x66 +# Endin map with overlap # [414, 448] \x77 +# [[begin, end, byte], ...] +intervals_list.append([[0, 24, b"\x11"], [28, 32, b"\x22"], [96, 100, b"\x33"], + [224, 320, b"\x44"], [225, 319, b"\x55"], [390, 394, b"\x66"], [414, 448, b"\x77"]]) +intervals_list.append(sorted(intervals_list[0], key=lambda x: x, reverse=True)) +intervals_list.append([[414, 448, b"\x77"], [353, 383, b"\x55"], [96, 100, b"\x33"], [390, 394, b"\x66"], [28, 32, b"\x22"], [224, 320, b"\x44"], [0, 24, b"\x11"]]) + +# Total file patch +intervals_list.append([[0, 32, b"\x11"], [96, 160, b"\x22"], [224, 320, b"\x33"], [352, 448, b"\x44"]]) +intervals_list.append(sorted(intervals_list[1], key=lambda x: x, reverse=True)) +intervals_list.append([[96, 160, b"\x22"], [0, 32, b"\x11"], [352, 448, b"\x44"], [224, 320, b"\x33"]]) +# same but shuffled + +test_dols(range(7,12), intervals_list) print("###############################################################################") print(f"# Cleaning test folders.") print("###############################################################################") -# remove test_path -shutil.rmtree(test_path) +shutil.rmtree(ini_path) +shutil.rmtree(dol_tests_path) +shutil.rmtree(dols_save_path) end = time() print("###############################################################################")