Last active
December 27, 2018 09:09
-
-
Save FiveYellowMice/d27ce5a9c7c9b42e003bd1042cc524d0 to your computer and use it in GitHub Desktop.
Extracts files from Artemis Engine resource files (.psf).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# encoding: utf-8 | |
# fronze_string_literal: true | |
## | |
# Extracts files from Artemis Engine resource files (.psf). | |
# | |
# Tested on: | |
# - Memory's Dogma CODE:01 | |
require 'fileutils' | |
unless ARGV.length == 2 | |
puts "Incorrect arguments." | |
puts "Usage: artemis_extract.rb <input_file_name> <output_directory_name>" | |
exit 2 | |
end | |
input_file_name = ARGV[0] | |
output_directory_name = ARGV[1] | |
input_file = File.open(input_file_name, 'rb') | |
# Convert little endian binary string to long int | |
def long_int(bstr) | |
bstr.bytes.reverse.inject(0) {|m, c| m * 256 + c } | |
end | |
unless input_file.read(3) == "pf6" | |
puts "Incorrect file signature." | |
exit 1 | |
end | |
info_size = long_int(input_file.read(4)) | |
puts "Info size: #{info_size}" | |
file_count = long_int(input_file.read(4)) | |
puts "File count: #{file_count}" | |
FileInfo = Struct.new :name, :offset, :size | |
file_list = [] | |
file_count.times do |i| | |
name_size = long_int(input_file.read(4)) | |
name = input_file.read(name_size).force_encoding('UTF-8') | |
if !name.valid_encoding? | |
name = name.force_encoding('SJIS') | |
if !name.valid_encoding? | |
raise 'Invalid encoding of file' | |
end | |
name = name.encode('UTF-8') | |
end | |
name = name.gsub('\\', File::SEPARATOR) | |
puts "#{i + 1}: #{name}" | |
input_file.seek(4, :CUR) | |
offset = long_int(input_file.read(4)) | |
size = long_int(input_file.read(4)) | |
file_list << FileInfo.new(name, offset, size) | |
end | |
puts '======== Extracting ========' | |
file_list.each_with_index do |file, i| | |
puts "#{i + 1}: #{file.name}" | |
FileUtils.mkdir_p(File.expand_path(File.dirname(file.name), output_directory_name)) | |
input_file.seek(file.offset) | |
File.write(File.expand_path(file.name, output_directory_name), input_file.read(file.size)) | |
end | |
input_file.close | |
puts 'Done!' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment