Advertisement
Guest User

wateland_editor.pl V1

a guest
Nov 10th, 2013
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.08 KB | None | 0 0
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. sub main {
  6.     my @buf = read_game_file("GAME1");
  7.     my @decrypt = decrypt_msq(\@buf, 0x253c5, 0x800);
  8.     save_char("characters.orig", @decrypt);
  9.     #Modify Characters
  10.     # See end of file for valid parameters
  11.     my $skills = [
  12.         { #1
  13.             "Brawling" => 2,
  14.             "Climb"    => 1,
  15.             "Swim"     => 1,
  16.             "Perception" => 1,
  17.             "Assault Rifle" => 2,
  18.             "AT Weapon" => 1,
  19.             "Acrobat" => 1,
  20.             ##
  21.             "Picklock" => 1,
  22.             "Silent Move" => 1,
  23.             "Demolitions" => 1,
  24.             "Safecrack" => 1,
  25.             "Medic" => 1,
  26.         },
  27.         { #2
  28.             "Brawling" => 2,
  29.             "Climb"    => 1,
  30.             "Swim"     => 1,
  31.             "Perception" => 1,
  32.             "Assault Rifle" => 2,
  33.             "AT Weapon" => 1,
  34.             "Acrobat" => 1,
  35.             ##
  36.             "Combat Shooting" => 1,
  37.             "Bureaucracy" => 1,
  38.             "Medic"=> 1,
  39.             "Cryptology" => 1,
  40.         },
  41.         { #3
  42.             "Brawling" => 2,
  43.             "Climb"    => 1,
  44.             "Swim"     => 1,
  45.             "Perception" => 1,
  46.             "Assault Rifle" => 2,
  47.             "AT Weapon" => 1,
  48.             "Acrobat" => 1,
  49.             ##
  50.             "Combat Shooting" => 1,
  51.             "Bomb disarm" => 2,
  52.         },
  53.         { #4
  54.             "Brawling" => 2,
  55.             "Climb"    => 1,
  56.             "Swim"     => 1,
  57.             "Perception" => 1,
  58.             "Assault Rifle" => 2,
  59.             "AT Weapon" => 1,
  60.             "Acrobat" => 1,
  61.             ##
  62.             "Combat Shooting" => 1,
  63.             "Medic" => 1,
  64.             "Metallurgy" => 1,
  65.         }
  66.     ];
  67.     my $attrs = [
  68.         { #1
  69.             lck => 17,
  70.             skillpt => 0,
  71.         },
  72.         { #2
  73.             skillpt => 1,
  74.         },
  75.         { #3
  76.             skillpt => 0,
  77.         },
  78.         { #4
  79.             dex => 16,
  80.             skillpt => 2,
  81.         }
  82.     ];
  83.     hack_characters(\@decrypt, $skills, $attrs);
  84.     save_char("characters.new", @decrypt);
  85.     encrypt_msq(\@buf, 0x253c5, @decrypt);
  86.     save_game_file("GAME1.new", \@buf);
  87. }
  88.  
  89. my %skills;
  90. my %attributes;
  91. sub read_game_file {
  92.     my($file) = @_;
  93.     open my $fh, "<", $file or die "ERROR: Couldn't open $file\n";
  94.     my $buffer;
  95.     read($fh, $buffer, 99999999);
  96.     my @buf = map {ord($_)} split(//, $buffer);
  97.     return @buf;
  98. }
  99.  
  100. #decrypt;
  101. sub decrypt_msq {
  102.     my($buf, $offset, $length) = @_;
  103.     my $b1 = $buf->[$offset+4];
  104.     my $b2 = $buf->[$offset+5];
  105.     my $chksum= 0;
  106.     my $enc = $b1 ^ $b2;
  107.     #printf "%02x ^ %02x ==> %02x\n", $b1,$b2,$enc;
  108.     my $pos = 6;
  109.     my @encrypt;
  110.     my @decrypt;
  111.     while($pos < $length + 6) {
  112.         push @encrypt, $buf->[$offset+$pos];
  113.         my $newb = $buf->[$offset+$pos] ^ $enc;
  114.         #printf("%04d %02x %04x %02x => %02x\n", $pos, $enc, $chksum, $buf->[$offset+$pos], $newb);
  115.         $chksum = ($chksum - $newb) & 0xffff;
  116.         $enc = ($enc + 0x1f) & 0xff;
  117.         $pos++;
  118.         push @decrypt, $newb;
  119.         #print chr($newb);
  120.     }
  121.     printf STDERR "Checksum: %04x <> %04x\n", ($b2 << 8) | $b1, $chksum;
  122.     #for $i (0 .. 5) {
  123.     #    print chr($buf->[$offset+$i]);
  124.     #}
  125.     #map {print chr($_)} @decrypt;
  126.     return @decrypt;
  127. }
  128.  
  129. sub save_char {
  130.     my($file, @data) = @_;
  131.     #Save decrypted character data
  132.     open my $fh, ">", $file or die "ERROR: Couldn't write $file\n";
  133.     map {print $fh chr($_)} @data;
  134.     close $fh;
  135. }
  136.  
  137. sub hack_characters {
  138.     my($data, $ch_skills, $ch_attrs) = @_;
  139.     for my $ch (0 .. 3) {
  140.         my $pos = 0x100 * $ch + 0x100;
  141.         my $ref = $ch_attrs->[$ch];
  142.         foreach (keys %$ref) {
  143.             die "ERROR: Couldn't find attr $_\n" if(! exists $attributes{$_});
  144.             $data->[$pos + $attributes{$_}] = $ref->{$_};
  145.         }
  146.  
  147.         my $skill_pos = 0x80;
  148.         $ref = $ch_skills->[$ch];
  149.         foreach (keys %$ref) {
  150.             die "ERROR: Couldn't find skill $_\n" if(! exists $skills{$_});
  151.             $data->[$pos + $skill_pos++] = $skills{$_};
  152.             $data->[$pos + $skill_pos++] = $ref->{$_};
  153.         }
  154.         while($skill_pos != 0xbc) {
  155.             $data->[$pos + $skill_pos++] = 0;
  156.         }
  157.     }
  158. }
  159.  
  160. sub encrypt_msq {
  161.     my($buf, $offset, @decrypt) = @_;
  162.     my $chksum = 0;
  163.     for (@decrypt) {
  164.         $chksum = ($chksum - $_) & 0xffff;
  165.     }
  166.     my $b1 = $chksum & 0xff;
  167.     my $b2 = $chksum >> 8;
  168.     my $enc = $b1 ^ $b2;
  169.     for (@decrypt) {
  170.         $_ = $_ ^ $enc;
  171.         $enc = ($enc + 0x1f) & 0xff;
  172.     }
  173.     $buf->[$offset+4] = $b1;
  174.     $buf->[$offset+5] = $b2;
  175.     my $pos = 6;
  176.     foreach (@decrypt) {
  177.         $buf->[$offset+$pos] = $_;
  178.     }
  179. }
  180.  
  181. sub save_game_file {
  182.     my($file, $buf) = @_;
  183.     open my $fh, ">", $file or die "ERROR: Couldn't write $file\n";
  184.     map {print $fh chr($_)} @$buf;
  185.     close $fh;
  186. }
  187.  
  188. %attributes = (
  189.    str => 0x0e,
  190.    iq  => 0x0f,
  191.    lck => 0x10,
  192.    spd => 0x11,
  193.    agl => 0x12,
  194.    dex => 0x13,
  195.    cha => 0x14,
  196.    skillpt => 0x20,
  197. );
  198. my %skill_id = (
  199.     0x01 => "Brawling",
  200.     0x02 => "Climb",
  201.     0x03 => "Clip Pistol",
  202.     0x04 => "Knife Fight",
  203.     0x05 => "Pugilism",
  204.     0x06 => "Rifle",
  205.     0x07 => "Swim",
  206.     0x08 => "Knife Throw",
  207.     0x09 => "Perception",
  208.     0x0A => "Assault Rifle",
  209.     0x0B => "AT Weapon",
  210.     0x0C => "SMG",
  211.     0x0D => "Acrobat",
  212.     0x0E => "Gambling",
  213.     0x0F => "Picklock",
  214.     0x10 => "Silent Move",
  215.     0x11 => "Combat Shooting",
  216.     0x12 => "Confidence",
  217.     0x13 => "Sleight of Hand",
  218.     0x14 => "Demolitions",
  219.     0x15 => "Forgery",
  220.     0x16 => "Alarm Disarm",
  221.     0x17 => "Bureaucracy",
  222.     0x18 => "Bomb disarm",
  223.     0x19 => "Medic",
  224.     0x1A => "Safecrack",
  225.     0x1B => "Cryptology",
  226.     0x1C => "Metallurgy",
  227.     0x1D => "Helicopter pilot",
  228.     0x1E => "Electronics",
  229.     0x1F => "Toaster repair",
  230.     0x20 => "Doctor",
  231.     0x21 => "Clone tech",
  232.     0x22 => "Energy weapon",
  233.     0x23 => "Cyborg tech",
  234. );
  235. foreach (keys %skill_id) {
  236.     $skills{$skill_id{$_}} = $_;
  237. }
  238.  
  239. main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement