From 9e7d7d7f27ed041eee01f4336b126cbe0d14959b Mon Sep 17 00:00:00 2001 From: Sergiotarxz Date: Tue, 12 Mar 2024 12:36:12 +0100 Subject: [PATCH] Adding initial support in rsaves to write pk3 files We already had support for read. --- lib/Rsaves.pm | 65 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/lib/Rsaves.pm b/lib/Rsaves.pm index 12c4cae..015e9a2 100644 --- a/lib/Rsaves.pm +++ b/lib/Rsaves.pm @@ -29,7 +29,7 @@ our @EXPORT_OK = ( qw/read_pc_storage save_pc_changes save_changes enable_eon_ticket add_key_item set_flag_id change_gender read_save get_saves find_current_save_index check_correct_size find_pokemon_substruct - read_pkm_file_box calculate_shiny_personality pokemon_set_shiny + calculate_shiny_personality pokemon_set_shiny get_first_super_data set_first_super_data enable_rematch_main_legendary check_flag_id enable_mirage_island_for_pokemon parse_version_name enable_deoxys_firered match_again_rival_firered_cerulean pokemon_fill_pp to_3rd_encoding translate_3rd_encoding check_rematch/ @@ -144,11 +144,11 @@ sub calculate_shiny_personality { sub pokemon_is_shiny { my $pokemon = shift; - return is_shiny(@{$pokemon}{ 'otid', 'personality' }); + return is_shiny( @{$pokemon}{ 'otid', 'personality' } ); } sub is_shiny { - my $otid = shift; + my $otid = shift; my $personality = shift; return ( _lowhalf_u32($personality) ^ _hihalf_u32($personality) ^ _lowhalf_u32($otid) ^ _hihalf_u32($otid) ) < 8; @@ -264,7 +264,7 @@ sub _read_pokemon_boxes_from_fh { for my $j ( 0 .. 29 ) { read $fh, my $pokemon_data, 0x50 or die "Failed to read 0x50 bytes"; open my $pokemon_fh, '<', \$pokemon_data; - push @$box, _read_pokemon_box_from_fh($pokemon_fh); + push @$box, _read_pokemon_from_fh($pokemon_fh); close $pokemon_fh; } push @$boxes, $box; @@ -272,18 +272,33 @@ sub _read_pokemon_boxes_from_fh { return $boxes; } -sub read_pkm_file_box { +sub read_pk3_file { my $file = shift; open my $fh, '<', $file or die "Unable to open $file"; my $file_contents = join '', <$fh>; - $file_contents = substr $file_contents, 0, 0x50; - open $fh, '<', \$file_contents; - return _read_pokemon_box_from_fh( $fh, 1 ); + return read_pk3_raw($file_contents); +} + +sub read_pk3_raw { + my $raw = shift; + $raw = substr $raw, 0, 0x50; + open my $fh, '<', \$raw; + return _read_pokemon_from_fh( $fh, 1 ); +} + +sub get_pk3_raw { + my $pokemon = shift; + my $return = ''; + open my $fh, '>', \$return; + _write_pokemon_fh( $fh, $pokemon, 1 ); + close $fh; + return $return; } sub _write_pokemon_fh { - my $fh = shift; - my $pokemon = shift; + my $fh = shift; + my $pokemon = shift; + my $is_pkm_file = shift; if ( $pokemon->{personality} > 0xFFFFFFFF ) { die "Too big personality"; } @@ -307,8 +322,10 @@ sub _write_pokemon_fh { { open my $fh_substructures, '>', \$substructures_raw; $pokemon->{checksum} = _write_pokemon_substructures_fh( - $fh_substructures, $pokemon->{substructures}, - $pokemon->{personality}, $pokemon->{otid} + $fh_substructures, + $pokemon->{substructures}, + $pokemon->{personality}, + $pokemon->{otid}, $is_pkm_file, ); close $fh_substructures; } @@ -320,7 +337,7 @@ sub _write_pokemon_fh { print $fh $substructures_raw; } -sub _read_pokemon_box_from_fh { +sub _read_pokemon_from_fh { my $fh = shift; my $is_pkm_file = shift; @@ -406,10 +423,14 @@ sub _write_pokemon_substructures_fh { my $substructures = shift; my $personality = shift; my $otid = shift; + my $is_pkm_file = shift; my $modulo = $personality % 24; my $decrypted_substructures = ''; open my $fh_decrypted_substructures, '>', \$decrypted_substructures; - my @order_substructures = _pokemon_substructures_order_by_modulo($modulo); + my @order_substructures = + ( $is_pkm_file + ? ( 0 .. 3 ) + : _pokemon_substructures_order_by_modulo($modulo) ); my $substruct0 = find_pokemon_substruct( $substructures, 0 ); @@ -430,14 +451,20 @@ sub _write_pokemon_substructures_fh { seek $fh_decrypted_substructures, 0, 0; my $encrypted_substructures; open my $fh_encrypted_substructures, '>', \$encrypted_substructures; - for ( 0 .. 11 ) { - read $fh_decrypted_substructures, my $read, 4; - $read = pack 'V', ( ( ( unpack 'V', $read ) ^ $personality ) ^ $otid ); - print $fh_encrypted_substructures $read; + if (!$is_pkm_file) { + for ( 0 .. 11 ) { + read $fh_decrypted_substructures, my $read, 4; + $read = pack 'V', ( ( ( unpack 'V', $read ) ^ $personality ) ^ $otid ); + print $fh_encrypted_substructures $read; + } } close $fh_decrypted_substructures; close $fh_encrypted_substructures; - print $fh $encrypted_substructures; + if ($is_pkm_file) { + print $fh $decrypted_substructures; + } else { + print $fh $encrypted_substructures; + } return $checksum; }