2022-04-23 22:30:22 +02:00
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
2022-04-15 23:34:03 +02:00
from pathlib import Path
2022-04-23 22:30:22 +02:00
import shutil
2022-04-15 23:34:03 +02:00
from time import time
2022-04-23 22:30:22 +02:00
__version__ = " 0.0.3 "
2022-04-16 00:24:25 +02:00
__author__ = " rigodron, algoflash, GGLinnk "
2022-04-15 23:34:03 +02:00
__license__ = " MIT "
__status__ = " developpement "
2022-04-23 22:30:22 +02:00
2022-04-15 23:34:03 +02:00
##################################################
# Installation
##################################################
2022-04-23 22:30:22 +02:00
# 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 " )
2022-04-15 23:34:03 +02:00
##################################################
# doltool.py commands wrappers
##################################################
2022-04-23 22:30:22 +02:00
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. " )
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
##################################################
# 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 " )
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
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
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
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 )
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
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 ( )
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
tmp_list . pop ( 0 )
continue
offsets + = b " \x00 \x00 \x00 \x00 "
address + = b " \x00 \x00 \x00 \x00 "
lengths + = b " \x00 \x00 \x00 \x00 "
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
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 " )
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
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
2022-04-15 23:34:03 +02:00
2022-04-23 22:30:22 +02:00
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 ( )
2022-04-15 23:34:03 +02:00
print ( " ############################################################################### " )
2022-04-23 22:30:22 +02:00
print ( " # Checking tests folder " )
print ( " ############################################################################### " )
# Check if tests folders exist
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 } " )
2022-04-15 23:34:03 +02:00
print ( " # Testing valid dol.resolve_img2virtual conversion. " )
print ( " ############################################################################### " )
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 ) ] :
if dol . resolve_img2virtual ( offset ) == virtual_address :
print ( " Correct translation " )
else :
raise Exception ( f " Error - resolve_img2virtual invalid translation for offset { offset : 08x } : { virtual_address : 08x } . " )
print ( " Testing last offset of each segments with correct output: " )
for ( offset , virtual_address ) in [ ( 0x100 + 0x24e0 - 1 , 0x800055e0 - 1 ) , ( 0x25e0 + 0x2ac800 - 1 , 0x802b1de0 - 1 ) , ( 0x2aede0 + 0x20 - 1 , 0x802b1e00 - 1 ) , ( 0x2aee00 + 0x20 - 1 , 0x802b1e20 - 1 ) , ( 0x2aee20 + 0xf060 - 1 , 0x802c0e80 - 1 ) , ( 0x2bde80 + 0xf5d40 - 1 , 0x803b6bc0 - 1 ) , ( 0x3b3bc0 + 0x2b20 - 1 , 0x8043f700 - 1 ) , ( 0x3b66e0 + 0x6d20 - 1 , 0x80446da0 - 1 ) ] :
if dol . resolve_img2virtual ( offset ) == virtual_address :
print ( " Correct translation " )
else :
raise Exception ( f " Error - resolve_img2virtual invalid translation for offset { offset : 08x } : { virtual_address : 08x } . " )
2022-04-16 17:26:52 +02:00
print ( " Testing first and last offset out of file datas to raise Exception: " )
2022-04-15 23:34:03 +02:00
for invalid_offset in [ 0x9f , 0x3bd400 ] :
try :
dol . resolve_img2virtual ( invalid_offset )
raise Exception ( " Error - InvalidImgOffsetError Exception should have been triggered. " )
except InvalidImgOffsetError :
print ( " Correct InvalidImgOffsetError triggered. " )
print ( " ############################################################################### " )
2022-04-23 22:30:22 +02:00
print ( f " # TEST 2/ { TEST_COUNT } " )
2022-04-15 23:34:03 +02:00
print ( " # Testing valid dol.resolve_virtual2img conversion. " )
print ( " ############################################################################### " )
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 :
2022-04-23 22:30:22 +02:00
print ( f " { dol . resolve_virtual2img ( virtual_address ) : 08x } " )
2022-04-15 23:34:03 +02:00
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: " )
for ( offset , virtual_address ) in [ ( 0x100 + 0x24e0 - 1 , 0x800055e0 - 1 ) , ( 0x25e0 + 0x2ac800 - 1 , 0x802b1de0 - 1 ) , ( 0x2aede0 + 0x20 - 1 , 0x802b1e00 - 1 ) , ( 0x2aee00 + 0x20 - 1 , 0x802b1e20 - 1 ) , ( 0x2aee20 + 0xf060 - 1 , 0x802c0e80 - 1 ) , ( 0x2bde80 + 0xf5d40 - 1 , 0x803b6bc0 - 1 ) , ( 0x3b3bc0 + 0x2b20 - 1 , 0x8043f700 - 1 ) , ( 0x3b66e0 + 0x6d20 - 1 , 0x80446da0 - 1 ) ] :
if dol . resolve_virtual2img ( virtual_address ) == offset :
print ( " Correct translation " )
else :
raise Exception ( f " Error - resolve_virtual2img invalid translation for offset { virtual_address : 08x } : { offset : 08x } . " )
print ( " Testing bounding virtual addresses of non existing offset to raise Exception: " )
for invalid_offset in [ 0x800030ff , 0x803b6bc0 , 0x803b6bc0 , 0x8043cbe0 - 1 , 0x8043f700 , 0x80440080 - 1 , 0x80446da0 , 0x80446dc8 , 0x81800000 ] :
try :
dol . resolve_virtual2img ( invalid_offset )
raise Exception ( " Error - InvalidVirtualAddressError Exception should have been triggered. " )
except InvalidVirtualAddressError :
print ( " Correct InvalidVirtualAddressError triggered. " )
2022-04-23 22:30:22 +02:00
print ( " ############################################################################### " )
print ( f " # TEST 3/ { TEST_COUNT } " )
print ( " # Testing MemoryObject. " )
print ( " ############################################################################### " )
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__. " )
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__. " )
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. " )
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 :
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. " )
2022-04-16 17:26:52 +02:00
print ( " ############################################################################### " )
print ( f " # TEST 4/ { TEST_COUNT } " )
2022-04-23 22:30:22 +02:00
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 \n 022E2CC0 00050096 \n 022E2CCC 00050136 \n 022E2CD8 0005012C \n 022E2CE4 000500D2 \n 042E4E2A 0000005A \n 042E4F92 000001E0 \n 042E50FA 0000005A \n 042E5262 0001003C \n 042E53CA 00000078 \n 042E5532 0000003C \n 042E569A 0000003C \n 042E5802 00000078 \n 042E596A 0000000A \n "
2022-04-16 17:26:52 +02:00
2022-04-23 22:30:22 +02:00
( 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 \n 082E2CC0 00050096 \n " , " 0002E2CC0 00050096 " , " 082E2CC0 00050096 " , " \n 122E2CC0 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 [ " \n 020030ff 00050096 \n " , " 05200000 00050096 " , " 05800000 00050096 " , " \n 02000000 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. " )
2022-04-16 17:26:52 +02:00
try :
2022-04-23 22:30:22 +02:00
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
2022-04-16 17:26:52 +02:00
2022-04-23 22:30:22 +02:00
test_dols ( range ( 7 , 12 ) , intervals_list )
2022-04-16 17:26:52 +02:00
2022-04-15 23:34:03 +02:00
print ( " ############################################################################### " )
print ( f " # Cleaning test folders. " )
print ( " ############################################################################### " )
2022-04-23 22:30:22 +02:00
shutil . rmtree ( ini_path )
shutil . rmtree ( dol_tests_path )
shutil . rmtree ( dols_save_path )
2022-04-15 23:34:03 +02:00
end = time ( )
print ( " ############################################################################### " )
print ( f " # All tests are OK - elapsed time: { end - start } " )
print ( " ############################################################################### " )