class PAKFile
Class handles Quake style PAK files
Attributes
pak_file[R]
Public Class Methods
new(path = nil)
click to toggle source
Opens an existing PAK file at path
or if not specified creates a virtual PAK
# File lib/pakspy.rb, line 6 def initialize(path = nil) @file_hash = Hash.new @pak_file = nil unless path.nil? @pak_file = File.open path, "rb" header = Header.new @pak_file.read 12 puts "Warning: Might not be a real PAK" unless header.magic == "PACK" file_count = header.size / 64 @pak_file.seek header.offset file_count.times do entry = FileEntryPAK.new self, @pak_file.read(64) file_add entry end end end
Public Instance Methods
extract(name, path)
click to toggle source
Extracts a file name
from this PAKFile
to path
on system
# File lib/pakspy.rb, line 31 def extract(name, path) file_entry = file_find(name) raise ArgumentError, "No such file #{name} in this PAK." if file_entry.nil? # Create the necessary directories path_current = "" File.dirname(path).split(/[\/\\]/).each do |dir| path_current += dir Dir.mkdir path_current unless Dir.exists?(path_current) path_current += "/" end # Transfer contents file = File.open path, "wb" file.write file_entry.read file.close end
extract_all(dir)
click to toggle source
Extracts all files in PAK to dir
directory
# File lib/pakspy.rb, line 52 def extract_all(dir) files_list.each do |file_name| extract file_name, dir + "/" + file_name end end
finalize()
click to toggle source
# File lib/pakspy.rb, line 25 def finalize @pak_file.close unless @pak_file.nil? end
insert(path, name)
click to toggle source
Inserts a system file at path
as name
# File lib/pakspy.rb, line 60 def insert(path, name) file_add FileEntrySystem.new self, path, name end
insert_all(dir)
click to toggle source
Inserts a directory dir
recursively contents as their names
# File lib/pakspy.rb, line 66 def insert_all(dir) insert_all_helper(dir, "") end
list()
click to toggle source
Lists all files in PAK to an array
# File lib/pakspy.rb, line 116 def list files_list end
save(path)
click to toggle source
Saves all the changes to path
# File lib/pakspy.rb, line 72 def save(path) tmp_path = "#{path}.tmp_" file = File.open tmp_path, "wb" file_entries = Array.new # Will finish header later when we know where the file entries will be file.write "PACK" file.seek 12 # Insert all of the files files_list.each do |name| entry = file_find name file_entry = Hash.new file_entry[:name] = entry.name file_entry[:offset] = file.pos file.write entry.read file_entry[:size] = file.pos - file_entry[:offset] file_entries.push file_entry end # Now we know the rest of the info needed for the header file_entry_pos = file.pos file.seek 4 file.write [file_entry_pos, file_entries.length * 64].pack("VV") # And finally add the file entries file.seek file_entry_pos file_entries.each do |file_entry| file.write [file_entry[:name], file_entry[:offset], file_entry[:size]].pack("a56VV") end # close so we can open it again file.close # And finally move it to the correct place File.rename tmp_path, path end
Private Instance Methods
file_add(file_entry)
click to toggle source
Adds file_entry
to pak
# File lib/pakspy.rb, line 126 def file_add(file_entry) @file_hash[file_entry.name] = file_entry end
file_find(name)
click to toggle source
Finds file called name
in pak
# File lib/pakspy.rb, line 132 def file_find(name) @file_hash[name] end
files_list()
click to toggle source
Returns a list of all the files as an array of strings
# File lib/pakspy.rb, line 138 def files_list @file_hash.values.map { |entry| entry.name } end
insert_all_helper(dir, prefix)
click to toggle source
# File lib/pakspy.rb, line 142 def insert_all_helper(dir, prefix) Dir.entries(dir).each do |entry| unless entry == "." or entry == ".." if File.directory? "#{dir}/#{entry}" insert_all_helper("#{dir}/#{entry}", "#{prefix}#{entry}/") else insert("#{dir}/#{entry}", "#{prefix}#{entry}") end end end end