daily pastebin goal
83%
SHARE
TWEET

wateland_editor.pl V1

a guest Nov 10th, 2013 428 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.             skillpt => 0,
  70.         },
  71.         { #2
  72.             skillpt => 1,
  73.         },
  74.         { #3
  75.             skillpt => 0,
  76.         },
  77.         { #4
  78.             skillpt => 2,
  79.         }
  80.     ];
  81.     hack_characters(\@decrypt, $skills, $attrs);
  82.     save_char("characters.new", @decrypt);
  83.     encrypt_msq(\@buf, 0x253c5, @decrypt);
  84.     save_game_file("GAME1.new", \@buf);
  85. }
  86.  
  87. my %skills;
  88. my %attributes;
  89. sub read_game_file {
  90.     my($file) = @_;
  91.     open my $fh, "<", $file or die "ERROR: Couldn't open $file\n";
  92.     my $buffer;
  93.     read($fh, $buffer, 99999999);
  94.     my @buf = map {ord($_)} split(//, $buffer);
  95.     return @buf;
  96. }
  97.  
  98. #decrypt;
  99. sub decrypt_msq {
  100.     my($buf, $offset, $length) = @_;
  101.     my $b1 = $buf->[$offset+4];
  102.     my $b2 = $buf->[$offset+5];
  103.     my $chksum= 0;
  104.     my $enc = $b1 ^ $b2;
  105.     #printf "%02x ^ %02x ==> %02x\n", $b1,$b2,$enc;
  106.     my $pos = 6;
  107.     my @encrypt;
  108.     my @decrypt;
  109.     while($pos < $length + 6) {
  110.         push @encrypt, $buf->[$offset+$pos];
  111.         my $newb = $buf->[$offset+$pos] ^ $enc;
  112.         #printf("%04d %02x %04x %02x => %02x\n", $pos, $enc, $chksum, $buf->[$offset+$pos], $newb);
  113.         $chksum = ($chksum - $newb) & 0xffff;
  114.         $enc = ($enc + 0x1f) & 0xff;
  115.         $pos++;
  116.         push @decrypt, $newb;
  117.         #print chr($newb);
  118.     }
  119.     printf STDERR "Checksum: %04x <> %04x\n", ($b2 << 8) | $b1, $chksum;
  120.     #for $i (0 .. 5) {
  121.     #    print chr($buf->[$offset+$i]);
  122.     #}
  123.     #map {print chr($_)} @decrypt;
  124.     return @decrypt;
  125. }
  126.  
  127. sub save_char {
  128.     my($file, @data) = @_;
  129.     #Save decrypted character data
  130.     open my $fh, ">", $file or die "ERROR: Couldn't write $file\n";
  131.     map {print $fh chr($_)} @data;
  132.     close $fh;
  133. }
  134.  
  135. sub hack_characters {
  136.     my($data, $ch_skills, $ch_attrs) = @_;
  137.     for my $ch (0 .. 3) {
  138.         my $pos = 0x100 * $ch + 0x100;
  139.         my $ref = $ch_attrs->[$ch];
  140.         foreach (keys %$ref) {
  141.             die "ERROR: Couldn't find attr $_\n" if(! exists $attributes{$_});
  142.             $data->[$pos + $attributes{$_}] = $ref->{$_};
  143.         }
  144.  
  145.         my $skill_pos = 0x80;
  146.         $ref = $ch_skills->[$ch];
  147.         foreach (keys %$ref) {
  148.             die "ERROR: Couldn't find skill $_\n" if(! exists $skills{$_});
  149.             $data->[$pos + $skill_pos++] = $skills{$_};
  150.             $data->[$pos + $skill_pos++] = $ref->{$_};
  151.         }
  152.         while($skill_pos != 0xbc) {
  153.             $data->[$pos + $skill_pos++] = 0;
  154.         }
  155.     }
  156. }
  157.  
  158. sub encrypt_msq {
  159.     my($buf, $offset, @decrypt) = @_;
  160.     my $chksum = 0;
  161.     for (@decrypt) {
  162.         $chksum = ($chksum - $_) & 0xffff;
  163.     }
  164.     my $b1 = $chksum & 0xff;
  165.     my $b2 = $chksum >> 8;
  166.     my $enc = $b1 ^ $b2;
  167.     for (@decrypt) {
  168.         $_ = $_ ^ $enc;
  169.         $enc = ($enc + 0x1f) & 0xff;
  170.     }
  171.     $buf->[$offset+4] = $b1;
  172.     $buf->[$offset+5] = $b2;
  173.     my $pos = 6;
  174.     foreach (@decrypt) {
  175.         $buf->[$offset+$pos] = $_;
  176.     }
  177. }
  178.  
  179. sub save_game_file {
  180.     my($file, $buf) = @_;
  181.     open my $fh, ">", $file or die "ERROR: Couldn't write $file\n";
  182.     map {print $fh chr($_)} @$buf;
  183.     close $fh;
  184. }
  185.  
  186. %attributes = (
  187.    str => 0x0e,
  188.    iq  => 0x0f,
  189.    lck => 0x10,
  190.    spd => 0x11,
  191.    agl => 0x12,
  192.    dex => 0x13,
  193.    cha => 0x14,
  194.    skillpt => 0x20,
  195. );
  196. my %skill_id = (
  197.     0x01 => "Brawling",
  198.     0x02 => "Climb",
  199.     0x03 => "Clip Pistol",
  200.     0x04 => "Knife Fight",
  201.     0x05 => "Pugilism",
  202.     0x06 => "Rifle",
  203.     0x07 => "Swim",
  204.     0x08 => "Knife Throw",
  205.     0x09 => "Perception",
  206.     0x0A => "Assault Rifle",
  207.     0x0B => "AT Weapon",
  208.     0x0C => "SMG",
  209.     0x0D => "Acrobat",
  210.     0x0E => "Gambling",
  211.     0x0F => "Picklock",
  212.     0x10 => "Silent Move",
  213.     0x11 => "Combat Shooting",
  214.     0x12 => "Confidence",
  215.     0x13 => "Sleight of Hand",
  216.     0x14 => "Demolitions",
  217.     0x15 => "Forgery",
  218.     0x16 => "Alarm Disarm",
  219.     0x17 => "Bureaucracy",
  220.     0x18 => "Bomb disarm",
  221.     0x19 => "Medic",
  222.     0x1A => "Safecrack",
  223.     0x1B => "Cryptology",
  224.     0x1C => "Metallurgy",
  225.     0x1D => "Helicopter pilot",
  226.     0x1E => "Electronics",
  227.     0x1F => "Toaster repair",
  228.     0x20 => "Doctor",
  229.     0x21 => "Clone tech",
  230.     0x22 => "Energy weapon",
  231.     0x23 => "Cyborg tech",
  232. );
  233. foreach (keys %skill_id) {
  234.     $skills{$skill_id{$_}} = $_;
  235. }
  236.  
  237. main();
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top