Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- sub main {
- my @buf = read_game_file("GAME1");
- my @decrypt = decrypt_msq(\@buf, 0x253c5, 0x800);
- save_char("characters.orig", @decrypt);
- #Modify Characters
- # See end of file for valid parameters
- my $skills = [
- { #1
- "Brawling" => 2,
- "Climb" => 1,
- "Swim" => 1,
- "Perception" => 1,
- "Assault Rifle" => 2,
- "AT Weapon" => 1,
- "Acrobat" => 1,
- ##
- "Picklock" => 1,
- "Silent Move" => 1,
- "Demolitions" => 1,
- "Safecrack" => 1,
- "Medic" => 1,
- },
- { #2
- "Brawling" => 2,
- "Climb" => 1,
- "Swim" => 1,
- "Perception" => 1,
- "Assault Rifle" => 2,
- "AT Weapon" => 1,
- "Acrobat" => 1,
- ##
- "Combat Shooting" => 1,
- "Bureaucracy" => 1,
- "Medic"=> 1,
- "Cryptology" => 1,
- },
- { #3
- "Brawling" => 2,
- "Climb" => 1,
- "Swim" => 1,
- "Perception" => 1,
- "Assault Rifle" => 2,
- "AT Weapon" => 1,
- "Acrobat" => 1,
- ##
- "Combat Shooting" => 1,
- "Bomb disarm" => 2,
- },
- { #4
- "Brawling" => 2,
- "Climb" => 1,
- "Swim" => 1,
- "Perception" => 1,
- "Assault Rifle" => 2,
- "AT Weapon" => 1,
- "Acrobat" => 1,
- ##
- "Combat Shooting" => 1,
- "Medic" => 1,
- "Metallurgy" => 1,
- }
- ];
- my $attrs = [
- { #1
- skillpt => 0,
- },
- { #2
- skillpt => 1,
- },
- { #3
- skillpt => 0,
- },
- { #4
- skillpt => 2,
- }
- ];
- hack_characters(\@decrypt, $skills, $attrs);
- save_char("characters.new", @decrypt);
- encrypt_msq(\@buf, 0x253c5, @decrypt);
- save_game_file("GAME1.new", \@buf);
- }
- my %skills;
- my %attributes;
- sub read_game_file {
- my($file) = @_;
- open my $fh, "<", $file or die "ERROR: Couldn't open $file\n";
- my $buffer;
- read($fh, $buffer, 99999999);
- my @buf = map {ord($_)} split(//, $buffer);
- return @buf;
- }
- #decrypt;
- sub decrypt_msq {
- my($buf, $offset, $length) = @_;
- my $b1 = $buf->[$offset+4];
- my $b2 = $buf->[$offset+5];
- my $chksum= 0;
- my $enc = $b1 ^ $b2;
- #printf "%02x ^ %02x ==> %02x\n", $b1,$b2,$enc;
- my $pos = 6;
- my @encrypt;
- my @decrypt;
- while($pos < $length + 6) {
- push @encrypt, $buf->[$offset+$pos];
- my $newb = $buf->[$offset+$pos] ^ $enc;
- #printf("%04d %02x %04x %02x => %02x\n", $pos, $enc, $chksum, $buf->[$offset+$pos], $newb);
- $chksum = ($chksum - $newb) & 0xffff;
- $enc = ($enc + 0x1f) & 0xff;
- $pos++;
- push @decrypt, $newb;
- #print chr($newb);
- }
- printf STDERR "Checksum: %04x <> %04x\n", ($b2 << 8) | $b1, $chksum;
- #for $i (0 .. 5) {
- # print chr($buf->[$offset+$i]);
- #}
- #map {print chr($_)} @decrypt;
- return @decrypt;
- }
- sub save_char {
- my($file, @data) = @_;
- #Save decrypted character data
- open my $fh, ">", $file or die "ERROR: Couldn't write $file\n";
- map {print $fh chr($_)} @data;
- close $fh;
- }
- sub hack_characters {
- my($data, $ch_skills, $ch_attrs) = @_;
- for my $ch (0 .. 3) {
- my $pos = 0x100 * $ch + 0x100;
- my $ref = $ch_attrs->[$ch];
- foreach (keys %$ref) {
- die "ERROR: Couldn't find attr $_\n" if(! exists $attributes{$_});
- $data->[$pos + $attributes{$_}] = $ref->{$_};
- }
- my $skill_pos = 0x80;
- $ref = $ch_skills->[$ch];
- foreach (keys %$ref) {
- die "ERROR: Couldn't find skill $_\n" if(! exists $skills{$_});
- $data->[$pos + $skill_pos++] = $skills{$_};
- $data->[$pos + $skill_pos++] = $ref->{$_};
- }
- while($skill_pos != 0xbc) {
- $data->[$pos + $skill_pos++] = 0;
- }
- }
- }
- sub encrypt_msq {
- my($buf, $offset, @decrypt) = @_;
- my $chksum = 0;
- for (@decrypt) {
- $chksum = ($chksum - $_) & 0xffff;
- }
- my $b1 = $chksum & 0xff;
- my $b2 = $chksum >> 8;
- my $enc = $b1 ^ $b2;
- for (@decrypt) {
- $_ = $_ ^ $enc;
- $enc = ($enc + 0x1f) & 0xff;
- }
- $buf->[$offset+4] = $b1;
- $buf->[$offset+5] = $b2;
- my $pos = 6;
- foreach (@decrypt) {
- $buf->[$offset+$pos] = $_;
- }
- }
- sub save_game_file {
- my($file, $buf) = @_;
- open my $fh, ">", $file or die "ERROR: Couldn't write $file\n";
- map {print $fh chr($_)} @$buf;
- close $fh;
- }
- %attributes = (
- str => 0x0e,
- iq => 0x0f,
- lck => 0x10,
- spd => 0x11,
- agl => 0x12,
- dex => 0x13,
- cha => 0x14,
- skillpt => 0x20,
- );
- my %skill_id = (
- 0x01 => "Brawling",
- 0x02 => "Climb",
- 0x03 => "Clip Pistol",
- 0x04 => "Knife Fight",
- 0x05 => "Pugilism",
- 0x06 => "Rifle",
- 0x07 => "Swim",
- 0x08 => "Knife Throw",
- 0x09 => "Perception",
- 0x0A => "Assault Rifle",
- 0x0B => "AT Weapon",
- 0x0C => "SMG",
- 0x0D => "Acrobat",
- 0x0E => "Gambling",
- 0x0F => "Picklock",
- 0x10 => "Silent Move",
- 0x11 => "Combat Shooting",
- 0x12 => "Confidence",
- 0x13 => "Sleight of Hand",
- 0x14 => "Demolitions",
- 0x15 => "Forgery",
- 0x16 => "Alarm Disarm",
- 0x17 => "Bureaucracy",
- 0x18 => "Bomb disarm",
- 0x19 => "Medic",
- 0x1A => "Safecrack",
- 0x1B => "Cryptology",
- 0x1C => "Metallurgy",
- 0x1D => "Helicopter pilot",
- 0x1E => "Electronics",
- 0x1F => "Toaster repair",
- 0x20 => "Doctor",
- 0x21 => "Clone tech",
- 0x22 => "Energy weapon",
- 0x23 => "Cyborg tech",
- );
- foreach (keys %skill_id) {
- $skills{$skill_id{$_}} = $_;
- }
- main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement